2015-09-20 19 views
2

我遇到小麻煩把這項do語句塊:脫糖「做」

ex10 :: [Int] 
ex10 = do 
    num <- [1..20] 
    guard (even num) 
    guard (num `mod` 3 == 0) 
    return num 

變成某種monad語法如下:

ex10' :: [Int] 
ex10' = [1..20] >>= (guard . even) >>= (guard . (==0) . (mod 3)) >>= \r -> return r 

這不工作,我我不太清楚爲什麼。我想我可能誤解了guard但我不確定以什麼方式。

+1

你錯過了'num'結合。您需要在第一個「>> =」處命名,以便在隨後的條件中重用它。 –

+0

另請注意,對於沒有<<-'的行,使用'>>'而不是'>> ='。 –

+2

你寫的代碼是'do {num < - [1..20]; x < - guard(偶數); r < - guard(x \'mod \'3 == 0);返回r}'。 –

回答

4

guard具有類型MonadPlus m => Bool -> m()所以你的第三段

(guard . (==0) . (mod 3)) 

接收()類型的值,這是不是你想要的。在do符號

do 
    guard (even num) 
    guard (num `mod` 3 == 0) 

被desugarded成類似

guard (even num) >> guard (num `mod` 3 == 0) 

這樣你就可以實現ex10'作爲

ex10' = [1..20] >>= (\num -> (guard $ even num) >> (guard $ num `mod` 3 == 0) >> return num)