What it says is that the order of statements doesn't influence the evaluation criteria. As @chi points out in IO monad effects are sequenced in order but their evaluation order is still not known. An example of a monad which will make the concept clear:
test = do
x <- Just (2 + undefined)
y <- Nothing
return (x + y)
In ghci:
λ> test
Nothing
The above code has three statements. It can be de-sugared into the following form:
Just (2 + undefined) >>= \x -> Nothing >>= \y -> return (x + y)
Now since (>>=)
is left associative, it will be evaluated like this:
(Just (2 + undefined) >>= \x -> Nothing) >>= \y -> return (x + y)
Note that Maybe
monad is defined like this:
(>>=) :: Maybe a -> (a -> Maybe b) -> Maybe b
Nothing >>= _ = Nothing -- A failed computation returns Nothing
(Just x) >>= f = f x -- Applies function f to value x
Applying the value (2 + undefined)
to the function \x -> Nothing
will result in Nothing
.
The expression 2 + undefined
is unevaluated, thanks to lazy evaluation strategy followed by Haskell.
Now we have a reduced form:
Nothing >>= \y -> return (2 + undefined + y)
Looking at the Monad
instance for it, you can see that this will produce Nothing
because Nothing >>= _ = Nothing
.
What if the argument was strict instead:
test = do
!x <- Just (2 + undefined)
y <- Nothing
return (y + x)
Demo in ghci
:
λ> test
*** Exception: Prelude.undefined
If we follows strict evaluation procedure, then you can see that order actually matters. But in a lazy setting, the order of statements doesn't matter. And hence the wiki claims, "the order of statements is not the criterion for the evaluation order".