Haskell pattern matching too strict?
Malcolm.Wallace at cs.york.ac.uk
Tue Jan 9 09:34:11 EST 2001
> -- broken fragment
> instance (Typeable a, Typeable b) => Typeable (a,b) where
> typeOf (x,y) = "("++(typeOf x)++ ","++(typeOf y)++")"
> Is this too strict? It never uses the tuple or its arguments yet
> tries to construct the tuple anyway.
Yes, this is too strict, but no, Haskell is correctly doing what you
asked for here. When you write
f (x,y) = ...
the pattern must be matched before the system can decide which clause
of the function definition to commit to. Hence, it must evaluate
the tuple as far as the (,) constructor, to be sure that it actually
If you really don't want to construct the tuple at all, then you
mustn't match on it strictly. There are many ways to make the
match non-strict - in all cases, you must defer the pattern-match
to the rhs of the equation, i.e. after the system has determined
which equation clause to use.
f ~(x,y) = ...
f xy = ... where (x,y) = xy
f xy = let (x,y) = xy in ...
By a similar trick, you can improve this:
> instance Typeable a => Typeable [a] where
> typeOf x = "["++(typeOf (see x))++"]"
> see :: [a] -> a
> see = undefined
to be simpler:
instance Typeable a => Typeable [a] where
typeOf xs = "["++(typeOf x)++"]"
where (x:_) = xs
More information about the Glasgow-haskell-bugs