Parsing permutations again

(This is the last of these, I promise.)

In my last post, I described a direct translation of Parsec's permutation parser combinators into Scala. I described one major problem with that approach: the need to provide a fully curried handler function. I suggested that a fix might be possible, and indeed it is. I've produced a new version of these combinators that does not require such a function.

As suggested in my last post, we can simply write:

def phrase = '(' ~> permute('a' ~~ 'b' ~~ 'c') <~ ')'

or

def countThrees =
  '(' ~> permute(ones ~~ twos ~~ threes) <~ ')' ^^
    { case _ ~ _ ~ ts => ts.length }

This matches precisely how Scala handles regular sequences:

def countThrees =
  '(' ~> (ones ~ twos ~ threes) <~ ')' ^^
    { case _ ~ _ ~ ts => ts.length }

This is a very happy outcome! As additional benefits, the new version relies less on implicit conversions, and the code is a bit clearer. Take a look at the full implementation.

Future work includes improving the efficiency of these combinators and adding goodies like separators and optional elements. However, I don't plan to spend any more time on this, so it'll have to wait.