0

だから、私はデータ型を定義するとしましょう

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 * -> * の種類制限に違反します。しかし、そうしないと、fin bind が渡された元のモナドと同じ型のモナドを返すことを知ることができませんtemper

私はこれについて間違って考えているだけだと確信しています。誰にもアイデアはありますか?

ベスト、エリック

4

1 に答える 1

1

so and ...WUnit c :: WPart aがあると仮定すると、いくつかのを制約できない限り、すでに呼び出すことはできません。さらに悪いことに、一般に成り立たない場所がまだあるとしても。f :: a -> WPart bnew_part :: WPart batomize new_part :: btemper :: forall a. WAtom a -> WPart a -> WPart ab ~ WPart (WAtom e)etemper $ atomize new_part :: WPart b -> WPart bWUnit c :: WPart aa ~ b

したがって、それは間違いなく の実装ではありませんMonad

于 2013-03-20T00:54:19.303 に答える