"where" block local to a guard?

Hamilton Richards ham@cs.utexas.edu
Tue, 17 Sep 2002 10:56:54 -0500


At 3:07 PM +0930 9/17/02, Dr Mark H Phillips wrote:
>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 get the effect you're after by using let-expressions:

>  functn :: Int -> Int
>  functn i
>      | i>5       = let t = functn (i-2) in t * i
>      | i>0       = let t = functn (i-1) in t * i
>      | otherwise = 1

'where' is part of the syntax of definitions, not expressions. This 
enables a name defined in a where-clause to be used in more than one 
guarded expression.

--Ham
-- 
------------------------------------------------------------------
Hamilton Richards                Department of Computer Sciences
Senior Lecturer                  The University of Texas at Austin
512-471-9525                     1 University Station C0500
Taylor Hall 5.138                Austin, Texas 78712-1188
ham@cs.utexas.edu                hrichrds@swbell.net
------------------------------------------------------------------