Haskell中的函数monad中的绑定是如何工作的?

Md *_*vel 4 monads haskell

从了解到一个哈克尔:http://learnyouahaskell.com/for-a-few-monads-more

函数的Monad实例是这样的:

instance Monad ((->) r) where  
    return x = \_ -> x  
    h >>= f = \w -> f (h w) w 
Run Code Online (Sandbox Code Playgroud)

我无法理解以下内容的输出:

import Control.Monad.Instances  

addStuff :: Int -> Int  
addStuff = do  
    a <- (*2)  
    b <- (+10)  
    return (a+b)
Run Code Online (Sandbox Code Playgroud)

addStuff 3返回19.书中说3作为参数传递给两者(*2) and (+10).怎么样?

h >>= f = \w -> f (h w) w,它似乎(h w)被绑定到a或b.那么,为什么6不被传递(+10)?

我的理解f这里的是,当(*2)h,f是最后2行addStuff.如果(+10)h,f是最后一行(在这种情况下,返回语句)的addStuff.

Wil*_*sem 7

让我们先来讨论这个do块[Haskell'10报告]:

addStuff = do
    a <- (*2)
    b <- (+10)
    return (a+b)
Run Code Online (Sandbox Code Playgroud)

相当于:

addStuff = (*2) >>= \a -> ((+10) >>= \b -> return (a + b))
Run Code Online (Sandbox Code Playgroud)

(+10) >>= \b -> return (a + b)因此可以将内部绑定表达式()转换为绑定定义:

\w -> (\b -> return (a + b)) ((+10) w) w
Run Code Online (Sandbox Code Playgroud)

如果我们替代returnconst,因此,我们得到:

\w -> (const . (a+)) ((+10) w) w
Run Code Online (Sandbox Code Playgroud)

因此,我们有一个功能,作为输入w,然后调用const . (a+)(w+10)w,所以它会忽略最后w.在语义上它相当于:

(a+) . (+10)
Run Code Online (Sandbox Code Playgroud)

所以现在我们addStuf相当于:

addStuff = (*2) >>= \a -> ((a+) . (+10))
Run Code Online (Sandbox Code Playgroud)

如果我们现在再次使用绑定运算符的定义,我们会看到:

\w -> (\a -> ((a+) . (+10))) ((*2) w) w
Run Code Online (Sandbox Code Playgroud)

或更短:

\w -> (\a -> ((a+) . (+10))) (w*2) w
Run Code Online (Sandbox Code Playgroud)

现在,我们可以substitue a(w*2)和获得:

\w -> ((w*2)+) . (+10)) w
Run Code Online (Sandbox Code Playgroud)

所以我们addStuf相当于:

addStuff w = (w*2) + (w+10)
Run Code Online (Sandbox Code Playgroud)

或者更简单:

addStuff w =  3*w + 10
Run Code Online (Sandbox Code Playgroud)