我看到提到过
ListT
是一个不满足monad 法则的有问题的 monad 转换器的典型例子。
这可以通过一个简单的例子来证明吗?
编辑:我的想法ListT []
有点错误,我错过了文档要求内部单子是可交换的。那么,ListT
仅仅是有这个要求的意义上的越野车,还是还有其他问题?(Haskell wiki 上的示例都使用ListT IO
并且IO
显然不是可交换的。)
我看到提到过
ListT
是一个不满足monad 法则的有问题的 monad 转换器的典型例子。
这可以通过一个简单的例子来证明吗?
编辑:我的想法ListT []
有点错误,我错过了文档要求内部单子是可交换的。那么,ListT
仅仅是有这个要求的意义上的越野车,还是还有其他问题?(Haskell wiki 上的示例都使用ListT IO
并且IO
显然不是可交换的。)
一个简单的例子说明它是如何不符合结合律的:
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找到。