All monads in Haskell are only monads if you exclude the weird seq
combinator. This is also true for IO
. Since seq
is not actually a regular function but involves magic, you have to exclude it from checking the monad laws for the same reason you have to exclude unsafePerformIO
. Using seq
you can prove all monads wrong, as follows.
In the Kleisli category the monad gives rise to, return
is the identity morphism and (<=<)
is composition. So return
must be an identity for (<=<)
:
return <=< x = x
Using seq
even Identity and Maybe fail to be monads:
seq (return <=< undefined :: a -> Identity b) () = ()
seq (undefined :: a -> Identity b) () = undefined
seq (return <=< undefined :: a -> Maybe b) () = ()
seq (undefined :: a -> Maybe b) () = undefined