411 REFERENCE · Wikibooks
Haskell/Solutions/Laziness
Reference material by Wikibooks contributors. This retains its source identity and is not 411 news reporting.
Why must we fully evaluate x to normal form in f x y = show x?
Which is the stricter function?
f x = length [head x]
g x = length (tail x)
Because show x needs to evaluate x to convert it to a String.
g is stricter: it must walk through the whole list to discover its length, even if it does not need to examine the single values.
Instead, to evaluate length [head x], when length evaluates the passed list it obtains thunk_0:[], where thunk_0 represents the result of head x.
Thus, you can verify that f undefined => 1 (actually, f is equivalent to const 1) while g undefined fails.
Also note that, if ls is a valid Int list (which does not contain undefined among its elements), all following expressions fail to evaluate:
g (1:undefined) => length undefined => undefined
whereas the following evaluate successfully:
g (1:undefined:ls) => length (undefined:ls) => 1 + length ls
g (undefined:ls) => length ls
The difference between g (1:undefined) and g (1:undefined:ls)may appear confusing, but is correct, because in the first case undefined replaces a list (in particular, the tail of the cons cell passed to g), while in the second case undefined replaces a list value (which is not needed).