Skip to content

Commit

Permalink
test setup
Browse files Browse the repository at this point in the history
  • Loading branch information
ValdemarGr committed Feb 18, 2024
1 parent b15a558 commit c5be2a2
Show file tree
Hide file tree
Showing 5 changed files with 156 additions and 368 deletions.
6 changes: 6 additions & 0 deletions build.sbt
Original file line number Diff line number Diff line change
Expand Up @@ -139,6 +139,12 @@ lazy val core = project
.settings(sharedSettings)
.settings(name := "gql-core")
.dependsOn(parser)

lazy val monadicArrow = project
.in(file("modules/monadic-arrow"))
.settings(sharedSettings)
.settings(name := "gql-monadic-arrow")
.dependsOn(core)

lazy val server = project
.in(file("modules/server"))
Expand Down
369 changes: 1 addition & 368 deletions modules/core/src/main/scala/gql/Modifier.scala
Original file line number Diff line number Diff line change
Expand Up @@ -16,7 +16,6 @@
package gql

import gql.ast._
import gql.resolver.Resolver

sealed trait Modifier
object Modifier {
Expand Down Expand Up @@ -163,370 +162,4 @@ object InverseModifierStack {
}
case Nil => ms.inner
}
}

import cats.implicits._
import cats.free._
import cats.arrow._
import cats._
import cats.data._
import org.tpolecat.sourcepos._

object Attempt3 {
final case class FetchVar[A](
id: Int,
pos: Option[SourcePos],
compilerPos: SourcePos
)
type Var[A] = FreeApplicative[FetchVar, A]

class Language[Arrow0[_, _]] {
sealed trait Declaration[A]
object Declaration {
case class Declare[A, B](v: Var[A], arrow: Arrow0[A, B], pos: SourcePos) extends Declaration[Var[B]]
}

final type Decl[A] = Free[Declaration, A]

def declare[A, B](v: Var[A])(f: Arrow0[A, B])(implicit sp: SourcePos): Decl[Var[B]] =
Free.liftF[Declaration, Var[B]](Declaration.Declare(v, f, sp))

def compileFull[A, B](f: Var[A] => Decl[Var[B]])(implicit arrow: Arrow[Arrow0], sp: SourcePos): Arrow0[A, B] = {
val init = FreeApplicative.lift(FetchVar[A](0, None, sp))
val program = f(init)
type U = Vector[Any]
type S = (Int, Arrow0[U, U])
type G[C] = State[S, C]

val nextId: G[Int] = State[S, Int] { case (x, u) => ((x + 1, u), x) }

def varCompiler(x: U) = new (FetchVar ~> Id) {
def apply[A0](fa: FetchVar[A0]): Id[A0] =
if (fa.compilerPos eq sp) x(fa.id).asInstanceOf[A0]
else {
val msg = fa.pos match {
case None =>
s"""|Initial variable introduced at ${fa.compilerPos}.
|Variables that were not declared in this scope may not be referenced.
|Example:
|```
|compile[Int]{ init =>
| for {
| y <- init.apply(_.andThen(compile[Int]{ _ =>
| // referencing 'init' here is an error
| init.apply(_.map(_ + 1))
| }))
| } yield y
|}
|```""".stripMargin
case Some(p) =>
s"""|Variable declared at ${p}.
|Compilation initiated at ${fa.compilerPos}.
|Variables that were not declared in this scope may not be referenced.
|Example:
|```
|compile[Int]{ init =>
| for {
| x <- init.apply(_.map(_ + 1))
| y <- init.apply(_.andThen(compile[Int]{ _ =>
| // referencing 'x' here is an error
| x.apply(_.map(_ + 1))
| }))
| } yield y
|}
|```""".stripMargin
}
throw new RuntimeException(
s"""|Variable closure error.
|$msg""".stripMargin
)
}
}

val arrowCompiler = new (Declaration ~> G) {
def apply[A1](fa: Declaration[A1]): G[A1] = fa match {
case alg: Declaration.Declare[a, b] =>
nextId.flatMap { thisId =>
val fetchVar = FetchVar[b](thisId, alg.pos.some, sp)
val thisArr: Arrow0[U, U] = alg.arrow
.first[U]
.lmap[U](m => (alg.v.foldMap(varCompiler(m)), m))
.rmap { case (b, u) => u.updated(fetchVar.id, b) }

State.modify[S] { case (x, arr) => (x, arr >>> thisArr) }.as(FreeApplicative.lift(fetchVar))
}
}
}

val ((varNum, arrowProgram), lastVar) = program
.foldMap(arrowCompiler)
.run((1, Arrow[Arrow0].lift[U, U](identity)))
.value

val b = Vector.fill[Any](varNum)(null)
arrowProgram
.map(u => lastVar.foldMap(varCompiler(u)))
.lmap[A] { a =>
b.updated(0, a)
}
}
}

abstract class LanguageDsl[Arrow0[_, _]: Arrow] extends Language[Arrow0] { self =>
def liftArrow[A](f: Arrow0[Unit, Unit] => Arrow0[Unit, A])(implicit sp: SourcePos): Decl[Var[A]] =
declare[Unit, A](().pure[Var])(f(Arrow[Arrow0].id[Unit]))

implicit class VarOps[A](v: Var[A]) {
def declare[B](f: Arrow0[A, B])(implicit sp: SourcePos): Decl[Var[B]] = self.declare(v)(f)

def apply[B](f: Arrow0[A, A] => Arrow0[A, B])(implicit sp: SourcePos): Decl[Var[B]] =
declare(f(Arrow[Arrow0].id[A]))
}

final class PartiallyAppliedLanguageCompiler[A](private val dummy: Boolean = true) {
def apply[B](f: Var[A] => Decl[Var[B]])(implicit sp: SourcePos): Arrow0[A, B] = compileFull(f)
}

def compile[A]: PartiallyAppliedLanguageCompiler[A] = new PartiallyAppliedLanguageCompiler[A]
}

object GQLL {
trait ResolverDsl[F[_]] extends LanguageDsl[Resolver[F, *, *]] {
def argument[A](arg: Arg[A])(implicit sp: SourcePos): Decl[Var[A]] =
liftArrow(_.andThen(Resolver.argument[F, Unit, A](arg)))
}
object ResolverDsl {
def apply[F[_]]: ResolverDsl[F] = new ResolverDsl[F] {}
}

import cats.effect._
val d = ResolverDsl[IO]
import d._
import gql.dsl.all._
val res = compile[Int] { init =>
for {
y <- init.apply(_.evalMap(x => IO(x * 2)))
z <- argument(arg[Int]("gab"))
h <- (y, z).tupled.apply(_.map { case (y0, z0) => y0 + z0 })
} yield h
}
}

}
/*
object Attempt2 {
sealed trait ArrowAlg[Arrow0[_, _], A, V[_]]
object ArrowAlg {
case class Declare[Arrow0[_, _], A, B, V[_]](
v: V[A],
arrow: Arrow0[A, B]
) extends ArrowAlg[Arrow0, V[B], V]
}
final type Declaration[Arrow0[_, _], A, V[_]] = Free[ArrowAlg[Arrow0, *, V], A]
trait LangBase {
case class FetchVar[X](id: Int)
final type Var[A] = FreeApplicative[FetchVar, A]
def compile[Arrow0[_, _]: Arrow, A, B](f: Var[A] => Declaration[Arrow0, Var[B], Var]): Arrow0[A, B]
}
object LangBase {
def apply: LangBase = new LangBase {
override def compile[Arrow0[_, _]: Arrow, A, B](
f: Var[A] => Declaration[Arrow0, Var[B], Var]
): Arrow0[A, B] = {
type U = Array[Any]
type S = (Int, Arrow0[U, U])
type G[C] = State[S, C]
type AA[C] = ArrowAlg[Arrow0, C, Var]
def nextId: G[Int] = State[S, Int] { case (x, u) => ((x + 1, u), x) }
val init = FreeApplicative.lift(FetchVar[A](0))
val program = f(init)
def varCompiler(x: U) = new (FetchVar ~> Id) {
def apply[A0](fa: FetchVar[A0]): Id[A0] = x(fa.id).asInstanceOf[A0]
}
val arrowCompiler = new (AA ~> G) {
def apply[A1](fa: AA[A1]): G[A1] = fa match {
case alg: ArrowAlg.Declare[Arrow0, a, b, Var] =>
nextId.flatMap { thisId =>
val fetchVar = FetchVar[b](thisId)
val thisArr: Arrow0[U, U] = alg.arrow
.first[U]
.lmap[U](m => (alg.v.foldMap(varCompiler(m)), m))
.rmap { case (b, u) => u.update(fetchVar.id, b); u }
State.modify[S] { case (x, arr) => (x, arr >>> thisArr) }.as(FreeApplicative.lift(fetchVar))
}
}
}
val ((varNum, arrowProgram), lastVar) = program
.foldMap(arrowCompiler)
.run((1, Arrow[Arrow0].lift[U, U](identity)))
.value
arrowProgram
.map(u => lastVar.foldMap(varCompiler(u)))
.lmap[A] { a =>
val arr = Array.ofDim[Any](varNum)
arr.update(0, a)
arr
}
}
}
}
def declare[Arrow0[_, _], A, B](language: LangBase)(v: language.Var[A])(
arrow: Arrow0[A, B]
): Declaration[Arrow0, language.Var[B], language.Var] =
Free.liftF[ArrowAlg[Arrow0, *, language.Var], language.Var[B]](
ArrowAlg.Declare(v, arrow)
)
trait Lang[Arrow0[_, _], A] {
case class FetchVar[X](id: Int)
sealed trait ArrowAlg[X]
final object ArrowAlg {
case class Declare[Y, X](
v: Var[Y],
arrow: Arrow0[Y, X]
) extends ArrowAlg[Var[X]]
}
type Var[X] = FreeApplicative[FetchVar, X]
final type Declaration[X] = Free[ArrowAlg, X]
def init: Var[A] = FreeApplicative.lift(FetchVar(0))
def compile[B](program: Declaration[Var[B]])(implicit A: Arrow[Arrow0]): Arrow0[A, B]
def declare[B, C](v: Var[B])(f: Arrow0[B, C]): Declaration[Var[C]]
}
object Lang {
def apply[Arrow0[_, _], A]: Lang[Arrow0, A] =
new Lang[Arrow0, A] {
override def init: FreeApplicative[FetchVar, A] = FreeApplicative.lift(FetchVar(0))
override def declare[B, C](v: Var[B])(f: Arrow0[B, C]): Declaration[Var[C]] =
Free.liftF[ArrowAlg, Var[C]](ArrowAlg.Declare(v, f))
override def compile[B](program: Declaration[Var[B]])(implicit A: Arrow[Arrow0]): Arrow0[A, B] = {
type U = Array[Any]
type S = (Int, Arrow0[U, U])
type G[C] = State[S, C]
def nextId: G[Int] = State[S, Int] { case (x, u) => ((x + 1, u), x) }
scala.collection.immutable.HashMap
def varCompiler(x: U) = new (FetchVar ~> Id) {
def apply[A0](fa: FetchVar[A0]): Id[A0] = x(fa.id).asInstanceOf[A0]
}
val arrowCompiler = new (ArrowAlg ~> G) {
def apply[A1](fa: ArrowAlg[A1]): G[A1] = fa match {
case alg: ArrowAlg.Declare[a, b] =>
nextId.flatMap { thisId =>
val fetchVar = FetchVar[b](thisId)
val thisArr: Arrow0[U, U] = alg.arrow
.first[U]
.lmap[U](m => (alg.v.foldMap(varCompiler(m)), m))
.rmap { case (b, u) => u.update(fetchVar.id, b); u }
State.modify[S] { case (x, arr) => (x, arr >>> thisArr) }.as(FreeApplicative.lift(fetchVar))
}
}
}
val ((varNum, arrowProgram), lastVar) = program
.foldMap(arrowCompiler)
.run((1, Arrow[Arrow0].lift[U, U](identity)))
.value
arrowProgram
.map(u => lastVar.foldMap(varCompiler(u)))
.lmap[A] { a =>
val arr = Array.ofDim[Any](varNum)
arr.update(0, a)
arr
}
}
}
}
/*
final class PartiallyAppliedCompiler[A] {
def apply[Arrow0[_, _]: Arrow, B](f: Var[A] => FreeArrow[Arrow0, Var[B]]): Arrow0[A, B] =
// Compiler.compileFull(null)
}
def compile[A]: PartiallyAppliedCompiler[A] = new PartiallyAppliedCompiler[A]*/
/*
object Test {
case class MyArrow[A, B](f: A => B)
implicit lazy val arrowForMyArrow: Arrow[MyArrow] =
new Arrow[MyArrow] {
override def compose[A, B, C](f: MyArrow[B, C], g: MyArrow[A, B]): MyArrow[A, C] =
MyArrow(f.f.compose(g.f))
override def first[A, B, C](fa: MyArrow[A, B]): MyArrow[(A, C), (B, C)] =
MyArrow { case (a, c) => (fa.f(a), c) }
override def lift[A, B](f: A => B): MyArrow[A, B] =
MyArrow(f)
}
object MyArrowDsl extends Dsl[MyArrow]
import MyArrowDsl._
val result: MyArrow[Int, String] = Lang[MyArrow, Int] { x =>
for {
x <- x.init.decl(_.map(_ - 2).map(_ + 2).map(_ - 2))
y <- init.decl(_.map(_ * 2))
k <- (x, x, x).tupled.decl(_.map { case (x1, x2, x3) => x1 + x2 + x3 })
z <- (k, y).tupled.decl(_.map { case (k, y) => k + y }.map(_.toString))
} yield z
}
}
object Practical {
import cats.effect._
object ResolverDsl extends Dsl[Resolver[IO, *, *]]
import ResolverDsl._
import Resolver._
import gql.dsl.all._
cats.syntax.arrow
val ageArg = arg[Int]("age")
val result: Resolver[IO, Int, String] = compile { init =>
for {
x <- init.decl(_.evalMap(x => IO(x - 2)).evalMap(x => IO(x + 2)).evalMap(x => IO(x - 2)))
y <- init.decl(_.streamMap(i => fs2.Stream(i)))
age <- init.decl(_ *> argument(ageArg))
z <- (x, y, age).tupled.decl(_.map { case (x, y, age) => x + y + age }.map(_.toString))
} yield z
}
}*/
type ArrowIO[A, B] = A => B
val ArrowForMyIO = Arrow[ArrowIO]
final case class Variable[A](id: Int)
type Var[A] = FreeApplicative[Variable, A]
sealed trait Algebra[A]
case class Declare[A, B](v: Var[A], arrow: ArrowIO[A, B]) extends Algebra[Var[B]]
type MyIO[A] = Free[Algebra, A]
def delay[A](f: => A): MyIO[Var[A]] =
Free.liftF[Algebra, Var[A]](Declare[Unit, A](().pure[Var], _ => f))
def derive[A, B](v: Var[A])(f: ArrowIO[A, B]): MyIO[Var[B]] =
Free.liftF[Algebra, Var[B]](Declare(v, f))
for {
x <- delay(1 + 1)
y <- derive(x)(_ * 2)
z <- derive((x,y).tupled){ case (a, b) => a + b }
} yield z
}
*/
}
Loading

0 comments on commit c5be2a2

Please sign in to comment.