簡體   English   中英

Haskell Monadic forms

[英]Haskell Monadic forms

一個簡單的問題:給定定義,(來自 Haskell SOE)

   do x — el; el\ ...; en 
    => el »= \x — do e2\ ...; en 

和:

do let decllist; el\...; en 
=> let decllist in do e2\ ...; en 

似乎這兩個構造是相同的:

do let x = e1
   e2

do x <- e1
   e2

都評估 e1,將其綁定到 e2,然后評估 e2。

是的?

讓我們在Maybe monad 中做一個簡單的例子:

foo = do
        let x = Just 1
        return x

bar = do
        x <- Just 1
        return x

對兩者都進行脫糖,我們得到

foo = let x = Just 1 in return x    -- do notation desugaring
    = return (Just 1)               -- let
    = Just (Just 1)                 -- definition of return for the Maybe monad

bar = let ok x = return x in Just 1 >>= ok   -- do notation desugaring
    = let ok x = return x in ok 1   -- definition of >>= for the Maybe monad
    = return 1                      -- definiton of ok
    = Just 1                        -- definition of return for the Maybe monad

作為參考,我使用的是 Haskell 2010 報告第 3.14 節的翻譯

不,它們不一樣。 例如,

do let x = getLine
   print x

翻譯成

let x = getLine in print x

這是一個類型錯誤,因為x的類型為IO String 我們要求打印計算本身,而不是其結果。


do x <- getLine
   print x

翻譯成

getLine >>= \x -> print x

這里x被綁定為計算的結果,它的類型是String ,所以這個類型檢查。


do -notation 中, let像往常一樣將值綁定到名稱,而<-用於執行單子綁定,即將名稱綁定到計算結果

假設e1Monad m => ma類型的計算,那么let x = e1x <- e1意味着有些不同的東西。

let版本中,當您在 do 表達式中使用x時,您正在處理Monad m => ma類型的值。

在另一個版本中,當您在 do 表達式中使用x時,您正在處理一個類型a的值(因為 do-notation 隱式處理對 monad 的映射)。

例如:

e :: IO Int
f :: Int -> Int

-- the following will result in a type error, since f operates on `Int`, not `IO Int`:
g = do let x = e
       return $ f x

-- the following will work:
g' = do x <- e
        return $ f x

沒有。 x <- e1轉換為e1 >>= \x -> ,一個不完整的表達式; let表達式只是一個普通的let 或者您是在問let(>>=)是否相同? 它們不是: (>>=)將被 monad 包裹的東西暴露給 function,它必須產生包裹在 monad 中的東西。 換句話說,對於x <- e1 ,對於某些ae1的類型必須是IO a ,但是對於let x = e1 e1的類型只是a ; 在這兩種情況下, x的類型都是a

暫無
暫無

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

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