所以,说我定义了数据类型
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上调用这个新monad的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)
然而,这并不是一个类型的问题。 monad的定义认为绑定中的f
可以改变monad的内部类型。这对我来说很有意义。然而,我似乎陷入了两难境地:1)如果我限制了WAtom可以采用的类型,那么将数据类型定义为WAtom Int
然后我将对Monads *的种类限制发生冲突* - &gt ; *。但是,如果我不这样做,那么我就不知道绑定中的f
将返回与传入的原始monad相同类型的monad。此外,我无法生成{{1}由于显而易见的原因存在量化。
我确定我只是想到这个错误。有人有什么想法吗?
最佳, 埃里克
答案 0 :(得分:1)
假设WUnit c :: WPart a
我们f :: a -> WPart b
new_part :: WPart b
和atomize new_part :: b
...所以我们已经无法调用temper :: forall a. WAtom a -> WPart a -> WPart a
,除非我们可以约束{{1}对于某些b ~ WPart (WAtom e)
。更糟糕的是,即使e
我们仍然temper $ atomize new_part :: WPart b -> WPart b
WUnit c :: WPart a
,a ~ b
一般也没有。
所以,这绝对不是Monad
的实现。