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
  g
  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?

--
fli...@flippac.org
_______________________________________________
Haskell-Cafe mailing list
Haskell-Cafe@haskell.org
http://www.haskell.org/mailman/listinfo/haskell-cafe

Reply via email to