"where" block local to a guard?

Brian Boutel brian@boutel.co.nz
Tue, 17 Sep 2002 21:37:54 +1200


Dr Mark H Phillips wrote:
> Hi,
> 
> Suppose you have some function
> 
> functn :: Int -> Int
> functn i
>     | i>5       = t  * i
>     | i>0       = t_ * i
>     | otherwise = 1
>     where
>     t  = functn (i-2)
>     t_ = functn (i-1)
> 
> Notice that t and t_ are really local to a guard, rather
> than to the whole guard section.  Why then, can't you write:
> 
> functn :: Int -> Int
> functn i
>     | i>5       = t * i
>         where
>         t = functn (i-2)
>     | i>0       = t * i
>         where
> 	t = functn (i-1)
>     | otherwise = 1
> 
> In particular, the above would mean you wouldn't need two names 
> t and t_, you could just use t for both!
> 
> Am I doing something wrongly, or is there a good reason why
> where isn't allowed to be used in this way?
>

You can't do this because where clauses are not part of the expression 
syntax. If they were, expressions like

	let a=b in c where d=e
or
	if a then b else c where d=e

whould be ambiguous, unless you adopt arbitrary rules about the 
prededences, and such arbitrary rules are considered a bad thing.

Very early on in the design of Haskell, the issue of how to deal with 
the two alternative styles for local definitions (let and where) was 
resolved by only allowing let in the expression syntax, but allowing 
where as part of the equation syntax. The nice thing about this is that, 
apart from removing ambiguities in expressions, where syntax provides a 
way of writing definitions which span several guarded right-hand-sides, 
and in the simple case of a single rhs, looks just like a where 
expression, so allows people to write effectively in that style.

--brian

-- 
Brian Boutel
Wellington New Zealand