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?
Essentially, a >> b can be read like "do a then do b , and return the result of b ". It's similar to the more common bind operator >>= .
The order of evaluation in Haskell is determined by one and only one thing: Data Dependence. An expression will only be evaluated when it is needed, and will not be evaluated if it is not needed.
a -> b Bool means... forall (a :: *) (b :: * -> *). a -> b Bool. b is therefore a type constructor taking a single type argument. Examples of single-argument type constructors abound: Maybe , [] , IO are all examples of things which you could use to instantiate b .
Haskell is a lazy language. It does not evaluate expressions until it absolutely must. This frequently allows our programs to save time by avoiding unnecessary computation, but they are at more of a risk to leak memory. There are ways of introducing strictness into our programs when we don't want lazy evaluation.
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).
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