I wrote some parser from combinatory library. I want a generic function that transform any size of nest ~ into a list. How to do this ?
Here is my example of parser I use (my real parser has a very long chain ~ so I want to avoid my current solution which is in comment below).
object CombinatorParser extends RegexParsers {
lazy val a = "a"
lazy val b = "b"
lazy val c = "c"
lazy val content = a ~ b ~ c // ^^ {case a~b => a::b::c::Nil work but I want something more general that work for any ~ length.
}
object CombinatorTesting {
def main(args:Array[String]) {
val testChar = "abc"
val output = CombinatorParser.parseAll(CombinatorParser.content, testChar)
println(output) // ((a~b)~c) but I want List(a,b,c)
}
}
This is a good (and fairly simple) application for the kind of generic programming techniques exemplified in shapeless.
Given your definition,
We can recursively define a type class that will flatten it’s results as follows,
First we define a trait which (abstractly) flattens an arbitrary match
Mto aList[String],Then we provide type class instances for all the shapes of
Mthat we’re interested in: in this case,String,A ~ BandParseResult[T](whereA,BandTare all types for which there areFlatteninstances),Finally we can define a convenience function to simplify applying
Flatteninstances to parse results,And now we’re ready to go,