Detail: laziness in show
Fergus Henderson
fjh@cs.mu.oz.au
Sat, 10 Feb 2001 17:19:29 +1100
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.