aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorJon Pretty <jon.pretty@propensive.com>2017-06-23 13:23:07 +0100
committerGitHub <noreply@github.com>2017-06-23 13:23:07 +0100
commita8bab561a1e7f43783c3536a7a68e8a27f34084a (patch)
treead46dba1dfa747876cb0ee6f33e7c2163599511b
parent27a55611230b772eae1f0a37822decb43c21ac25 (diff)
parent2fa873cd0322d21148cf01d94e485e04b03cdb7c (diff)
downloadmagnolia-a8bab561a1e7f43783c3536a7a68e8a27f34084a.tar.gz
magnolia-a8bab561a1e7f43783c3536a7a68e8a27f34084a.tar.bz2
magnolia-a8bab561a1e7f43783c3536a7a68e8a27f34084a.zip
Merge pull request #12 from propensive/ruippeixotog-cats-contravariant-example
Ruippeixotog cats contravariant example
-rw-r--r--.gitignore4
-rw-r--r--build.sbt4
-rw-r--r--core/src/main/scala/magnolia.scala19
-rw-r--r--examples/src/main/scala/cats.scala22
-rw-r--r--examples/src/main/scala/eq.scala (renamed from examples/src/main/scala/example.scala)38
-rw-r--r--tests/shared/src/main/scala/magnolia/main.scala16
6 files changed, 52 insertions, 51 deletions
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/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"))
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
new file mode 100644
index 0000000..8d33a0f
--- /dev/null
+++ b/examples/src/main/scala/cats.scala
@@ -0,0 +1,22 @@
+package magnolia.examples
+
+import scala.collection.immutable.ListMap
+import scala.language.experimental.macros
+
+import cats.Show
+import magnolia.ContravariantDerivation
+import magnolia.Macros
+
+object catsShowDerivation {
+
+ 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/example.scala b/examples/src/main/scala/eq.scala
index 543fa3d..30e7869 100644
--- a/examples/src/main/scala/example.scala
+++ b/examples/src/main/scala/eq.scala
@@ -3,25 +3,19 @@ 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 }
}
@@ -36,37 +30,21 @@ 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 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("{", ", ", "}")
- }
-}
-
-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 {
+object Eq {
implicit val eqInt: Eq[Int] = _ == _
- implicit val derivation = new ContravariantDerivation2[Eq] {
+ 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)
}
-}
-
-trait Eq_1 {
+
implicit def generic[T]: Eq[T] = macro Macros.magnolia[T, Eq[_]]
}
-
diff --git a/tests/shared/src/main/scala/magnolia/main.scala b/tests/shared/src/main/scala/magnolia/main.scala
index 3ac3fb6..c6cd9bc 100644
--- a/tests/shared/src/main/scala/magnolia/main.scala
+++ b/tests/shared/src/main/scala/magnolia/main.scala
@@ -1,23 +1,21 @@
package magnolia
-import examples._
+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)
-
}
}
-