[Haskell] Mixing monadic and non-monadic functions

Ben Rudiak-Gould Benjamin.Rudiak-Gould at cl.cam.ac.uk
Sat Sep 17 13:56:36 EDT 2005

Frederik Eaton wrote:
> I think this is a good idea. I like the inline "<-", or maybe
> something like "@".

The operator-section notation (<- expr) has the big advantage of being 
unlikely to collide with any other syntax proposals.

> I'm not sure what you intend to do about nested "do" statements,
> though. If they correspond to different monads, I might want to have a
> 'borrow' in the inner "do" statement create a lifted expression in the
> outer "do" statement.

In such cases you almost certainly wouldn't want to use this notation 
anyway. It's confusing enough with a single monad.

As an experiment I tried rewriting some monadic code from one of my projects 
(Reform) using the (<- expr) syntax. It was interesting. Some points:

   * Most of my uses of <- could be replaced with the inline form. In
     some cases it seemed like a bad idea, because the intermediate
     variable name was useful as documentation. In the other cases I'd
     obviously chosen a meaningless intermediate variable name just to
     get around the lack of a feature like this one.

   * I found myself writing "do return" a lot, which isn't a combination
     you usually see in Haskell code. It felt odd, but perhaps you'd get
     used to it.

   * The new syntax is really nice as a replacement for the annoyingly
     common "x <- foo ; case x of..." idiom that I've always disliked.

   * The increased similarity to programming in an eager language was
     startling at times. I'm just not used to thinking eagerly when I
     write Haskell, even though I do it all the time in other languages.

   * There are tricky corner cases. For example,

       x <- getByte
       if x < 128
         then return x
         else return (x - 128) * 256 + (<- getByte)

     doesn't do what it's probably intended to do: the second byte will
     be read even if x < 128. You have to write "else do return"
     instead of "else return". I'm afraid this would be easy to get
     wrong. It wouldn't be hard to make the translation assume an
     implicit do at the branches of if and case statements, but this
     wouldn't always be what you'd want. Even worse is that short-
     circuiting && and || don't work as they do in eager languages.

So on reflection I'm not sure I think this proposal is a good idea. I 
probably wouldn't be able to write or read code in this style without doing 
manual desugaring in my head, which takes away much of the appeal. But it 
might be worth adding if people can be trusted to use it judiciously.

-- Ben

More information about the Haskell mailing list