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?
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).
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.
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
()
The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.