
The point of where is that it scopes over guards and multiple equations as well as right hand sides. f x | xsquared < 1000 = xsquared | otherwise = 0 where xsquared = x*x For the same reason, it has to be restricted to appear at the "top level" of a right hand side. Of course, we also need a construct to bind local variables inside an expression -- hence let, which therefore cannot scope over guards. Two kinds of scope, two binding constructions. We could have got away with one, if we had thrown out guards and relied just on if-then-else to test conditions instead. But guards are very expressive: some programs would have been a lot harder to write without them. Typical examples are when we just want to pick out one case in the first equation of a function, before lots of pattern matching: f x y | simplecase x y = simpleanswer f p1 p2 = ... f p3 p4 = ... ... There's no neat way to write this with if-then-else: you need to split f into two functions f x y = if simplecase x y then simpleanswer else f' x y f' p1 p2 = ... ... That's the reason Haskell has two binding constructions. John Hughes