当我正在研究谈话时,我遇到了一些我认为不可能的事情,我仍然无法弄清楚它为什么会起作用。在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
这怎么可能?显然,tail
和head
在输出m
中有所不同。
*或类型检查器会推断出以下类型:forall t2. Array (Array t2) -> Array t2
答案 0 :(得分:3)
因此,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
与Maybe
和a
,b
和c
替换为a
或{{Array a
1}}类型为composeKliesli
。