-
Notifications
You must be signed in to change notification settings - Fork 4
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Support extending the AST for database specific query support, without losing sealed trait benefits. #40
Comments
I'm thinking that this can be done by adding in a "hole". So, given this "base" ADT: sealed trait ArithmeticOperationsADT[+A,+B]
case class Lit[+A](value: A) extends ArithmeticOperationsADT[A, Nothing]
case class Add[+A, +B](left: ArithmeticOperationsADT[A, B], right: ArithmeticOperationsADT[A, B]) extends ArithmeticOperationsADT[A, B]
case class Sub[+A, +B](left: ArithmeticOperationsADT[A, B], right: ArithmeticOperationsADT[A, B]) extends ArithmeticOperationsADT[A, B]
case class Div[+A, +B](left: ArithmeticOperationsADT[A, B], right: ArithmeticOperationsADT[A, B]) extends ArithmeticOperationsADT[A, B]
case class Mul[+A, +B](left: ArithmeticOperationsADT[A, B], right: ArithmeticOperationsADT[A, B]) extends ArithmeticOperationsADT[A, B]
case class ArithmeticOperationsADTExtensions[+B](b: B) extends ArithmeticOperationsADT[Nothing, B] We can extend ArithmeticOperationsADT (which currently only supports arithmetic) to support more arithmetic operations like this: sealed trait MoreOperationsADT[+A]
case class Pow[A](base: ArithmeticAndMoreADT[A], exponent: ArithmeticAndMoreADT[A]) extends MoreOperationsADT[A]
case class Root[A](base: ArithmeticAndMoreADT[A], nthRoot: ArithmeticAndMoreADT[A]) extends MoreOperationsADT[A]
type ArithmeticAndMoreADT[+A] = ArithmeticOperationsADT[A, MoreOperationsADT[A]] Then, usage/construction of these ADTs might looks like Add(Lit(5), Sub(Lit(6), ArithmeticOperationsADTExtensions(Pow(Lit(5),Lit(2))))) Which would represent
This scastie is an example of what a practical usage might be... This would obviously be much more complex in the context of scoobie. This idea could be expanded further to support Coproduct extensions, which would allow extending a single ADT with multiple ADTs. |
The above apporoach works fine for a simple ADT, not so much for an entire AST. |
@edmundnoble, @bshelden, and @sellout helped me realize that I have a mutually recursive AST. The solution to mutually recursive ASTs in general is to have something like below: trait AST[A[_], I] // A represents additional AST nodes, and I is an Indexer which represents the type of node.
object Indicies {
trait FooAST
trait BarAST
}
case class FooAST[A[_]](subNode: A[Indicies.BarAST]) extends AST[A, Indicies.FooAST]
case class FooLeaf[A[_]](foo: Int) extends AST[A, Indicies.FooAST]
case class BarAST[A[_]](subNode: A[Indicies.FooAST]) extends AST[A, Indicies.BarAST] In the end, you wind up employing the use of case class FixH[F[_[_], _], A](unfix: F[HFix[F, ?], A])
Unfortunately, whenever you try to create an Once the new versions of Scala are out, the way this will wind up looking in Scoobie is something like trait Query[T, A[_], I] // T represents the type on query parameters. In the context of a doobie query, this will be [[doobie.imports.Fragment]]
object Indicies {
trait Value
trait Comparison
} where all nodes extend Once all this is done, extending the AST should be as simple as using a Right now, that branch has it's own implementations of The above is just my understanding of the issue currently. Things up there might be wrong, and the approach to solving this in the end might change. |
Making lots of progress on this. Got the DSL functioning with the new |
The dotty branch has everything necessary to implement this. Once https://github.com/scala/scala#5744 gets a resolution, I'll update the scala branch to reflect that. Until then, dotty is where the most up to date stuff is. It all works, besides some dotty instability. |
In lieu of a solution to https://github.com/scala/scala#5744, I'm going to implement this using plain 'ol recursive datastructures. The result will be an extensible AST, but users will be able to generate invalid trees. In the end, I think this is worth it, since the AST should be built by a DSL anyway. |
No description provided.
The text was updated successfully, but these errors were encountered: