【发布时间】:2021-04-20 14:42:26
【问题描述】:
这个问题来自“Haskell Programming from first principle”一书第 18.5 节“Monad 法则”的“Bad monads and their denizens”一节。
data CountMe a =
CountMe Integer a
deriving (Eq, Show)
instance Functor CountMe where
fmap f (CountMe i a) =
CountMe i (f a)
instance Applicative CountMe where
pure = CountMe 0
CountMe n f <*> CountMe n' a =
CountMe (n + n') (f a)
instance Monad CountMe where
return = pure
CountMe n a >>= f =
let CountMe n' b = f a
in CountMe (n + n') b
我在理解 Monad CountMe 的绑定如何使用等式推理时遇到了一些问题:
CountMe (n + n') b
变成
CountMe n b + CountMe n' b
变成
CountMe n b + f a
这是正确的吗?如果是这样,CountMe n b 会变成什么?
如果无法进行等式推理,我应该如何理解它是如何工作的?
CountMe n a >>= f =
let CountMe n' b = f a
in CountMe (n + n') b
【问题讨论】:
-
CountMe (n + n') b = CountMe n b + CountMe n' b看起来不对 - 据我所知,您的CountMe没有+。我也很难看到您尝试扩展/证明的内容(bind/>>=似乎根本没有参与您所写的内容) -
@Carsten,谢谢,我已经更新了我的问题。
-
这里的模式匹配是否给您带来了一些困惑?这实际上与
bind (n, a) f = let { (n', b) = f a } in (n + n', b)或bind p1 f = let { p2 = f (snd p1) } in (fst p1 + fst p2, snd p2)相同——这些更清楚吗?也就是说,CountMe a类型的值等价于一对(Integer, a),Monad实例中的绑定实现在这样一对p1上调用函数f,并将p1与该函数p2的结果,对第一个组件和后对的第二个组件使用求和。 -
@JonPurdy,谢谢,您的回答有点帮助。我认为最具解释性的答案来自@DavidFletcher,因为他提供了一个在一定程度上将
myfunc与x分离的示例。在我仔细考虑他的答案之前,我的想法是尝试做CountMe n b = f a...