I've seen mentioned that
ListT
is a classic example of a buggy monad transformer that doesn't satisfy the monad laws.
Can this be demonstrated by a simple example?
Edit: My idea with ListT []
is a bit wrong, I missed that the documentation requires the inner monad to be commutative. So, is ListT
buggy just in the sense that has this requirement, or is there another problem? (The examples at Haskell wiki all use ListT IO
and IO
is obviously not commutative.)
A simple example that shows how it fails the associativity law:
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]]
More examples (mostly using IO
) and a solution how to fix ListT
can be found at ListT done right.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With