2012-09-27 27 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时才能正确工作,那么是否有人会认为满意? –