parserz
parserz copied to clipboard
Explore removing nested tuples and eithers
Given we have the following combinators
def ~ [SI1 <: SI, SO1 >: SO, E1 >: E, B](that: Grammar[SI1, SO1, E1, B]): Grammar[SI1, SO1, E1, A /\ B]
def | [SI1 <: SI, SO1 >: SO, E1 >: E, B](that: Grammar[SI1, SO1, E1, B]): Grammar[SI1, SO1, E1, A \/ B]
that produce nested structures when chained, e.g.
val g1: Grammar[SI1, SO1, E, ((A, B), C)] = a ~ b ~ c
Explore the concept of building a parser/printer that skips creation of nested structures when executed.
Idea is to use a witness type with 2 parameters
type G[_, _]
where 1st is a phantom type to capture what is produced by using parser combinators and 2nd is some representation of the 1st.
For example
sealed trait Equiv[A, Repr]
object Equiv {
def caseClass1[Z, A](f: A => Z, g: Z => Option[A]): Equiv[A, Z] = ???
def caseClass2[Z, A, B](f: (A, B) => Z, g: Z => Option[(A, B)]): Equiv[(A, B), Z] = ???
def caseClass3[Z, A, B, C](f: (A, B, C) => Z, g: Z => Option[(A, B, C)]): Equiv[((A, B), C), Z] = ???
}
This way a
final case class Person(name: String, age: Int, address: String)
can be isomorphic to
((String, Int), String)
via means of Equiv
.
def to[Z](implicit equiv: Equiv[A, Z]): Grammar[SI, SO, E, Z]
can be used to describe an intent for isomorphic transformation. Existing program in terms of grammars should be kept to be further optimized into an efficient code that is not doing extra allocations.