だから、私はデータ型を定義するとしましょう
data WAtom a = WAtom {innerVal :: a, temper :: WPart a -> WPart a }
data WPart a where
WUnit :: WAtom a -> WPart a
WCompound :: WAtom a -> WAtom a -> WPart a
atomize :: WPart a -> a
atomize (WUnit a) = innerVal a
{- Write one for compound too -}
ここで、WPart を Monad のインスタンスにしたいと思います。これまでのところ、すべて順調に見えます。bind
モナドのinnerValでバインドされた関数を呼び出して、新しいモナドを生成することで操作したいと思います。temper
次に、元のモナドでこの新しいモナドを呼び出します。
instance Monad (WPart) where
return a = WUnit $ WAtom a
(WUnit c) >>= f = let new_part = f $ innerVal c in
(temper $ atomize new_part) (WUnit c)
ただし、これは型チェックを行いません。f
モナドの定義は、 in bind がモナドの内部型を変更できると主張しています。これは私には理にかなっています。しかし、私はジレンマに悩まされているようです: 1) WAtom が取ることができる型を制限する場合、代わりにデータ型を定義するWAtom Int
と、Monads * -> * の種類制限に違反します。しかし、そうしないと、f
in bind が渡された元のモナドと同じ型のモナドを返すことを知ることができませんtemper
。
私はこれについて間違って考えているだけだと確信しています。誰にもアイデアはありますか?
ベスト、エリック