从了解到一个哈克尔: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.
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)
如果我们替代return用const,因此,我们得到:
\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)