On 09-Feb-2001, Patrik Jansson <patrikj@cs.chalmers.se> wrote:
I just uncountered an interesting example of (hidden) laziness - here is a very short session with hugs (February 2000):
Prelude> undefined :: String " Program error: {undefined}
Note the starting double quote on the line before the error! In a more complicated context this puzzled me for a while until I realized that there is an implicit application of show that produces the quote. The show instance for strings prints a '"' character before it starts evaluating the argument. (With the setting -u for hugs, nothing is printed.)
So, what about other types?
I spent a few minutes a couple of colleagues yesterday puzzling over a similar example. The example was something like this: instance Show (a -> b) where showsPrec _ _ = showString "<function>" f :: Int -> Int -> Int f = error "f is undefined" Hugs> f 3 The expected output was "Program error: f is undefined", since the expression `f 3' should evaluate to `error "..."', but the actual output was "<function>". This puzzled us for quite a while, until we realized that Hugs was only evaluating the expression `show (f 3)', rather than evaluating `f 3', and our instance of `show' for functions was lazy. Fortunately we had defined the instance for functions explicitly, rather than using `import ShowFunctions', otherwise it might have taken much longer to figure out what was going on. But I wondered afterwards whether it might be better for Hugs to use x `seq` show x rather than show x when evaluating expressions at the Hugs command-line (with the default +u option). -- Fergus Henderson <fjh@cs.mu.oz.au> | "I have always known that the pursuit | of excellence is a lethal habit" WWW: <http://www.cs.mu.oz.au/~fjh> | -- the last words of T. S. Garp.