Skip to content

Instantly share code, notes, and snippets.

@rubenfiszel
Created March 2, 2017 01:36
Show Gist options
  • Save rubenfiszel/03a851cd5fb7e2892f4a5fe7ca9d06e5 to your computer and use it in GitHub Desktop.
Save rubenfiszel/03a851cd5fb7e2892f4a5fe7ca9d06e5 to your computer and use it in GitHub Desktop.
import com.scalakata._
@instrument class Playground {
Prog.main()
}
trait Expr {
sealed trait Exp[T]
case class Const[T](x: T) extends Exp[T]
}
trait StagedT
trait Staged {
this: Expr =>
trait StagedTop[T] extends StagedT {
def exp: Exp[T]
}
}
trait Core extends Expr with Staged
trait Lift[A, B] {
def lift(x:A):B
}
trait Booleans {
type BoolConst = Boolean
type Bool <: BooleanOps with StagedT
trait BooleanOps {
def &&(b: Bool): Bool
def ||(b: Bool): Bool
def unary_!(): Bool
}
def liftBool: Lift[BoolConst, Bool]
}
trait BooleansExp extends Booleans {
this: Core =>
case class BoolAnd(x: Exp[BoolConst], y: Exp[BoolConst]) extends Exp[BoolConst]
case class BoolOr(x: Exp[BoolConst], y: Exp[BoolConst]) extends Exp[BoolConst]
case class BoolNot(x: Exp[BoolConst]) extends Exp[BoolConst]
case class Bool(exp: Exp[BoolConst]) extends BooleanOps with StagedTop[BoolConst] {
def &&(b: Bool) = Bool(bool_and applyOrElse((this.exp, b.exp), (BoolAnd.apply _).tupled))
def ||(b: Bool) = Bool(bool_or applyOrElse((this.exp, b.exp), (BoolOr.apply _).tupled))
def unary_! = Bool(bool_not applyOrElse(this.exp , BoolNot.apply))
}
val liftBool = new Lift[BoolConst, Bool] {
def lift(x: BoolConst) = Bool(Const(x))
}
def bool_and = PartialFunction.empty[(Exp[BoolConst], Exp[BoolConst]), Exp[BoolConst]]
def bool_or = PartialFunction.empty[(Exp[BoolConst], Exp[BoolConst]), Exp[BoolConst]]
def bool_not = PartialFunction.empty[Exp[BoolConst], Exp[BoolConst]]
}
trait BooleansOptImpl extends BooleansExp {
this: Core =>
override def bool_and = {
case (Const(cx), Const(cy)) => Const(cx && cy)
}
}
trait BooleansLib extends Booleans {
case class Bool(c:BoolConst) extends BooleanOps with StagedT {
def &&(b: Bool) = Bool(c && b.c)
def ||(b: Bool) = Bool(c || b.c)
def unary_! = Bool(!c)
}
val liftBool = new Lift[BoolConst, Bool] {
def lift(x: BoolConst) = Bool(x)
}
}
trait BooleansAPI {
val x: Booleans
type Boolean = x.Bool
implicit val boolList: Lift[scala.Boolean, Boolean] = x.liftBool
}
trait API {
implicit def liftF[A,B](x:A)(implicit l: Lift[A, B]):B =
l.lift(x)
}
trait DSL extends BooleansAPI with API
object Stage extends DSL{
override lazy val x = new BooleansOptImpl with Core {}//with ...
}
object Lib extends DSL {
override lazy val x = new BooleansLib with Core {}
}
object Prog {
import Lib._
def main() = {
val a: Boolean = true
val b: Boolean = false
a && b
}
}
trait TypeCheck extends DSL {
def main() = {
val a: Boolean = true
val b: Boolean = false
val c: Int = a
a && b
}
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment