(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.