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.