> > let x = 12
> > let x = (<- x)
> Okay, so the desugaring process wouldn't terminate in that case! One
> could either: (a) try to retain the equivalence in theory, but make it
> illegal to use x in a monadic subexpression when defining x; (b) we
> could abandon my claim that they are equivalent.
This example isn't intended to be about termination of the desugaring,
or about types etc - the only point is to note the change in the
lexical scoping rules that (<-) gives. I'll try and state my concern
let x = a
In this expression, x is available for use within a, since let is
recursive. This allows us to write:
let xs = "paws" : xs
With the end result that xs is bound to ["paws","paws","paws","paws"...
let x = (<- a)
With the proposed desugaring we obtain:
temp <- a
let x = temp
Now x is NOT in scope within the expression a! We have changed the
static lexical scoping, and only within the brackets. This behaviour
is (in my opinion) horrid. A quick poll of people in my office lead us
all to believe that this issue means you should not be allowed (<-)
within a do's let statement.
This leads us to a second problem, floating these monadic expressions
outside any binding:
do case x of
 -> return 1
(y:ys) -> f (<- g y)
Here, the proposed desugaring does not work, since y is not in scope
where we move the element to.
Perhaps this leads to the conclusion that monadic subexpressions
should not be allowed inside any binding group, including let, case or
Haskell-Cafe mailing list