[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