Monad法则用连接而不是绑定来表达?

时间:2017-08-23 01:07:47

标签: haskell monads

monad法律传统上用>>=pure来描述:

pure a >>= k = k a
m >>= pure = m
m >>= (\x -> k x >>= h) = (m >>= k) >>= h

但是,monad也可以用join而不是>>=来定义。我想根据join提出monad法律的表述。

使用x >>= f = join (fmap f x),可以轻松重写现有的monad法则以消除>>=。在适用法律的帮助下,略微简化了结果,前两条法律得到了非常愉快的表达:

join . pure = id
join . fmap pure = id

对这些法则的直觉也很容易,因为很明显,当与pure结合使用join时,引入额外的“层”应该是无操作。然而,第三定律并不是那么好。最终看起来像这样:

  join (fmap (\x -> join (fmap h (k x))) m)
= join (fmap h (join (fmap k m)))

这并没有使用适用的法律令人愉快地减少,而且如果不盯着它看一段时间就很难理解。它当然不具备相同的直觉。

join方面的monad法则是否有更容易理解的等效替代公式?或者,有没有办法简化上述法律,或者让它更容易理解? >>=的版本已经不如使用Kleisli合成的版本好,但join的版本几乎不可读。

1 个答案:

答案 0 :(得分:18)

直接从Wikipedia

被盗

(自然变换η: 1 -> Tpure;自然变换µ: T^2 -> Tjoin

  

µ . Tµ = µ . µT

在Haskell:

join . fmap join = join . join

英文版:如果你从mmma :: Monad m => m (m (m a))开始使用三层monad,那么先将内层压平,然后将其展平为外层,或者先将外层展平为内层,然后将其展平,则无关紧要。这与您列为第三(关联性)的法律相同。

  

µ . Tη = µ . ηT = 1

在Haskell:

join . fmap pure = join . pure = id

英文:如果你从一层monad开始为ma :: Monad m => m a,那么你在它内部创建一个新图层然后展平它,或者如果你在它之外创建一个新图层然后再无关紧要压扁它,两者都是无所事事。这项法律是你的前两个法律的组合。