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