我看到提到过
ListT
is a classic example of a buggy monad transformer that doesn't satisfy the monad laws.
这可以通过一个简单的例子来证明吗?
编辑:我对
ListT []
的想法有点不对,我错过了documentation要求内部单子(monad)是可交换的。所以,是 ListT
buggy 只是在有这个要求的意义上,还是有其他问题? (examples at 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 找到.
关于haskell - 为什么 ListT monad 转换器被认为是错误的 - 它违反了哪些 monad 法则?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/12617916/