Erik Henriksson
Erik Henriksson

Reputation: 737

Why does haskell evaluate a in a >> b?

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

Answers (3)

Petr
Petr

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

Chris Kuklewicz
Chris Kuklewicz

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

Cubic
Cubic

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

Related Questions