私のデータ型は、常に、少なくとも2つのパラメータを持つことになりますし、最後の2つのパラメータはそれぞれ、「Q」と「M」は常にあります。エラータイプの脱構築
Could not deduce (bBase ~ D2 t0) (LINE 1)
で
{-# LANGUAGE TypeFamilies, FlexibleContexts, UndecidableInstances, TypeOperators, DataKinds, ConstraintKinds, FlexibleInstances #-}
data D1 q m = D1 q
data D2 t q m = D2 q
class Foo a where -- a has kind * -> *
f :: a x -> a x
class (Foo b) => Bar b where -- b has kind * -> *
-- the purpose of g is to change ONE type parameter, while fixing the rest
-- the intent of the equality constraints is to decompose the parameter b into
-- its base type and 'q' parameter, then use the same base type with a *different*
-- `q` parameter for the answer
g :: (b ~ bBase q1, b' ~ bBase q2) => b m -> b' m
instance (Foo (D2 t q), Integral q) => Bar (D2 t q) where
g (D2 q) = D2 $ fromIntegral q -- LINE 1
このプログラムの結果
私がインスタンスを書いたとき、私は確かにbBase ~ D2 t
を意図しました。私はtが何とか結ばれていないと思うので(t0の導入)、GHCがこのタイプをまったく解体できないかどうかわかりません。あるいは、私はちょっとばかげたことをやっているかもしれません。
さらに、Barにパラメータをkind * - > * - > *にすると、この種の型の平等/型の解体は必要ありません。しかし、私はFooの制約を強制することができませんでした:
class (Foo (b q)) => Bar b where -- b has kind * -> * -> *
g :: b q m -> q b' -- this signature is now quite simple, and I would have no problem implementing it
qはバーにパラメータではありませんので、これは動作しません、と私はがバーにパラメータににそれを望んでいません。
私は2つの余分な「ダミー」の関連タイプを使用して解決策を見つけたが、私は本当に周りにそれらを持つように私はそれらを必要としないしない場合:これは動作します
class (Foo b, b ~ (BBase b) (BMod b)) => Bar b where -- b has kind * -> *
type BBase b :: * -> * -> *
type BMod b :: *
g :: (Qux (BMod b), Qux q') => b m -> (BBase b) q' m
instance (Foo (D2 t q), Integral q) => Bar (D2 t q) where
type BBase (D2 t q) = D2 t
type BMod (D2 t q) = q
g (D2 q) = D2 $ fromIntegral q
、それが明示的になります単純な型のインスタンスがあれば、型を解体する必要はありません。
どちらのアプローチにも解決策を探しています:「より適用された」タイプのクラス制約を適用する方法を教えてください。あるいは、GHC解体型を作成する方法を教えてください。
ありがとうございます!
「amy16.hs:7:1: 不正な等式制約b〜bベースq1 (これを許可するには-XGADTsまたは-XTypeFamiliesを使用してください) クラスメソッドをチェックするとき: g :: forall(bBase :: * - * *)q1(b ':: * - > *)q2 m。 === === bm - > b 'm 'Bar'のクラス宣言で が失敗しましたモジュールがロードされました:none.'だから' GADTの言語プラグマまたは 'TypeFamilies'プラグマ、および場合によっては他のプラグマも含まれます。 – mhwombat
私は上記のコードでコンパイルフラグ/言語プラグマを含んでいませんでしたが、もちろん、これらの用語(すべてのスニペットを動作させるはずです)に必要なものすべてを使用しています:TypeFamilies、FlexibleContexts、UndecidableInstances、TypeOperators、DataKinds 、ConstraintKinds、FlexibleInstances – crockeea