Questa è una buona (e abbastanza semplice) applicazione per il tipo di tecniche di programmazione generici esemplificato in shapeless.
Data la tua definizione,
object CombinatorParser extends RegexParsers {
lazy val a = "a"
lazy val b = "b"
lazy val c = "c"
lazy val content = a ~ b ~ c
}
Possiamo ricorsivamente definire una classe tipo che appiattirlo di risultati come segue,
import CombinatorParser._
In primo luogo definiamo un tratto che (astrattamente) appiattisce delle partite arbitraria M
ad un List[String]
,
trait Flatten[M] extends (M => List[String]) {
def apply(m : M) : List[String]
}
T gallina forniamo istanze di classe tipo per tutte le forme di M
che siamo interessati a: in questo caso, String
, A ~ B
e ParseResult[T]
(dove A
, B
e T
sono tutti i tipi per i quali non sono Flatten
casi),
// Flatten instance for String
implicit def flattenString = new Flatten[String] {
def apply(m : String) = List(m)
}
// Flatten instance for `A ~ B`. Requires Flatten instances for `A` and `B`.
implicit def flattenPattern[A, B]
(implicit flattenA : Flatten[A], flattenB : Flatten[B]) =
new Flatten[A ~ B] {
def apply(m : A ~ B) = m match {
case a ~ b => flattenA(a) ::: flattenB(b)
}
}
// Flatten instance for ParseResult[T]. Requires a Flatten instance for T.
implicit def flattenParseResult[T]
(implicit flattenT : Flatten[T]) = new Flatten[ParseResult[T]] {
def apply(p : ParseResult[T]) = (p map flattenT) getOrElse Nil
}
Finalmente possiamo definire una funzione convenienza per semplificare l'applicazione Flatten
casi per analizzare i risultati,
def flatten[P](p : P)(implicit flatten : Flatten[P]) = flatten(p)
e ora siamo pronti a partire,
val testChar = "abc"
val output = parseAll(content, testChar)
println(output) // ((a~b)~c) but I want List(a, b, c)
val flattenedOutput = flatten(output)
println(flattenedOutput) // List(a, b, c)
non credo che sia possibile. Non puoi dividere le tue catene in pezzi più piccoli? Cosa stai cercando di fare esattamente? Forse se dai un po 'più di contesto qualcuno ha una soluzione migliore per questo. – drexin