簡體   English   中英

Haskell中的函數monad中的綁定是如何工作的?

[英]How binding works in function monads in 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返回19.書中說3作為參數傳遞給(*2) and (+10) 怎么樣?

h >>= f = \\w -> f (hw) w ,似乎(hw)被綁定到a或b。 那么,為什么6不被傳遞(+10)?

我對f理解是,當(*2)hfaddStuff的最后2行。 (+10)hfaddStuff的最后一行(在本例中為return語句)。

讓我們先看看do塊[Haskell'10報告]

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

如果我們用const替換return ,我們就得到:

\w -> (const . (a+)) ((+10) w) w

因此,我們有一個函數,它接受輸入w ,然后調用const . (a+) const . (a+) on (w+10)w ,所以它將忽略最后一個w 在語義上它相當於:

(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

哈斯克爾do記號是一系列的語法糖>>=綁定; 在這種情況下,對於這樣的事情:

addStuff = (*2) >>= (\a -> (+10) >>= (\b -> return (a + b)))

在計算步驟之間傳遞更新的參數(因此將服務於一個國家的角色)是另一個monad的工作,即State monad。

函數Read 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) ))

在任何monad。

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM