From 4a6e5eaa04fe54fdda2c501cf79fb2c4c5aaa439 Mon Sep 17 00:00:00 2001 From: Rui Gonçalves Date: Wed, 21 Jun 2017 22:37:41 +0100 Subject: Add cats-core to the examples' dependencies --- build.sbt | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/build.sbt b/build.sbt index db54f76..33026f3 100644 --- a/build.sbt +++ b/build.sbt @@ -23,6 +23,7 @@ lazy val examples = crossProject(JSPlatform, JVMPlatform, NativePlatform) .settings(publishSettings: _*) .settings(moduleName := "magnolia-examples") .settings(quasiQuotesDependencies) + .settings(examplesDependencies) .nativeSettings(nativeSettings) .dependsOn(core) @@ -132,6 +133,9 @@ lazy val scalaMacroDependencies: Seq[Setting[_]] = Seq( libraryDependencies += compilerPlugin("org.scalamacros" % "paradise" % "2.1.0" cross CrossVersion.full) ) +lazy val examplesDependencies: Seq[Setting[_]] = Seq( + libraryDependencies += "org.typelevel" %% "cats-core" % "0.9.0") + credentials ++= (for { username <- Option(System.getenv().get("SONATYPE_USERNAME")) password <- Option(System.getenv().get("SONATYPE_PASSWORD")) -- cgit v1.2.3 From 0ccdf446c4c7770e60ede55ab712c8a551e36796 Mon Sep 17 00:00:00 2001 From: Rui Gonçalves Date: Wed, 21 Jun 2017 22:38:58 +0100 Subject: Reorganize magnolia.Show implicits Scopes magnolia.Show implicits so that they do not clash with cats' Show type class --- .gitignore | 4 ++++ examples/src/main/scala/example.scala | 21 ++++++++++----------- tests/shared/src/main/scala/magnolia/main.scala | 3 ++- 3 files changed, 16 insertions(+), 12 deletions(-) create mode 100644 .gitignore diff --git a/.gitignore b/.gitignore new file mode 100644 index 0000000..e7f1455 --- /dev/null +++ b/.gitignore @@ -0,0 +1,4 @@ +target +.jvm +.js +.native diff --git a/examples/src/main/scala/example.scala b/examples/src/main/scala/example.scala index e649b88..c3d4c2f 100644 --- a/examples/src/main/scala/example.scala +++ b/examples/src/main/scala/example.scala @@ -6,21 +6,11 @@ import language.experimental.macros import language.higherKinds import collection.immutable.ListMap -object `package` { - implicit class Showable[T: Show](t: T) { - def show: String = implicitly[Show[T]].show(t) - } - implicit val showString: Show[String] = identity - implicit val showBool: Show[Boolean] = _.toString - implicit def showList[T: Show]: Show[List[T]] = xs => xs.map { x => s"list:${implicitly[Show[T]].show(x)}" }.mkString(";") - implicit def showSet[T: Show]: Show[Set[T]] = s => "set" -} - sealed trait EmptyType sealed trait Tree case class Branch(left: Tree, right: Tree) extends Tree -case class Leaf(value: Int, no: EmptyType) extends Tree +case class Leaf(value: Int, no: String) extends Tree sealed trait Entity case class Person(name: String, address: Address) extends Entity @@ -31,12 +21,21 @@ case class Country(name: String, code: String, salesTax: Boolean) trait Show[T] { def show(t: T): String } object Show extends Show_1 { implicit val showInt: Show[Int] = _.toString + implicit val showString: Show[String] = identity + implicit val showBool: Show[Boolean] = _.toString + implicit def showList[T: Show]: Show[List[T]] = xs => xs.map { x => s"list:${implicitly[Show[T]].show(x)}" }.mkString(";") + implicit def showSet[T: Show]: Show[Set[T]] = s => "set" + implicit val derivation = new ContravariantDerivation[Show] { type Return = String def call[T](show: Show[T], value: T): String = show.show(value) def construct[T](body: T => String): Show[T] = body(_) def join(xs: ListMap[String, String]): String = xs.map { case (k, v) => s"$k=$v" }.mkString("{", ", ", "}") } + + implicit class Showable[T: Show](t: T) { + def show: String = implicitly[Show[T]].show(t) + } } trait Show_1 { diff --git a/tests/shared/src/main/scala/magnolia/main.scala b/tests/shared/src/main/scala/magnolia/main.scala index 014ec33..88b401e 100644 --- a/tests/shared/src/main/scala/magnolia/main.scala +++ b/tests/shared/src/main/scala/magnolia/main.scala @@ -1,10 +1,11 @@ package magnolia import examples._ +import examples.Show._ object Main { def main(args: Array[String]): Unit = { - println(Branch(Branch(Leaf(1, null), Leaf(2, null)), Leaf(3, null)).show) + println(Branch(Branch(Leaf(1, "a"), Leaf(2, "b")), Leaf(3, "c")).show) println(List[Entity](Person("John Smith", Address(List("1 High Street", "London", "SW1A 1AA"), Country("UK", "GBR", false)))).show) -- cgit v1.2.3 From d3bf8bef81124ef47097d808a0b9299641fe5c7b Mon Sep 17 00:00:00 2001 From: Rui Gonçalves Date: Wed, 21 Jun 2017 22:39:26 +0100 Subject: Add ContravariantDerivation for cats.Show --- examples/src/main/scala/cats.scala | 23 +++++++++++++++++++++++ tests/shared/src/main/scala/magnolia/cats.scala | 17 +++++++++++++++++ 2 files changed, 40 insertions(+) create mode 100644 examples/src/main/scala/cats.scala create mode 100644 tests/shared/src/main/scala/magnolia/cats.scala diff --git a/examples/src/main/scala/cats.scala b/examples/src/main/scala/cats.scala new file mode 100644 index 0000000..08690c2 --- /dev/null +++ b/examples/src/main/scala/cats.scala @@ -0,0 +1,23 @@ +package magnolia.examples.cats + +import scala.collection.immutable.ListMap +import scala.language.experimental.macros +import scala.language.higherKinds + +import cats.Show +import magnolia.ContravariantDerivation +import magnolia.Macros + +object instances extends instances1 { + + implicit val showDerivation = new ContravariantDerivation[Show] { + type Return = String + def call[T](show: Show[T], value: T): String = show.show(value) + def construct[T](body: T => String): Show[T] = body(_) + def join(xs: ListMap[String, String]): String = xs.map { case (k, v) => s"$k=$v" }.mkString("{", ", ", "}") + } +} + +trait instances1 { + implicit def genericShow[T]: Show[T] = macro Macros.magnolia[T, Show[_]] +} diff --git a/tests/shared/src/main/scala/magnolia/cats.scala b/tests/shared/src/main/scala/magnolia/cats.scala new file mode 100644 index 0000000..4a1c096 --- /dev/null +++ b/tests/shared/src/main/scala/magnolia/cats.scala @@ -0,0 +1,17 @@ +package magnolia + +import examples.{Address, Branch, Country, Entity, Leaf, Person} +import cats.instances.all._ +import cats.syntax.all._ +import examples.cats.instances._ +import language.experimental.macros + +object CatsMain { + + def main(args: Array[String]): Unit = { + println(Branch(Branch(Leaf(1, "a"), Leaf(2, "b")), Leaf(3, "c")).show) + println(List[Entity](Person("John Smith", + Address(List("1 High Street", "London", "SW1A 1AA"), + Country("UK", "GBR", false)))).show) + } +} -- cgit v1.2.3 From 2fa873cd0322d21148cf01d94e485e04b03cdb7c Mon Sep 17 00:00:00 2001 From: Jon Pretty Date: Fri, 23 Jun 2017 14:20:40 +0200 Subject: Tidied up and made it compile and run --- core/src/main/scala/magnolia.scala | 19 +++--- examples/src/main/scala/cats.scala | 23 ++++--- examples/src/main/scala/eq.scala | 50 +++++++++++++++ examples/src/main/scala/example.scala | 82 ------------------------- tests/shared/src/main/scala/magnolia/cats.scala | 17 ----- tests/shared/src/main/scala/magnolia/main.scala | 17 +++-- 6 files changed, 75 insertions(+), 133 deletions(-) create mode 100644 examples/src/main/scala/eq.scala delete mode 100644 examples/src/main/scala/example.scala delete mode 100644 tests/shared/src/main/scala/magnolia/cats.scala diff --git a/core/src/main/scala/magnolia.scala b/core/src/main/scala/magnolia.scala index 66d59d0..e2d1341 100644 --- a/core/src/main/scala/magnolia.scala +++ b/core/src/main/scala/magnolia.scala @@ -221,8 +221,8 @@ class Macros(val c: whitebox.Context) { val contraDerivationType = appliedType(contraDerivationTypeclass, List(typeConstructor)) val contraDerivation2Type = appliedType(contraDerivation2Typeclass, List(typeConstructor)) - def findDerivationImplicit[T <: DerivationImplicit](tpe: c.Type, cons: Tree => T): Try[DerivationImplicit] = - Try(cons(c.untypecheck(c.inferImplicitValue(tpe, false, false)))) + def findDerivationImplicit[T <: DerivationImplicit](derivationType: c.Type, wrap: Tree => T): Try[DerivationImplicit] = + Try(wrap(c.untypecheck(c.inferImplicitValue(derivationType, false, false)))) val derivationImplicit = findDerivationImplicit(coDerivationType, CovariantDerivationImplicit) @@ -258,17 +258,12 @@ class Macros(val c: whitebox.Context) { val searchType = appliedType(typeConstructor, genericType) Some(q"_root_.magnolia.Lazy[$searchType]($methodAsString)") } - } else { - directInferImplicit(genericType, typeConstructor, derivationImplicit) - } + } else directInferImplicit(genericType, typeConstructor, derivationImplicit) - if(currentStack.frames.isEmpty) recursionStack = Map() + if(currentStack.frames.isEmpty) recursionStack = ListMap() result.map { tree => - if(currentStack.frames.isEmpty) { - val res = c.untypecheck(removeLazy.transform(tree)) - res - } else tree + if(currentStack.frames.isEmpty) c.untypecheck(removeLazy.transform(tree)) else tree }.getOrElse { c.abort(c.enclosingPosition, "could not infer typeclass for type $genericType") } @@ -312,8 +307,8 @@ private[magnolia] object CompileTimeState { def termName(c: whitebox.Context): c.TermName = term.asInstanceOf[c.TermName] } - private[magnolia] var recursionStack: Map[api.Position, Stack] = - Map() + private[magnolia] var recursionStack: ListMap[api.Position, Stack] = + ListMap() private[magnolia] var emittedErrors: Set[ImplicitNotFound] = Set() } diff --git a/examples/src/main/scala/cats.scala b/examples/src/main/scala/cats.scala index 08690c2..8d33a0f 100644 --- a/examples/src/main/scala/cats.scala +++ b/examples/src/main/scala/cats.scala @@ -1,23 +1,22 @@ -package magnolia.examples.cats +package magnolia.examples import scala.collection.immutable.ListMap import scala.language.experimental.macros -import scala.language.higherKinds import cats.Show import magnolia.ContravariantDerivation import magnolia.Macros -object instances extends instances1 { +object catsShowDerivation { - implicit val showDerivation = new ContravariantDerivation[Show] { - type Return = String - def call[T](show: Show[T], value: T): String = show.show(value) - def construct[T](body: T => String): Show[T] = body(_) - def join(xs: ListMap[String, String]): String = xs.map { case (k, v) => s"$k=$v" }.mkString("{", ", ", "}") - } -} - -trait instances1 { + implicit val showDerivation: ContravariantDerivation[Show] = + new ContravariantDerivation[Show] { + type Return = String + def call[T](show: Show[T], value: T): String = show.show(value) + def construct[T](body: T => String): Show[T] = body(_) + def join(xs: ListMap[String, String]): String = + xs.map { case (k, v) => s"$k=$v" }.mkString("{", ", ", "}") + } + implicit def genericShow[T]: Show[T] = macro Macros.magnolia[T, Show[_]] } diff --git a/examples/src/main/scala/eq.scala b/examples/src/main/scala/eq.scala new file mode 100644 index 0000000..30e7869 --- /dev/null +++ b/examples/src/main/scala/eq.scala @@ -0,0 +1,50 @@ +package magnolia.examples + +import magnolia._ + +import language.experimental.macros +import collection.immutable.ListMap + +object `package` { + implicit class Equable[T: Eq](t: T) { + def isEqualTo(other: T): Boolean = implicitly[Eq[T]].isEqual(t, other) + } + + implicit val eqString: Eq[String] = _ == _ + implicit val eqBool: Eq[Boolean] = _ == _ + + implicit def eqList[T: Eq]: Eq[List[T]] = + (l1, l2) => l1.size == l2.size && (l1 zip l2).forall { case (e1, e2) => e1 isEqualTo e2 } + + implicit def eqSet[T: Eq]: Eq[Set[T]] = + (s1, s2) => s1.size == s2.size && (s1 zip s2).forall { case (e1, e2) => e1 isEqualTo e2 } +} + +sealed trait Tree +case class Branch(left: Tree, right: Tree) extends Tree +case class Leaf(value: Int) extends Tree + +sealed trait Entity +case class Person(name: String, address: Address) extends Entity +case class Organization(name: String, contacts: Set[Person]) extends Entity +case class Address(lines: List[String], country: Country) +case class Country(name: String, code: String, salesTax: Boolean) + +trait Eq[T] { def isEqual(a: T, b: T): Boolean } + +object Eq { + + implicit val eqInt: Eq[Int] = _ == _ + + implicit val derivation: ContravariantDerivation2[Eq] = new ContravariantDerivation2[Eq] { + type Return = Boolean + + def call[T](eq: Eq[T], value1: T, value2: T): Boolean = + if(value1.getClass == value2.getClass) eq.isEqual(value1, value2) else false + + def construct[T](body: (T, T) => Boolean): Eq[T] = body(_, _) + def join(elements: ListMap[String, Boolean]): Boolean = elements.forall(_._2) + } + + implicit def generic[T]: Eq[T] = macro Macros.magnolia[T, Eq[_]] +} diff --git a/examples/src/main/scala/example.scala b/examples/src/main/scala/example.scala deleted file mode 100644 index 6c289cb..0000000 --- a/examples/src/main/scala/example.scala +++ /dev/null @@ -1,82 +0,0 @@ -package magnolia.examples - -import magnolia._ - -import language.experimental.macros -import language.higherKinds -import collection.immutable.ListMap - - -object `package` { - implicit class Showable[T: Show](t: T) { - def show: String = implicitly[Show[T]].show(t) - } - implicit val showString: Show[String] = identity - implicit val showBool: Show[Boolean] = _.toString - implicit def showList[T: Show]: Show[List[T]] = xs => xs.map { x => s"list:${implicitly[Show[T]].show(x)}" }.mkString(";") - implicit def showSet[T: Show]: Show[Set[T]] = s => "set" - - implicit class Equable[T: Eq](t: T) { - def isEqualTo(other: T): Boolean = implicitly[Eq[T]].isEqual(t, other) - } - implicit val eqString: Eq[String] = _ == _ - implicit val eqBool: Eq[Boolean] = _ == _ - implicit def eqList[T: Eq]: Eq[List[T]] = - (l1, l2) => l1.size == l2.size && (l1 zip l2).forall { case (e1, e2) => e1 isEqualTo e2 } - implicit def eqSet[T: Eq]: Eq[Set[T]] = - (s1, s2) => s1.size == s2.size && (s1 zip s2).forall { case (e1, e2) => e1 isEqualTo e2 } -} - -sealed trait Tree -case class Branch(left: Tree, right: Tree) extends Tree -case class Leaf(value: Int) extends Tree - -sealed trait Entity -case class Person(name: String, address: Address) extends Entity -case class Organization(name: String, contacts: Set[Person]) extends Entity -case class Address(lines: List[String], country: Country) -case class Country(name: String, code: String, salesTax: Boolean) - -trait Show[T] { def show(t: T): String } -object Show extends Show_1 { - implicit val showInt: Show[Int] = _.toString - implicit val showString: Show[String] = identity - implicit val showBool: Show[Boolean] = _.toString - implicit def showList[T: Show]: Show[List[T]] = xs => xs.map { x => s"list:${implicitly[Show[T]].show(x)}" }.mkString(";") - implicit def showSet[T: Show]: Show[Set[T]] = s => "set" - - implicit val derivation = new ContravariantDerivation[Show] { - type Return = String - def call[T](show: Show[T], value: T): String = show.show(value) - def construct[T](body: T => String): Show[T] = body(_) - def join(xs: ListMap[String, String]): String = xs.map { case (k, v) => s"$k=$v" }.mkString("{", ", ", "}") - } - - implicit class Showable[T: Show](t: T) { - def show: String = implicitly[Show[T]].show(t) - } -} - -trait Show_1 { - implicit def generic[T]: Show[T] = macro Macros.magnolia[T, Show[_]] -} - -trait Eq[T] { def isEqual(a: T, b: T): Boolean } - -object Eq extends Eq_1 { - - implicit val eqInt: Eq[Int] = _ == _ - - implicit val derivation = new ContravariantDerivation2[Eq] { - type Return = Boolean - def call[T](eq: Eq[T], value1: T, value2: T): Boolean = - if(value1.getClass == value2.getClass) eq.isEqual(value1, value2) else false - def construct[T](body: (T, T) => Boolean): Eq[T] = body(_, _) - def join(elements: ListMap[String, Boolean]): Boolean = elements.forall(_._2) - } -} - -trait Eq_1 { - implicit def generic[T]: Eq[T] = macro Macros.magnolia[T, Eq[_]] -} - diff --git a/tests/shared/src/main/scala/magnolia/cats.scala b/tests/shared/src/main/scala/magnolia/cats.scala deleted file mode 100644 index 4a1c096..0000000 --- a/tests/shared/src/main/scala/magnolia/cats.scala +++ /dev/null @@ -1,17 +0,0 @@ -package magnolia - -import examples.{Address, Branch, Country, Entity, Leaf, Person} -import cats.instances.all._ -import cats.syntax.all._ -import examples.cats.instances._ -import language.experimental.macros - -object CatsMain { - - def main(args: Array[String]): Unit = { - println(Branch(Branch(Leaf(1, "a"), Leaf(2, "b")), Leaf(3, "c")).show) - println(List[Entity](Person("John Smith", - Address(List("1 High Street", "London", "SW1A 1AA"), - Country("UK", "GBR", false)))).show) - } -} diff --git a/tests/shared/src/main/scala/magnolia/main.scala b/tests/shared/src/main/scala/magnolia/main.scala index 4a9347a..c6cd9bc 100644 --- a/tests/shared/src/main/scala/magnolia/main.scala +++ b/tests/shared/src/main/scala/magnolia/main.scala @@ -1,24 +1,21 @@ package magnolia -import examples._ -import examples.Show._ +import examples.{Address, Branch, Country, Entity, Leaf, Person} +import cats.instances.all._ +import cats.syntax.all._ +import examples.catsShowDerivation._ +import language.experimental.macros object Main { - def main(args: Array[String]): Unit = { - val tree1: Tree = Branch(Branch(Leaf(1), Leaf(2)), Leaf(3)) - val tree2: Tree = Branch(Leaf(1), Leaf(2)) + def main(args: Array[String]): Unit = { + val tree1 = Branch(Branch(Leaf(1), Leaf(2)), Leaf(3)) println(tree1.show) println(tree1 isEqualTo tree1) - println(tree1 isEqualTo tree2) - println(Branch(Branch(Leaf(1), Leaf(2)), Leaf(3)).show) - println(List[Entity](Person("John Smith", Address(List("1 High Street", "London", "SW1A 1AA"), Country("UK", "GBR", false)))).show) - } } - -- cgit v1.2.3