Reputation: 737
The >> operator for Monads in haskell is often defined as
(>>) :: m a -> m b -> m b
a >> b = a >>= \_ -> b
It can be used to print things like
main = putStr "foo" >> putStrLn "bar"
Why does the compiler not optimize away the value of putStr "foo"
and just evaluate putStrLn "bar"
? It doesn't need it so why compute it?
Upvotes: 7
Views: 330
Reputation: 63399
As Chris said, it depends on the monad. Identity
or Reader
won't evaluate the part in front of >>
, because they don't need it to compute the result. Other monads, like Writer
, Maybe
, Either
, State
or IO
will.
Let's take Maybe
as an example. >>=
is defined as
Nothing >>= _ = Nothing
(Just x) >>= f = f x
So if we expand >>
we get
Nothing >> _ = Nothing
(Just x) >> y = y
So Maybe
must evaluate what's in front of >>
to see if the result will be Nothing
or y
.
IO
is purposely defined in a way so that the action is evaluated whether its result is needed or not (otherwise it would be just impossible to use).
Upvotes: 10
Reputation: 8153
It depends on the monad. In IO is is evaluated. In Identity the first is not evaluated:
> import Control.Monad.Identity
> import Control.Monad.Trace
> let x = trace "x" $ return () :: Identity ()
> let y = trace "y" $ return () :: Identity ()
> runIdentity $ x >> y
y
()
Upvotes: 6
Reputation: 15693
Huh? Of course it needs the value of putStr "foo"
. It's evaluated in >>=
- only the result of the action is thrown away, not the action itself if you want to think of monads as actions.
For example in a parser, that would mean throwing away the just parsed sequence - but it was still parsed, so the cursor is still being moved forward.
Upvotes: 6