Let in do-expressions

Johan Nordlander nordland@cse.ogi.edu
Fri, 16 Feb 2001 14:42:32 -0800


Martin Erwig wrote:
> 
> Hi there,
> 
> I am trying to use the "let"-notation within do-expressions,
> and it seems to me that it does not work correctly. (I am using
> Hugs, version February 2000, on Solaris.)
> 
> E.g.,
> 
>   do {x <- [1..9]; let i=1 in do {return ((+i) x)}}
> 
> works as expected, but with
> 
>   do {x <- [1..9]; let i=1; return ((+i) x)}
> 
> I get:
> 
>   ERROR: Syntax error in definition (unexpected symbol "i")
> 
> According to the Report (Section 3.14) the latter expression
> should be a valid abbreviation of the former, or am I missing
> something here? If it is a bug, has it been corrected in the
> new version of Hugs?

No, it's not a bug, but an unfortunate consequence of the current
definition of the layout rule.  What you've written will be parsed as

   do {x <- [1..9]; let {i=1; return ((+i) x)}}

which is clearly incorrect (although the error message isn't very 
helpful).

What you probably intended was

   do {x <- [1..9]; let {i=1}; return ((+i) x)}

but the layout rule isn't advanced enough to figure this out.  The
exact reason is that only one look-ahead is used to determine if
a closing brace should be inserted, but since 'return' is a valid
prefix of a let-definition, the parser has already committed to
parsing more let-bindings when the error is detected.

Note especially that

   do {x <- [1..9]; let i=1; in return ((+i) x)}

parses ok.

The problem with this part of the layout rule was discussed on the
haskell list not long ago, see

   http://www.mail-archive.com/haskell@haskell.org/msg08099.html

-- Johan