Skip to content

Commit

Permalink
init
Browse files Browse the repository at this point in the history
  • Loading branch information
dos65 committed Jun 25, 2020
0 parents commit fe2f2af
Show file tree
Hide file tree
Showing 12 changed files with 662 additions and 0 deletions.
48 changes: 48 additions & 0 deletions .gitignore
Original file line number Diff line number Diff line change
@@ -0,0 +1,48 @@
*.class
*.log

# sbt specific
.cache
.history
.lib/
dist/*
target/
lib_managed/
src_managed/
project/boot/
project/plugins/project/
**/.bloop

# Scala-IDE specific
.scala_dependencies
.worksheet

.idea

# ENSIME specific
.ensime_cache/
.ensime

.metals/
metals.sbt
metals/project/

.vscode/

local.*

.DS_Store

node_modules

lib/core/metadata.js
lib/core/MetadataBlog.js

website/translated_docs
website/build/
website/yarn.lock
website/node_modules
website/i18n/*
!website/i18n/en.json

project/metals.sbt
17 changes: 17 additions & 0 deletions build.sbt
Original file line number Diff line number Diff line change
@@ -0,0 +1,17 @@
lazy val core = project.in(file("modules/core"))
.settings(
scalaVersion := "2.12.11",
libraryDependencies ++= Seq(
"org.typelevel" %% "cats-core" % "2.1.1",
"org.typelevel" %% "cats-effect" % "2.1.3",
"com.lihaoyi" %% "sourcecode" % "0.1.9",
"org.scala-lang" % "scala-reflect" % scalaVersion.value
)
)

lazy val example = project.in(file("modules/example"))
.dependsOn(core)
.settings(
scalaVersion := "2.12.11",
//scalacOptions ++= Seq("-Ymacro-debug-lite", "-Yshow-trees-compact")
)
62 changes: 62 additions & 0 deletions modules/core/src/main/scala/make/Make.scala
Original file line number Diff line number Diff line change
@@ -0,0 +1,62 @@
package make

import make.internal.Node
import make.internal.NodeTag
import cats.effect.Resource
import cats.Applicative
import make.internal.NodeTag.Pos
import scala.reflect.classTag
import scala.reflect.ClassTag
import scala.language.experimental.macros
import cats.Monad

trait Make[F[_], A] {
def node: Node[A]
final def asResource(implicit x: Monad[F]): Resource[F, A] = internal.Dag.toResource[F, A](node)
}

object Make {

def context[F[_]: Applicative]: Make.Ctx[F] = new Ctx[F]

def inCtx[F[_]: Make.Ctx]: DerivePartillyApplyed[F] =
new DerivePartillyApplyed[F]

class DerivePartillyApplyed[F[_]] {
def derive[A]: Make[F, A] =
macro make.internal.DepsCtxMacros.materializeMake[F, A]
}

final class Ctx[F[_]: Applicative] {
def pure[A: NodeTag](v: A): Make[F, A] =
createFromNodeUnsafe(Node.Pure(v, NodeTag.of[A]))

def effect[A: NodeTag](v: F[A]): Make[F, A] =
createFromNodeUnsafe(Node.Eff(Resource.liftF(v), NodeTag.of[A]))

def resource[A: NodeTag](v: Resource[F, A]): Make[F, A] =
createFromNodeUnsafe(Node.Eff(v, NodeTag.of[A]))
}

final class DepsCtx[F[_]: Applicative, A](deps: Make[F, A]) {
def pure[B: NodeTag](f: A => B): Make[F, B] =
createFromNodeUnsafe(Node.Func(deps.node, f, NodeTag.of[B]))

def effect[B: NodeTag](f: A => F[B]): Make[F, B] =
createFromNodeUnsafe(Node.EffFunc(deps.node, (a: A) => Resource.liftF(f(a)), NodeTag.of[B]))

def resource[B: NodeTag](f: A => Resource[F, B]): Make[F, B] =
createFromNodeUnsafe(Node.EffFunc(deps.node, f, NodeTag.of[B]))
}

object DepsCtx {

implicit def derive[F[_], A]: Make.DepsCtx[F, A] =
macro make.internal.DepsCtxMacros.materializeDeps[F, A]
}

def createFromNodeUnsafe[F[_], A](v: Node[A]): Make[F, A] =
new Make[F, A] {
val node: Node[A] = v
}
}
155 changes: 155 additions & 0 deletions modules/core/src/main/scala/make/Second.scala
Original file line number Diff line number Diff line change
@@ -0,0 +1,155 @@
package sdi

import cats.effect.Resource
import scala.reflect.macros.blackbox.Context
import scala.language.experimental.macros

// trait InstanceTree[F[_], A]

// trait EffForInstances[F[_]]

// sealed trait Instance2[A] {
// def tag: Tag[A]
// }
// object Instance2 {

// final case class Pure[A](v: A, tag: Tag[A]) extends Instance2[A]
// final case class Func[In, A](prev: Instance2[In], f: In => A, tag: Tag[A]) extends Instance2[A]

// sealed trait EffInstance[F[_], A] extends Instance2[A]
// final case class Eff[F[_], A](v: F[A], tag: Tag[A]) extends EffInstance[F, A]
// final case class EffFunc[F[_], In, A](prev: Instance2[In], f: In => Resource[F, A], tag: Tag[A]) extends EffInstance[F, A]

// final case class Ap[In, A](prev: Instance2[In], f: Instance[In => A], tag: Tag[In => A]) extends Instance2[In => A]

// // def deriveTree[F[_], A]: InstanceTree[F, A] = ???

// }


// sealed trait Instance[A] {
// def tag: Tag[A]
// }

// object Instance {

// final case class Pure[A](v: A, tag: Tag[A]) extends Instance[A]
// final case class Effect[F[_], A](v: F[A], tag: Tag[A]) extends Instance[A]
// final case class Map[In, A](prev: Instance[In], f: In => A, tag: Tag[A]) extends Instance[A]
// final case class Ap[In, A](prev: Instance[In], f: Instance[In => A], tag: Tag[In => A]) extends Instance[In => A]

// final case class PureK[F[_], A](v: A, tag: Tag[A]) extends Instance[A]

// def pure[A: Tag](v: A): Instance.Pure[A] = Instance.Pure(v, Tag.of[A])
// def effect[F[_], A: Tag](v: F[A]): Instance.Effect[F, A] = Instance.Effect(v, Tag.of[A])

// }

// trait Requires[A]
// object Requires {
// implicit def derive[A]: Requires[A] = macro RequiresMacro.materialize[A]
// }

// class RequiresMacro(val c: Context) {
// import c.universe._

// private val intanceTC = typeOf[Instance[_]].typeConstructor

// def materialize[A: c.WeakTypeTag]: c.Expr[Requires[A]] = {
// val tpe = weakTypeOf[A]
// println(tpe.getClass())
// val out = resolve(tpe).orElse(tryTuple(tpe))

// out match {
// case Some(tree) => c.Expr[Requires[A]](q"new Requires[$tpe]{}")
// case None =>
// c.error(c.enclosingPosition, s"Can't find `Requires` for $tpe")
// c.Expr[Requires[A]](EmptyTree)
// }
// }

// private val tupleRegex = "scala.Tuple(\\d+)".r


// private def tryTuple(tpe: Type): Option[c.Tree] = {
// val name = tpe.typeSymbol.fullName

// name match {
// case tupleRegex(x) =>
// println(s"sdassa: ${x}")
// println(tpe.typeArgs)

// val init = List.empty[String]
// val errors = tpe.typeArgs.foldLeft(init){
// case (errAcc, t) =>
// resolve(t) match {
// case Some(_) => errAcc
// case None => s"Can't find Instance for ${t}" :: errAcc
// }
// }
// if (errors.nonEmpty) {
// val x = errors.mkString("\n")
// c.error(c.enclosingPosition, x)
// None
// } else {
// Some(EmptyTree)
// }
// case _ => None
// }
// }

// private def resolve(tpe: Type): Option[c.Tree] = {
// c.inferImplicitValue(appliedType(intanceTC, tpe)) match {
// case EmptyTree => None
// case tree => Some(tree)
// }
// }
// }


// object XXx2 {

// case class Args(args: List[String])
// object Args {
// implicit def instance(implicit req: Requires[List[String]]): Instance[]
// }

// case class Abc(args: Args, out: String)
// object Abc {
// implicit val instance: Bind2.Func[Args, Abc] = Bind2.func(Abc(_, "default"))
// }

// case class Foo(args: Args)
// object Foo {
// implicit val instanceXXX: Bind2.Func[Args, Foo] = Bind2.func(Foo(_))
// implicit val instance2: Bind2.Func[Int, Foo] = Bind2.func(x => Foo(Args(List(x.toString()))))
// }

// case class End(
// abc: Abc,
// foo: Foo
// ) {
// def what: String = abc.out
// }

// object End {
// implicit val instance: Bind2.Func[(Abc, Foo), End] = Bind2.func({ case (abc, foo) => End(abc, foo)})
// }


// def main(args: Array[String]): Unit = {
// import cats.implicits._
// import cats.effect.implicits._

// implicit val initArgs = Bind2.pure(args.toList)

// implicit val tmp = Bind2.pure(1)
// // implicit val abcOverride = Bind2.func(Abc(_, "override"))
// val out = DependencyTree.of[IO, Foo]
// // val rsc = Instantiate(out)

// // val eff = rsc.use(value => IO.delay(println(s"HAHAHAH: ${value.what}")))
// // eff.unsafeRunSync()
// }

// }
104 changes: 104 additions & 0 deletions modules/core/src/main/scala/make/internal/Dag.scala
Original file line number Diff line number Diff line change
@@ -0,0 +1,104 @@
package make.internal

import cats.Monad
import cats.effect.Resource

object Dag {

case class Entry[F[_]](
tag: NodeTag[Any],
create: List[Any] => Resource[F, Any],
takes: Vector[NodeTag[Any]]
)

def toResource[F[_], A](node: Node[A])(implicit F: Monad[F]): Resource[F, A] = {

def toMap(
node: Node[Any],
acc: Map[NodeTag[Any], Entry[F]]
): Map[NodeTag[Any], Entry[F]] = {
node match {
case Node.Pure(v, tag) =>
val entry = acc.get(tag) match {
case None => Entry[F](tag, _ => Resource.pure(v), Vector.empty)
case Some(e) => e
}
acc.updated(tag, entry)
case Node.Func(prev, f, tag) =>
val updEntry = acc.get(tag) match {
case None => Entry[F](tag, lst => Resource.pure(f(lst(0))), Vector(prev.tag))
case Some(e) => e.copy(takes = e.takes :+ prev.tag)
}
val next = acc.updated(tag, updEntry)
toMap(prev, next)
case Node.Eff(v, tag) =>
val entry = acc.get(tag) match {
case None => Entry[F](tag, _ => v.asInstanceOf[Resource[F, Any]], Vector.empty)
case Some(e) => e
}
acc.updated(tag, entry)
case Node.EffFunc(prev, f, tag) =>
val updEntry = acc.get(tag) match {
case None => Entry[F](tag, lst => f(lst(0)).asInstanceOf[Resource[F, Any]], Vector(prev.tag))
case Some(e) => e.copy(takes = e.takes :+ prev.tag)
}
val next = acc.updated(tag, updEntry)
toMap(prev, next)
case Node.Ap(prev, op, tag) =>
val opAdded = toMap(op.asInstanceOf[Node[Any]], acc)
val updEntry = acc.get(tag) match {
case None => Entry[F](
tag,
lst => {
val a = lst(0)
val aToB = lst(1).asInstanceOf[Any => Any]
Resource.pure(aToB(a))
},
Vector(prev.tag, op.tag.asInstanceOf[NodeTag[Any]])
)
case Some(e) => e.copy(takes = e.takes :+ prev.tag)
}
val next = opAdded.updated(tag, updEntry)
toMap(prev, next)
}
}
val empty = Map.empty[NodeTag[Any], Entry[F]]
val asMap = toMap(node.asInstanceOf[Node[Any]], empty)

val indexedKeys = asMap.keys.zipWithIndex.toMap
val indexedMap = indexedKeys.map {case (tag, _) =>
val entry = asMap(tag)
println(entry)
entry.takes.map(indexedKeys(_)).toList
}.toList


val sorted = Tarjans.apply(indexedMap)

val entriesWithTags = sorted.flatten.map(i => {
val (tag, idx) = indexedKeys.find(_._2 == i).get
val entry = asMap(tag)
(entry, tag)
})


case class ResourceState(
map: Map[NodeTag[Any], Any]
)

val init = Resource.make[F, Map[NodeTag[Any], Any]](F.pure(Map.empty))(_ => F.unit)
val resourcePipeline = entriesWithTags.foldLeft(init){ case (accResource, (entry, tag)) =>
accResource.flatMap(depsMap => {
val input = entry.takes.map(depsMap(_))
val rsc = entry.create(input.toList)
rsc.map(v => depsMap.updated(tag, v))
})
}

resourcePipeline.map(all => {
println(all)
all(node.tag.asInstanceOf[NodeTag[Any]])
}).asInstanceOf[Resource[F, A]]
}

}
Loading

0 comments on commit fe2f2af

Please sign in to comment.