robey/packrattle — pull request #3 by hallettj (2013-05-26 22:09:30+00:00)
Title: Extends onMatch to behave as a monad transform

With this change onMatch checks the return type of its callback and acts
as a monad transform (like flatMap) if the returned value is another
parser. Otherwise onMatch acts as a functor transform as before.

Also adds a succeed() function that produces a parser that always
matches and that consumes no input. This pairs with the monad behavior
of onMatch.

I am liking packrattle. The provided helpers and the facility to lazily evaluate parsers are both very helpful. In my view a monad transform is a necessary feature for a parser combinator library. It allows for examples like this:

evens = $.regex(/\d+/).onMatch (s) ->
n = parseInt(s, 10)
if n % 2 != 0
$.reject.onFail("only even numbers please")
else
n

I know that I could do this job with the ifMatch method. But with the monad behavior I can be more specific about conditions in which an error message appears. In this example if the regex fails the appropriate message is preserved. The even numbers message only results if the regex succeeds but the even check fails.

In fact a monad provides a general control flow mechanism. For example:

numbers = $.regex(/\d+/).onMatch (s) ->
n = parseInt(s, 10)
if n % 2 == 0
$.string(' is even')
else
$.string('is odd')