[Haskell-cafe] Applicative do?

Philippa Cowderoy flippa at flippac.org
Fri Oct 9 13:06:04 EDT 2009

I do a lot of work with parsers, and want to do more using Applicatives. 
That said, I'm finding it a little tedious being forced to use pointless 
style for a task that's well-suited to having a few names around. The 
idea of an applicative do notation's been kicked around on #haskell a 
few times (I can't find any trace of it on the mailing list, but I 
confess to not having searched too hard), so I thought I'd propose it here.

The basic idea is to turn this:

do a <- f
   b <- h
   pure $ foo a b

into this:

(\a b -> pure $ foo a b) <*> (f <*> g *> h)

Aside from changing >>= and >> into <*> and *>, the most significant 
difference from monadic do is that all the generated lambda abstractions 
go in front of the final "return" statement which is then fmapped across 
the rest of the code. Bindings are thus only in scope in the "return" 
statement. I believe sugared let statements can be handled similarly so 
long as they respect the binding discipline.

This leads us to the bikeshed topic: what's the concrete syntax? The 
obvious way is to replace do with a new keyword - for example, ado for 
"applicative do". There's a nice alternative though: we can check 
whether a do statement meets the binding rules for an applicative block 
and treat it as one if so, or a monadic one if not. While not all Monads 
are Applicatives, code can readily be changed back using the 
WrappedMonad newtype - whereas existing code needn't turn on the 
appropriate extension in the first place.

Thoughts, comments?

flippa at flippac.org

More information about the Haskell-Cafe mailing list