We can associate a notion of nesting with Haskell expressions. For instance, if we have something like f (g x), then the expression (g x) is nested deeper than the expression f. Thus it makes sense to talk of outer and inner expressions as candidates for reduction.
Two canonical reduction strategies are
The first reduction of square (4+3) above was computed eagerly, while the second and third were lazy. Haskell follows the strategy of outermost, or lazy, reduction, while ML follows the strategy of innermost, or eager, reduction.
Here is another example:
power :: Float -> Int -> Float power x n | (n==0) = 1 | otherwise = x * (power x (n-1))
Consider what happens when we evaluate power (7.0/0) 0.
With outermost reduction, we first try to reduce power. The first rule applies and we get power (7.0/0) 0 1. On the other hand, innermost reduction will try to evaluate (7.0/0) and generate an error.
Thus, the two reduction strategies are not always equivalent. We have the following general result.