Skip to content

Commit

Permalink
rework
Browse files Browse the repository at this point in the history
  • Loading branch information
dos65 committed Oct 4, 2020
1 parent 237b901 commit 2c3e181
Show file tree
Hide file tree
Showing 17 changed files with 119 additions and 205 deletions.
23 changes: 7 additions & 16 deletions build.sbt
Original file line number Diff line number Diff line change
@@ -1,3 +1,5 @@
import sbt.addCompilerPlugin

val commonSettings = Seq(
scalaVersion := "2.13.3",
organization := "io.github.dos65",
Expand Down Expand Up @@ -41,28 +43,17 @@ lazy val makeCatsEffect = project.in(file("modules/cats-effect"))
libraryDependencies ++= Seq(
"org.typelevel" %% "cats-effect" % "2.1.3"
),
)

lazy val makeZio = project.in(file("modules/zio"))
.dependsOn(core)
.settings(commonSettings)
.settings(
name := "make-zio",
scalacOptions ++= Seq(
"-language:experimental.macros"
),
libraryDependencies += "org.scalameta" %% "munit" % "0.4.3" % "test",
testFrameworks += new TestFramework("munit.Framework"),
libraryDependencies ++= Seq(
"dev.zio" %% "zio" % "1.0.1"
)
addCompilerPlugin("org.typelevel" %% "kind-projector" % "0.11.0" cross CrossVersion.full)
)

lazy val example = project.in(file("modules/example"))
.dependsOn(makeCatsEffect, makeZio)
.dependsOn(makeCatsEffect)
.settings(commonSettings)
.settings(
name := "make-example",
libraryDependencies ++= Seq(
"dev.zio" %% "zio" % "1.0.1"
),
addCompilerPlugin("org.typelevel" %% "kind-projector" % "0.11.0" cross CrossVersion.full)
)

Expand Down

This file was deleted.

18 changes: 18 additions & 0 deletions modules/cats-effect/src/main/scala/make/ce/resource.scala
Original file line number Diff line number Diff line change
@@ -0,0 +1,18 @@
package make.ce

import cats.effect.Resource
import cats.effect.IO
import make.MakeEff
import cats.Applicative

object resource {

type IOResource[A] = Resource[IO, A]

implicit def ceResourceEff[F[_]: Applicative]: MakeEff[Resource[F, ?]] =
new MakeEff[Resource[F, ?]] {
def map[A, B](fa: Resource[F, A])(f: A => B): Resource[F, B] = fa.map(f)
def pure[A](a: A): Resource[F, A] = Resource.pure(a)
def flatMap[A, B](fa: Resource[F, A])(f: A => Resource[F, B]): Resource[F, B] = fa.flatMap(f)
}
}
8 changes: 7 additions & 1 deletion modules/core/src/main/scala/make/Conflicts.scala
Original file line number Diff line number Diff line change
Expand Up @@ -3,7 +3,13 @@ package make
import scala.reflect.runtime.universe.Type
import make.Tag.SourcePos

final case class Conflicts(values: List[Conflicts.TpeConflict])
final case class Conflicts(values: List[Conflicts.TpeConflict]) extends Exception {
override def getMessage(): String = {
def renderSingle(v: Conflicts.TpeConflict): String =
s"${v.tpe} defined at ${v.positions.mkString(",")}"
s"Conflicts: ${values.map(renderSingle).mkString("; ")}"
}
}
object Conflicts {
final case class TpeConflict(tpe: Type, positions: List[SourcePos])
}
Original file line number Diff line number Diff line change
Expand Up @@ -7,19 +7,19 @@ import make.Make.Ap
import scala.annotation.tailrec
import make.Tag.SourcePos
import make.internal.Tarjans
import make.Make.Eff
import make.MakeEff

final class Dag[F[_], A](
entries: Map[Type, Dag.RawEntry[F]],
final class Graph[F[_], A](
entries: Map[Type, Graph.RawEntry[F]],
targetTpe: Type
)(implicit F: Eff[F]) {
)(implicit F: MakeEff[F]) {

def toEff: F[A] = {
def initEff: F[A] = {
val order = initOrder
val init = F.pure(Map.empty[Type, Any])

val rs = order.foldLeft(init){ case (rs, tpe) =>
Eff[F].flatMap(rs)(depsMap => {
MakeEff[F].flatMap(rs)(depsMap => {

val entry = entries(tpe)
val input = entry.dependsOn.map(depsMap(_))
Expand All @@ -28,7 +28,7 @@ final class Dag[F[_], A](
})
}

Eff[F].map(rs)(values => values(targetTpe).asInstanceOf[A])
MakeEff[F].map(rs)(values => values(targetTpe).asInstanceOf[A])
}

private def initOrder: List[Type] = {
Expand All @@ -47,7 +47,7 @@ final class Dag[F[_], A](

}

object Dag {
object Graph {

case class RawEntry[F[_]](
tpe: Type,
Expand All @@ -56,7 +56,7 @@ object Dag {
f: List[Any] => F[Any]
)

def fromMake[F[_]: Eff, A](v: Make[F, A]): Either[Conflicts, Dag[F, A]] = {
def fromMake[F[_]: MakeEff, A](v: Make[F, A]): Either[Conflicts, Graph[F, A]] = {
val allEntriesMap = makeToAllEntriesMap(
Map.empty,
List(v.asInstanceOf[Make[F, Any]])
Expand All @@ -79,12 +79,12 @@ object Dag {
if (errors.size > 0) {
Left(Conflicts(errors))
} else {
Right(new Dag(okMap, v.tag.typeTag.tpe))
Right(new Graph(okMap, v.tag.typeTag.tpe))
}
}

@tailrec
private def makeToAllEntriesMap[F[_]: Eff](
private def makeToAllEntriesMap[F[_]: MakeEff](
acc: Map[Type, List[RawEntry[F]]],
stack: List[Make[F, Any]]
): Map[Type, List[RawEntry[F]]] = {
Expand All @@ -104,7 +104,7 @@ object Dag {
(in: List[Any]) => {
val a = in(0)
val aToB = in(1).asInstanceOf[Any => Any]
Eff[F].pure[Any](aToB(a))
MakeEff[F].pure[Any](aToB(a))
}
val deps = List(
prev.tag.typeTag.tpe,
Expand Down
21 changes: 4 additions & 17 deletions modules/core/src/main/scala/make/Make.scala
Original file line number Diff line number Diff line change
Expand Up @@ -28,27 +28,14 @@ object Make extends MakeTupleInstances with LowPrioMake {
tag: Tag[A]
) extends Make[F, A]

def pure[F[_]: Eff, A: Tag](a: A): Make[F, A] =
Value(Eff[F].pure(a), Tag.of[A])
def pure[F[_]: MakeEff, A: Tag](a: A): Make[F, A] =
Value(MakeEff[F].pure(a), Tag.of[A])

def eff[F[_]: Eff, A: Tag](v: F[A]): Make[F, A] =
def eff[F[_]: MakeEff, A: Tag](v: F[A]): Make[F, A] =
Value(v, Tag.of[A])

trait Eff[F[_]] {
def map[A, B](fa: F[A])(f: A => B): F[B]
def pure[A](a: A): F[A]
def flatMap[A, B](fa: F[A])(f: A => F[B]): F[B]
}

object Eff {
def apply[F[_]](implicit eff: Eff[F]): Eff[F] = eff
}

trait EffError[F[_]] extends Eff[F] {
def raiseConflicts[A](v: Conflicts): F[A]
}

implicit def contraMakeInstance[F[_]: Eff, B, A](
implicit def contraMakeInstance[F[_]: MakeEff, B, A](
implicit contra: ContraMake[B, A], m: Make[F, B], tag: Tag[A]
): Make[F, A] = MakeOps.map(m)(contra.f)
}
Expand Down
11 changes: 11 additions & 0 deletions modules/core/src/main/scala/make/MakeEff.scala
Original file line number Diff line number Diff line change
@@ -0,0 +1,11 @@
package make

trait MakeEff[F[_]] {
def map[A, B](fa: F[A])(f: A => B): F[B]
def pure[A](a: A): F[A]
def flatMap[A, B](fa: F[A])(f: A => F[B]): F[B]
}

object MakeEff {
def apply[F[_]](implicit eff: MakeEff[F]): MakeEff[F] = eff
}
23 changes: 11 additions & 12 deletions modules/core/src/main/scala/make/MakeSyntax.scala
Original file line number Diff line number Diff line change
@@ -1,31 +1,30 @@
package make

import make.internal.MakeOps
import make.Make.Eff
import make.Make.EffError
import make.MakeEff

object syntax extends MakeTupleSyntax {
implicit def makeToBasicSyntax[F[_], A](make: Make[F, A]): MakeBasicSyntax[F, A] =
new MakeBasicSyntax(make)
}

final class MakeBasicSyntax[F[_], A](private val m: Make[F, A]) extends AnyVal {
def map[B: Tag](f: A => B)(implicit F: Eff[F]): Make[F, B] =
def map[B: Tag](f: A => B)(implicit F: MakeEff[F]): Make[F, B] =
MakeOps.map(m)(f)

def mapF[B: Tag](f: A => F[B])(implicit F: Eff[F]): Make[F, B] =
def mapF[B: Tag](f: A => F[B])(implicit F: MakeEff[F]): Make[F, B] =
MakeOps.mapF(m)(f)

def ap[B: Tag](mf: Make[F, A => B]): Make[F, B] =
MakeOps.ap(m)(mf)

def toDag(implicit F: Eff[F]): Either[Conflicts, Dag[F, A]] =
Dag.fromMake(m)
def toGraph(implicit F: MakeEff[F]): Either[Conflicts, Graph[F, A]] =
Graph.fromMake(m)

def toEff(implicit F: EffError[F]): F[A] = {
toDag match {
case Left(conflicts) => F.raiseConflicts(conflicts)
case Right(dag) => dag.toEff
}
}
// def toEff(implicit F: EffError[F]): F[A] = {
// toDag match {
// case Left(conflicts) => F.raiseConflicts(conflicts)
// case Right(dag) => dag.toEff
// }
// }
}
Original file line number Diff line number Diff line change
Expand Up @@ -52,7 +52,7 @@ class MakeAnnotationMacro(val c: blackbox.Context) {

val mapF = if (params.size > 1) q"($create).tupled" else create

val effTpe = TermName(c.freshName("MakeEff")).toTypeName
val effTpe = TermName(c.freshName("E")).toTypeName

val targetTpe =
if (typeParams.isEmpty)
Expand All @@ -62,7 +62,7 @@ class MakeAnnotationMacro(val c: blackbox.Context) {

val implicits =
q"deps: _root_.make.Make[$effTpe, $tpe]" ::
q"${TermName(c.freshName())}: _root_.make.Make.Eff[$effTpe]" ::
q"${TermName(c.freshName())}: _root_.make.MakeEff[$effTpe]" ::
implicitParams.toList ++
(if (paramsTpe.isEmpty) List.empty else List(q"tag: _root_.make.Tag[$targetTpe]"))

Expand Down
15 changes: 4 additions & 11 deletions modules/core/src/main/scala/make/internal/MakeBasicOps.scala
Original file line number Diff line number Diff line change
Expand Up @@ -2,31 +2,24 @@ package make.internal

import make.Tag
import make.Make
import make.Make.Eff
import make.MakeEff

trait MakeBasicOps {

def map[F[_]: Eff, A, B: Tag](ma: Make[F, A])(f: A => B): Make[F, B] =
def map[F[_]: MakeEff, A, B: Tag](ma: Make[F, A])(f: A => B): Make[F, B] =
Make.Bind(
ma,
(a: A) => Eff[F].pure(f(a)),
(a: A) => MakeEff[F].pure(f(a)),
Tag.of[B]
)

def mapF[F[_]: Eff, A, B: Tag](ma: Make[F, A])(f: A => F[B]): Make[F, B] =
def mapF[F[_]: MakeEff, A, B: Tag](ma: Make[F, A])(f: A => F[B]): Make[F, B] =
Make.Bind(
ma,
(a: A) => f(a),
Tag.of[B]
)

// def mapResource[F[_], A, B: Tag](ma: Make[F, A])(f: A => Resource[F, B]): Make[F, B] =
// Make.Bind(
// ma,
// f,
// Tag.of[B]
// )

def ap[F[_], A, B: Tag](ma: Make[F, A])(mf: Make[F, A => B]): Make[F, B] =
Make.Ap(
ma,
Expand Down
8 changes: 4 additions & 4 deletions modules/core/src/test/scala/make/MakeTest.scala
Original file line number Diff line number Diff line change
Expand Up @@ -12,20 +12,20 @@ class MakeTest extends FunSuite {

test("basic") {
val a = Make.pure[IO, Int](1)
assertEquals(a.tag.sourcePos, SourcePos("make.MakeTest.a", 12, 31))
assertEquals(a.tag.sourcePos, SourcePos("make.MakeTest.a", 14, 31))
}

test("map") {
val a = Make.pure(42)
val b = a.map(_.toString)
assertEquals(b.tag.sourcePos, SourcePos("make.MakeTest.b", 18, 18))
assertEquals(b.tag.sourcePos, SourcePos("make.MakeTest.b", 20, 18))
}

test("conflict") {
val a = Make.pure[IO, Int](42)
val b = a.map(identity)
assert(a.toDag.isRight)
assert(b.toDag.isLeft)
assert(a.toGraph.isRight)
assert(b.toGraph.isLeft)
}

}
4 changes: 2 additions & 2 deletions modules/core/src/test/scala/make/ioEff.scala
Original file line number Diff line number Diff line change
Expand Up @@ -4,8 +4,8 @@ import cats.effect.IO

object ioEff {

implicit def ioEff: Make.Eff[IO] =
new Make.Eff[IO] {
implicit def ioEff: MakeEff[IO] =
new MakeEff[IO] {
def map[A, B](fa: IO[A])(f: A => B): IO[B] = fa.map(f)
def pure[A](a: A): IO[A] = IO.pure(a)
def flatMap[A, B](fa: IO[A])(f: A => IO[B]): IO[B] = fa.flatMap(f)
Expand Down
Loading

0 comments on commit 2c3e181

Please sign in to comment.