I've seen mentioned that IO
doesn't satisfy the monad laws, but I didn't find a simple example showing that. Anybody knows an example? Thanks.
Edit: As ertes and n.m. pointed out, using seq
is a bit illegal as it can make any monad fail the laws (combined with undefined
). Since undefined
may be viewed as a non-terminating computation, it's perfectly fine to use it.
So the revised question is: Anybody knows an example showing that IO
fails to satisfy the monad laws, without using seq
? (Or perhaps a proof that IO
does satisfy the laws if seq
is not allowed?)
The IO monad in Haskell is often explained as a state monad where the state is the world. So a value of type IO a monad is viewed as something like worldState -> (a, worldState) .
Conclusion. Monad is a simple and powerful design pattern for function composition that helps us to solve very common IT problems such as input/output, exception handling, parsing, concurrency and other.
A monad is essentially just a functor T with two extra methods, join , of type T (T a) -> T a , and unit (sometimes called return , fork , or pure ) of type a -> T a .
What is a Monad? A monad is an algebraic structure in category theory, and in Haskell it is used to describe computations as sequences of steps, and to handle side effects such as state and IO. Monads are abstract, and they have many useful concrete instances. Monads provide a way to structure a program.
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
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