我很难理解一个函数如何成为一个单子。
(->) r
根据以下声明,函数是一个 monad Control.Monad.Instances
:
instance Monad ((->) r) where
return x = \_ -> x
h >>= f = \w -> f (h w) w
甚至 Miran Lipovača所说的也让我感到困惑:
for 的实现
>>=
似乎有点神秘,但实际上并非如此。当我们用>>=
一个单子值给一个函数时,结果总是一个单子值。所以在这种情况下,当我们将一个函数提供给另一个函数时,结果也是一个函数。这就是为什么结果以 lambda 开始的原因。>>=
到目前为止,所有的实现 总是以某种方式将结果与一元值隔离,然后将函数 f 应用于该结果。同样的事情也发生在这里。要从函数中获取结果,我们必须将其应用到某物上,这就是为什么我们在(h w)
这里从函数中获取结果,然后将 f 应用到该函数上的原因。f 返回一个单子值,在我们的例子中是一个函数,所以我们也将它应用到 w 上。
(>>=) 的类型签名是这样的: (>>=) :: ma -> (a -> mb) -> mb
所以我认为h
它的类型是 asm a
和f
as (a -> m b)
。如果一个函数是m a
,它是否返回一个a
类型值?还是返回其他a
类型的东西?
如果将 的非单子值h
馈送到f
,那么我们得到: f (hw) 看起来不错。既然f
是一个函数并且接受了它的唯一参数,那么它已经是一个值了,不是吗?由于它是一元函数,因此该值也是一元值。那么为什么它需要另一个值w
呢?喂食不是w
让它f something
成为非单子的,也就是说,它不再是一个函数,不是吗?我也无法理解为什么f something
并h
采用相同的参数w
并返回不同的值类型(m a
和m b
)。