Haskell 无法理解Monad(->;)

Haskell 无法理解Monad(->;),haskell,Haskell,在Monad的以下实例中: instance Monad ((->) r) where return = const f >>= k = \ r -> k (f r) r 这是否迫使k成为两个参数的函数?如果是这样,为什么要将(fr)和r传递到k 这是否迫使k是两个参数的函数 对。查看Monad的定义,我们有 class Monad m where return :: a -> m a (>>=) :: m a ->

在Monad的以下实例中:

instance Monad ((->) r) where
    return = const
    f >>= k = \ r -> k (f r) r
这是否迫使
k
成为两个参数的函数?如果是这样,为什么要将
(fr)
r
传递到
k

这是否迫使k是两个参数的函数

对。查看
Monad
的定义,我们有

class Monad m where
    return :: a -> m a
    (>>=) :: m a -> (a -> m b) -> m b
return :: a -> (->) r a
(>>=) :: (->) r a -> (a -> (->) r b) -> (->) r b
(>)r
代替
m
,我们有

class Monad m where
    return :: a -> m a
    (>>=) :: m a -> (a -> m b) -> m b
return :: a -> (->) r a
(>>=) :: (->) r a -> (a -> (->) r b) -> (->) r b
现在,
(>)ra
只是
r->a
的一种奇怪的语法,对于其他情况也是如此,所以我们得到

return :: a -> r -> a
(>>=) :: (r -> a) -> (a -> r -> b) -> r -> b
因此我们可以看到,
>=
的第二个参数必须是(至少)两个参数的函数

为什么??因为两个参数的函数只是一个取一个参数并返回一个参数的函数,而
>=
的第二个参数应该是一个取一个参数并返回monad类型构造函数值的函数;对于函数monad,此值将是一个函数。因此,
>>=
的第二个参数将是两个参数的函数

[W] 你为什么要通过(fr)和r到k

部分原因是它使
(>)r
类型适合单子的统一结构,这在很多方面都很有用

部分
k
不知道您正在使用哪个函数
f
。这意味着,从
k
的角度来看,
fr
r
这两个参数实际上是独立的--
k
无法从另一个参数中计算出一个参数

考虑这一功能:

-- | 'f' takes two numbers and adds them together
f :: (->) (Int, Int) Int
f = fst >>= \ n0 -> snd >>= \ n1 -> return (n0 + n1)

函数
\n0->snd>=\n1->return(n0+n1)
不关心它的参数来自哪里,特别是它的参数是输入的第一个组件。因此,它需要参数
n0
和完整输入。

您可能会喜欢读卡器monad(搜索“reader”)。是
k
是一个函数
a->r->b
r
是您拥有的
r
的唯一实例,而
f r
是获得
a
的唯一方法,因此您没有太多选择。的可能重复