The GHC manual states this about monadic binding in GHCI:
Another important difference between the two types of binding is that the monadic bind (p <- e) is strict (it evaluates e), whereas with the let form, the expression isn’t evaluated immediately:
(from here)
But I can do this in GHCI:
λ: x <- return $ error ":("
λ: :sprint x
x = _
This seems to show that the monadic bind is not strict. What am I missing?
Remember that a function being strict means f ⊥ = ⊥
. Consider:
ghci> x <- return undefined
-- no error
This means that return undefined >>= \x -> ...
is not ⊥, but that doesn't really say anything about the strictness of >>=
, because of the return
. This, however:
ghci> y <- undefined
*** Exception: Prelude.undefined
is the case that the manual is referring to, and it shows that bind is strict in the left argument, because undefined >>= (\y -> ...)
is ⊥. Finally,
ghci> :set -XBangPatterns
ghci> !z <- return undefined
*** Exception: Prelude.undefined
This line shows what happens if we give it a strict function as an argument, so we know that return undefined >>= f
is ⊥ if f
is strict. This actually follows from the monad law return x >>= f = f x
, so return ⊥ >>= f = f ⊥ = ⊥
In Haskell, we separate evaluation of values from execution of computations. return (error "")
is a computation that succeeds returning an undefined value, the value is not evaluated when bound. error "" :: IO a
is an undefined computation, that fails immediately.
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