Search code examples
haskellghci

Is GHCI monadic bind strict?


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?


Solution

  • 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 ⊥ = ⊥