Malcolm Wallace writes:
Quick quiz: without running this through a compiler, who can spot the mistake? :-)
module Main where import Char f x = y where y | isSpace x = True y | otherwise = False -- ** The problem line? main = print (f 'x')
Without running this through the compiler, but based on similar problems I've had recently, I'd assume the problem is the marked line. Two outer-level patterns are each presented with guards. This would be correct for a function definition:
f x = y () where y _ | isSpace x = True y _ | otherwise = False -- ** Does this work?
This is a tricky issue. I'd like the original program to be all right. We end up sowing confusion with erroneous programs like this one:
f x = y where y | otherwise = False -- ** Now this pattern overlaps! y | isSpace x = True
But of course an analogous problem occurs in the function definition, and I think can be caught by turning on warnings in ghc. -Jan-Willem Maessen jmaessen@mit.edu
f x = y where y | isSpace x = True y | otherwise = False -- ** The problem line?
Correct. Here y is a pattern binding, and multiple pattern bindings of the same variable are not permitted.
f x = y () where y _ | isSpace x = True y _ | otherwise = False -- ** Does this work?
Correct. Here y is a function binding instead, and multiple clauses *are* permitted.
I'd like the original program to be all right.
Me too. I wrote 'y' as a 0-arity function, knowing that because it used a free variable bound at an outer scope, it would probably be lambda-lifted to a greater arity by the compiler. But only one compiler saw it in the same way as I did. :-) Of course, if the pattern binding is more complex than a single variable name, I still want the no-multiple-bindings rule to apply as usual:
f x = y () where (y:_) | isSpace x = [True] (y:_) | otherwise = [False] -- ** Definitely wrong
and indeed all compilers reject this, as they should. Regards, Malcolm
participants (2)
-
Jan-Willem Maessen -
Malcolm Wallace