在Monad的以下实例中:
instance Monad ((->) r) where
return = const
f >>= k = \ r -> k (f r) r
这是强制k
是两个参数的函数吗?如果是这样,为什么要将(f r)
和r
传递给k
?
答案 0 :(得分:9)
这是强迫k是两个参数的函数吗?
是。看一下Monad
的定义,我们有
class Monad m where
return :: a -> m a
(>>=) :: m a -> (a -> m b) -> m b
将(->) r
替换为m
,我们有
return :: a -> (->) r a
(>>=) :: (->) r a -> (a -> (->) r b) -> (->) r b
现在,(->) r a
只是r -> a
的一种奇怪的语法,对于其他情况也是如此,所以我们得到了
return :: a -> r -> a
(>>=) :: (r -> a) -> (a -> r -> b) -> r -> b
所以我们可以看到>>=
的第二个参数确实必须是(至少)两个参数的函数。
为什么呢?因为两个参数的函数只是一个函数接受一个参数并返回一个参数的函数,而>>=
的第二个参数应该是一个函数接受一个参数并返回一个monad类型的值构造函数;对于函数monad,此值将是一个函数。因此>>=
的第二个参数将是两个参数的函数。
[W] hy你想把(f r)AND r传给k?
部分是因为它使(->) r
类型符合Monad的统一结构,这有很多原因。
部分k
并不知道您正在使用哪个功能f
。这意味着,从k
的角度来看,两个参数f r
和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
并不关心它的参数来自何处,或者特别是它的参数是输入的第一个组成部分。因此它需要参数{{1}}和完整输入。