麻烦理解Monad( - >)

Gre*_*aro 7 haskell

在Monad的以下实例中:

instance Monad ((->) r) where
    return = const
    f >>= k = \ r -> k (f r) r
Run Code Online (Sandbox Code Playgroud)

这个强制k是两个参数的函数吗?如果是这样,你为什么会想通过(f r)rk

Jon*_*ast 9

这个强迫k是两个参数的函数吗?

是.看看Monad我们的定义

class Monad m where
    return :: a -> m a
    (>>=) :: m a -> (a -> m b) -> m b
Run Code Online (Sandbox Code Playgroud)

(->) rm,我们有

return :: a -> (->) r a
(>>=) :: (->) r a -> (a -> (->) r b) -> (->) r b
Run Code Online (Sandbox Code Playgroud)

现在,(->) r a这只是一个奇怪的语法r -> a,并且类似于其他情况,所以我们得到

return :: a -> r -> a
(>>=) :: (r -> a) -> (a -> r -> b) -> r -> b
Run Code Online (Sandbox Code Playgroud)

所以我们可以看到,确实第二个参数>>=必须是(至少)两个参数的函数.

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

[W] hy你想传递(fr)和r到k吗?

部分是因为它使(->) r类型适合Monad的统一结构,这有很多原因.

部分k不知道f你正在使用哪个功能.这意味着,从k的角度来看,这两个参数f rr真正独立--- k无法计算从另一个.

考虑这个功能:

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

该函数\ n0 -> snd >>= \ n1 -> return (n0 + n1)不关心其参数的来源,或者特别是它的参数是输入的第一个组件.因此它需要参数n0和完整输入.