Monad 不组合,对吧?

Monads do not compose, right?

当我在研究一个演讲时,我遇到了一些我认为不可能的事情,我仍然无法弄清楚它为什么有效。在Control.Bind模块中,有fish算子的定义:

composeKleisli ∷ ∀ a b c m. Bind m ⇒ (a → m b) → (b → m c) → a → m c

上面的文档给出了一个例子:

third = tail >=> tail >=> head

这是我脑子里没有计算的地方。我以为它永远不会编译*,但它确实可以:

> :t tail >=> tail >=> head
forall t2. Array t2 -> Maybe t2

怎么会这样?显然 tailhead 的输出不同 m.

* 或者类型检查器会推断出以下类型:forall t2. Array (Array t2) -> Array t2

所以,m 在那种情况下是 Maybe,因此你不需要组合不同类型的 monad。

更具体地说:

tail :: forall a. Array a -> Maybe (Array a)
head :: forall a. Array a -> Maybe a

所以

composeKliesli tail tail :: forall a. Array a → Maybe (Array a)
composeKliesli (composeKliesli tail tail) head :: forall a. Array a -> Maybe a

要看到您需要将 m 替换为 Maybea,将 bc 替换为 aArray a 类型为 composeKliesli.