多数据构造函数的Monad实例

时间:2016-05-04 16:42:38

标签: haskell monads

我不久前开始使用Haskell,现在正在教我自己的monad,所以我在这里为自己想出了一个愚蠢的例子来帮助我理解monad的一个方面。

给定Certainty类型定义为

data Certainty a = Definitely a | Perhaps a | Nope

和所述类型的Monad实例

instance Monad Certainty where
  return = ...

如何为Certainty及其每个数据构造函数定义方法return

2 个答案:

答案 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)

当然,Carsten的答案是完全正确的,但根据我的经验,通常more intuitive通过定义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

当然,>>=可以用joinfmap来定义(这对于Certainty来说是微不足道的,并且可以由ghc自动找到使用-XDeriveFunctor

x >>= f = join (fmap f x)

这使我的定义等同于Carsten'

此外,通过查看join定义的最后三行,我们看到所有x :: Certainty a我们都有join (Definitely x) = x,这表明

 return x = Definitely x