2012-09-27 29 views
24

我見過提到爲什麼ListT monad變壓器被認爲是越野車 - 它打破了哪些monad法則?

ListT是一個有錯誤的單子變壓器不符合monad laws一個典型的例子。

這可以通過一個簡單的例子來演示嗎?

編輯:我的想法與ListT []有點不對,我錯過了documentation要求內部monad是可交換的。那麼,ListT只是在這個要求的意義上,還是有另一個問題? (該examples at Haskell wiki都使用ListT IOIO顯然是不可交換的。)

回答

19

一個簡單的例子來展示它是如何失敗的關聯性規律:

v :: Int -> ListT [] Int 
v 0 = ListT [[0, 1]] 
v 1 = ListT [[0], [1]] 

main = do 
    print $ runListT $ ((v >=> v) >=> v) 0 
    -- = [[0,1,0,0,1],[0,1,1,0,1],[0,1,0,0],[0,1,0,1],[0,1,1,0],[0,1,1,1]] 
    print $ runListT $ (v >=> (v >=> v)) 0 
    -- = [[0,1,0,0,1],[0,1,0,0],[0,1,0,1],[0,1,1,0,1],[0,1,1,0],[0,1,1,1]] 

更多的例子(大多采用IO)和解決方案如何解決ListT可在ListT done right找到。

+2

該文件說變換的monad必須是可交換的;嘗試使用例如'v n = ListT $ map(read :: String - > Int)。排列。顯示 。 (+ n)' – applicative

+1

@applicative好點,我錯過了。我嘗試過使用'( - >)'monad,但到目前爲止我找不到反例。 –

+8

呃......他們被稱爲「monad變形金剛」,而不是「交換單體變形金剛」。如果我定義了一個變壓器只適用於幾個特定的​​monads時才能正確工作,那麼是否有人會認爲滿意? –