Haskell 中的函数 monad 中的绑定是如何工作的?
How binding works in function monads in Haskell?
从学你一个haskell:http://learnyouahaskell.com/for-a-few-monads-more
函数的 Monad 实例是这样的:
instance Monad ((->) r) where
return x = \_ -> x
h >>= f = \w -> f (h w) w
我无法理解以下输出:
import Control.Monad.Instances
addStuff :: Int -> Int
addStuff = do
a <- (*2)
b <- (+10)
return (a+b)
addStuff 3
returns 19. 书上说 3 作为参数传递给 (*2)
and (+10)
。怎么样?
从 h >>= f = \w -> f (h w) w
开始,似乎 (h w)
被绑定到 a 或 b。
那么,为什么 6 没有传入 (+10)?
我这里对f
的理解是,当(*2)
是h
时,f
就是addStuff
的最后2行。当 (+10)
是 h
时,f
是 addStuff
.
的最后一行(在本例中是 return 语句)
Haskell do
符号是一系列 >>=
绑定的语法糖;在这种情况下,对于这样的事情:
addStuff = (*2) >>= (\a -> (+10) >>= (\b -> return (a + b)))
让我们先desugar the do
block [Haskell'10 report]:
addStuff = do
a <- (*2)
b <- (+10)
return (a+b)
相当于:
addStuff = (*2) >>= \a -> ((+10) >>= \b -> return (a + b))
内部绑定表达式 ((+10) >>= \b -> return (a + b)
),因此可以将绑定定义转换为:
\w -> (\b -> return (a + b)) ((+10) w) w
如果我们将return
替换为const
,我们将得到:
\w -> (const . (a+)) ((+10) w) w
因此我们有一个函数将 w
作为输入,然后在 (w+10)
和 w
上调用 const . (a+)
,因此它将忽略最后一个 [=25] =].在语义上它等同于:
(a+) . (+10)
所以现在我们的 addStuf
等同于:
addStuff = (*2) >>= \a -> ((a+) . (+10))
如果我们现在再次使用绑定运算符的定义,我们会看到:
\w -> (\a -> ((a+) . (+10))) ((*2) w) w
或更短:
\w -> (\a -> ((a+) . (+10))) (w*2) w
我们现在可以用(w*2)
代替a
得到:
\w -> ((w*2)+) . (+10)) w
所以我们的addStuf
相当于:
addStuff w = (w*2) + (w+10)
或更简单:
addStuff w = 3*w + 10
在计算步骤之间传递更新的参数(这将充当状态的角色)是另一个 monad 的工作,即 State monad。
函数又名 Reader monad 比那个更简单,做的工作更少:
-- (return x) w = x
-- (h >>= f) w = f (h w) w
(h >>= (\a -> g >>= (\b -> return (f a b)))) w
=
(\a -> g >>= (\b -> return (f a b))) (h w) w
=
(g >>= (\b -> return (f (h w) b))) w
=
(\b -> return (f (h w) b))) (g w) w
=
return (f (h w) (g w)) w
=
f (h w) (g w)
因此,输入参数 w
被 未更改 传递到两个(通过扩展,所有)计算步骤。或者在您询问的特定情况下,
liftM2 (+) ( *2) ( +10) w
=
(+) (w*2) (w+10)
liftM2
函数相当于你显示的 do
块,
liftM2 f h g =
do {
a <- h ;
b <- g ;
return (f a b) }
=
h >>= (\ a ->
g >>= (\ b -> return (f a b) ))
在任何单子中。
从学你一个haskell:http://learnyouahaskell.com/for-a-few-monads-more
函数的 Monad 实例是这样的:
instance Monad ((->) r) where
return x = \_ -> x
h >>= f = \w -> f (h w) w
我无法理解以下输出:
import Control.Monad.Instances
addStuff :: Int -> Int
addStuff = do
a <- (*2)
b <- (+10)
return (a+b)
addStuff 3
returns 19. 书上说 3 作为参数传递给 (*2)
and (+10)
。怎么样?
从 h >>= f = \w -> f (h w) w
开始,似乎 (h w)
被绑定到 a 或 b。
那么,为什么 6 没有传入 (+10)?
我这里对f
的理解是,当(*2)
是h
时,f
就是addStuff
的最后2行。当 (+10)
是 h
时,f
是 addStuff
.
Haskell do
符号是一系列 >>=
绑定的语法糖;在这种情况下,对于这样的事情:
addStuff = (*2) >>= (\a -> (+10) >>= (\b -> return (a + b)))
让我们先desugar the do
block [Haskell'10 report]:
addStuff = do
a <- (*2)
b <- (+10)
return (a+b)
相当于:
addStuff = (*2) >>= \a -> ((+10) >>= \b -> return (a + b))
内部绑定表达式 ((+10) >>= \b -> return (a + b)
),因此可以将绑定定义转换为:
\w -> (\b -> return (a + b)) ((+10) w) w
如果我们将return
替换为const
,我们将得到:
\w -> (const . (a+)) ((+10) w) w
因此我们有一个函数将 w
作为输入,然后在 (w+10)
和 w
上调用 const . (a+)
,因此它将忽略最后一个 [=25] =].在语义上它等同于:
(a+) . (+10)
所以现在我们的 addStuf
等同于:
addStuff = (*2) >>= \a -> ((a+) . (+10))
如果我们现在再次使用绑定运算符的定义,我们会看到:
\w -> (\a -> ((a+) . (+10))) ((*2) w) w
或更短:
\w -> (\a -> ((a+) . (+10))) (w*2) w
我们现在可以用(w*2)
代替a
得到:
\w -> ((w*2)+) . (+10)) w
所以我们的addStuf
相当于:
addStuff w = (w*2) + (w+10)
或更简单:
addStuff w = 3*w + 10
在计算步骤之间传递更新的参数(这将充当状态的角色)是另一个 monad 的工作,即 State monad。
函数又名 Reader monad 比那个更简单,做的工作更少:
-- (return x) w = x
-- (h >>= f) w = f (h w) w
(h >>= (\a -> g >>= (\b -> return (f a b)))) w
=
(\a -> g >>= (\b -> return (f a b))) (h w) w
=
(g >>= (\b -> return (f (h w) b))) w
=
(\b -> return (f (h w) b))) (g w) w
=
return (f (h w) (g w)) w
=
f (h w) (g w)
因此,输入参数 w
被 未更改 传递到两个(通过扩展,所有)计算步骤。或者在您询问的特定情况下,
liftM2 (+) ( *2) ( +10) w
=
(+) (w*2) (w+10)
liftM2
函数相当于你显示的 do
块,
liftM2 f h g =
do {
a <- h ;
b <- g ;
return (f a b) }
=
h >>= (\ a ->
g >>= (\ b -> return (f a b) ))
在任何单子中。