简体   繁体   中英

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?

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.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM