[Haskell-beginners] Re: Non-recursive binding expression

Will Ness will_n48 at yahoo.com
Sun Mar 1 04:33:39 EST 2009

Brent Yorgey <byorgey <at> seas.upenn.edu> writes:

> On Sat, Feb 28, 2009 at 10:31:37PM +0000, Will Ness wrote:
> > 
> > That's what I understood the OP wanted - Scheme's LET, not LETREC, allowing 
> > shadowing. I was suprised let-statement in do chain didn't work that way. I 
> > expected it to be equivalent to a kind of code above, since each new line 
in do 
> > block represents a nested function in explicit bind notation, and nested 
> > function binding definitely provides for non-recursive let kind of argument 
> > binding, with shadowing. 
> > 
> No, the point of let expressions in do-blocks is to have a convenient
> way to make pure bindings, i.e. ones that aren't piped through >>= .
> Note that let statements in do-blocks just get desugared into normal
> let expressions:
>   do { let x = y ; stuff }
>     desugars into
>   let x = y in do { stuff }
> Haskell simply doesn't have anything equivalent to Scheme's LET,
> except for actual nested functions.
> -Brent

Shadowing has its legitimate uses, for example when some value is refined while 
being propagated through a chain of action-functions, there is no reason for 
action-functions further down in the chain to have access to its previous, 
outdated version.

Consider generating (i,j,k) triples representing Hamming numbers in some range, 
along with their logarithm value, q = i*log 2 + j*log 3 + k*log 5, which gets 
partially built as new indices get generated:

  do k <- [0..kmax]
     q <- [ k*log 5 ]
     j <- [0..jmax]
     q <- [ q + j*log 3]
     i <- [0..imax]
     q <- [ q + i*log 2]
     return ((i,j,k),q)

Why not have some syntactic adornement in place of ugly-looking singleton 
generators? Calling it LET got it confused with the regular LET; calling it SET 
doesn't have to confuse anyone to believe it's destructive (it's not).

But if it's a syntactic re-write it ought to follow the semantics of the 
original construct.

The possibility of having shadowing definitions got eliminated here with this 
LET rewrite. It's not right.

After all, if we really had to have some recursive definition, we could always 
use the regular let expression, like

  do a <- as
     set q = let zs=0:zs in zs
     b <- bs

could we?


More information about the Beginners mailing list