Haskell で組み込み言語の安全な表現を作成するには、多くの拡張機能を使用する必要がありました。関数の相互依存関係を導入したある時点で、型推論は停止し、型変数の正しい置換を見つけ出しました。以下の例を参照してください。
-- create a bidirectional connection between Unit' and ()
class Connect t r | t -> r, r -> t where
data Unit'
instance Connect Unit' () where
-- define a GADT that has only a MyGADT Unit' instance
data MyGADT t where
MyGADT :: () -> MyGADT Unit'
class Clas a where
type RetTyp a :: *
eval' :: Connect (RetTyp a) r => a -> r
instance Clas (MyGADT t) where
type RetTyp (MyGADT t) = t
eval' (MyGADT a) = a -- cannot figure out that "a :: ()"
興味深いことに、TypeFamily を使用したときはConnect
問題ありませんでした。
class Connect' t where
type Repr t :: *
instance Connect' Unit' where
type Repr Unit' = ()
class Clas' a where
type RetTyp' a :: *
eval'' :: Connect' (RetTyp a) => a -> (Repr (RetTyp' a))
instance Clas' (MyGADT t) where
type RetTyp' (MyGADT t) = t
eval'' (MyGADT a) = a -- ok
2 つのケースの型解決の違いは何ですか?