[Haskell-cafe] let vs do?

Thomas Schilling nominolo at googlemail.com
Fri Jun 29 13:26:26 EDT 2007

On 29 jun 2007, at 16.26, Dave Bayer wrote:
>>> That way you would have to use monads everywhere.
>> As you already hinted at in a later message, this has to do with  
>> let-bindings being potentially polymorphic and monadic bindings  
>> being necessarily monomorphic:
> Are there papers that prove this need be the case in any language,  
> or are we simply now trapped into this for the moment by some  
> design choices?

The big design choice is to have non-strict evaluation semantics.   
Monads re-sequence instructions for cases where you need it.  Recall  
that in Haskell

   let x = foo bar baz
       y = error "Gotcha."
   in (x, y)

isn't equivalent to

   (let ((x (foo bar baz))
         (y (error "Gotcha.")))
      (values x y)

because Lisp is strict.  In Lisp this would result in an error, even  
if y is never used, in Haskell only once y is actually used.

To simulate this in Haskell you'd have to write:

   do x <- foo bar baz
      y <- error "baz"
      return (x, y)

and choose the monad according to your semantics.

I take it, your claim now is that by choosing the Identity monad,  
we'd get normal Haskell semantics (modulo polymorphic types?) and  
using any other monad we'd get any other semantics?

Some problems I can see with this is:

   - Monads aren't transparent to the compiler.  The compiler would  
still have to transform it into a pure intermediate form.

   - Most importantly, monads sequence computation.  But I guess you  
can get around it.  After all, you can simulate Haskell in strict  
lisp via:

   (let ((x (delay (foo bar baz)))
         (y (delay (error "Gotcha"))))
      (delay (values x y)))

   - So, I assume the big question is how not to lose type inference,  
and get used to the less pretty syntax ;)

Maybe, others can comment on these issues.

/ Thomas

More information about the Haskell-Cafe mailing list