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通过调用 monad 的 innerVal 上的绑定函数来生成一个新的 monad。然后在原始 monad 上调用这个新的tempermonad:

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)

但是,这不会进行类型检查。monad 的定义认为fin bind 可以改变 monad 的内部类型。这对我来说很有意义。但是,我似乎处于两难境地:1)如果我限制 WAtom 可以采用的类型,请说定义数据类型,因为WAtom Int这样我将违反 Monads * -> * 的种类限制。但如果我不这样做,那么我无法知道in bind 将返回与传入的原始 monad 相同类型的 monad。此外,由于明显的原因f,我无法进行存在量化。temper

我确定我只是在想这个错误。有人有想法么?

最好的,埃里克

4

1 回答 1

1

假设WUnit c :: WPart a我们有f :: a -> WPart bso new_part :: WPart band atomize new_part :: b... 所以我们已经无法调用temper :: forall a. WAtom a -> WPart a -> WPart a,除非我们可以限制b ~ WPart (WAtom e)some e。更糟糕的是,即使temper $ atomize new_part :: WPart b -> WPart b我们仍然有WUnit c :: WPart awherea ~ b通常不成立。

所以,这绝对不是Monad.

于 2013-03-20T00:54:19.303 回答