2016-02-11 42 views
4

真正意義據我所知,代碼列表發電機在Haskell

l = [(a,b)|a<-[1,2],b<-[3,4]] 

相當於

l = do 
    a <- [1,2] 
    b <- [3,4] 
    return (a,b) 

[1,2] >>= (\a -> [3,4] >>= (\b -> return (a,b))) 

的類型這樣的表達的是[( t,t1)]其中t和t1在Num中。

如果我喜歡寫東西

getLine >>= (\a -> getLine >>= (\b -> return (a,b))) 

解釋讀取兩行並返回一個包含它們的元組。

但我可以在列表生成器中使用getLine或類似的東西嗎?

表達

[x|x<-getLine] 

返回錯誤 「不能匹配預期類型[t0]' with actual type IO字符串」「

但是,當然,這個作品在DO-符號或使用(>> =) 。

列表生成器有什麼意義,它們和標記之間有什麼實際區別?

使用列表生成時是否有任何類型限制?

回答

9

這是一個明智的觀察,你不是在那蹣跚的第一個。你是對的,[x|x<-getLine]的翻譯將導致一個完全有效的monadic表達式。關鍵是列表解析是我認爲first僅作爲列表的便利語法引入,並且(可能)沒有人認爲人們可以將它們用於其他單子。

然而,由於限制[]是不是真的一個必要條件,有一個GHC擴展名爲-XMonadComprehensions這消除了限制,並允許你寫你想要什麼:

Prelude> :set -XMonadComprehensions 
Prelude> [x|x<-getLine] 
sdf 
"sdf" 
+1

我聽到傳言說內涵*用於*爲任何monad工作,但錯誤信息是不可理解的,所以它被改變了。儘管如此,我還沒有一個引用...... – MathematicalOrchid

+0

那麼,如果在過去的日子裏,翻譯是純粹的重寫和獨立於類型檢查......也許在有人嚴格應用報告中的站點之前,這是有道理的。 – phg

+4

@MathematicalOrchid:有[此票](https://ghc.haskell.org/trac/ghc/ticket/4370)和[本維基頁面](https://ghc.haskell。組織/ TRAC/GHC /維基/ MonadComprehensions);都表明MonadComprehensions最初被允許,然後被刪除,並且隨後通過語言擴展加回。 – Zeta