我不久前开始使用Haskell,现在正在教我自己的monad,所以我在这里为自己想出了一个愚蠢的例子来帮助我理解monad的一个方面。
给定Certainty
类型定义为
data Certainty a = Definitely a | Perhaps a | Nope
和所述类型的Monad
实例
instance Monad Certainty where
return = ...
如何为Certainty及其每个数据构造函数定义方法return
?
答案 0 :(得分:6)
你必须根据我建议的命名选择一个
return value = Definitely value
请记住return a >>= f
必须是f a
bind 应该是
(Definitely a) >>= f = f a
(Perhaps a) >>= f = case f a of
Definitely b -> Perhaps b
Perhaps b -> Perhaps b
Nope -> Nope
Nope >>= _ = Nope
答案 1 :(得分:1)
join
函数来指定monad(特别是在这种情况下,任何孩子都会明白,如果妈妈说我们明天肯定有冰淇淋,这意味着我们或许有冰淇淋..)
join :: Certainty (Certainty a) -> Certainty a
join Nope = Nope
join (Perhaps Nope) = Nope
join (Perhaps (Perhaps x)) = Perhaps x
join (Perhaps (Definitely x)) = Perhaps x
join (Definitely Nope) = Nope
join (Definitely (Perhaps x)) = Perhaps x
join (Definitely (Definitely x)) = Definitely x
当然,>>=
可以用join
和fmap
来定义(这对于Certainty
来说是微不足道的,并且可以由ghc
自动找到使用-XDeriveFunctor
)
x >>= f = join (fmap f x)
这使我的定义等同于Carsten'
此外,通过查看join
定义的最后三行,我们看到所有x :: Certainty a
我们都有join (Definitely x) = x
,这表明
return x = Definitely x