diff options
author | Jon Pretty <jon.pretty@propensive.com> | 2017-06-11 21:36:32 +0200 |
---|---|---|
committer | Jon Pretty <jon.pretty@propensive.com> | 2017-06-11 21:36:32 +0200 |
commit | 1ea072197cf8a992b37d7efe0636358a236b9d6d (patch) | |
tree | fed6804a2e65f783881ce1029bae60303b175803 /examples/src/main | |
parent | 9ff2305bcdd742529bd184ba90ecdef32ca2fe4d (diff) | |
download | magnolia-1ea072197cf8a992b37d7efe0636358a236b9d6d.tar.gz magnolia-1ea072197cf8a992b37d7efe0636358a236b9d6d.tar.bz2 magnolia-1ea072197cf8a992b37d7efe0636358a236b9d6d.zip |
Appears to be working for both covariant and contravariant typeclasses
Diffstat (limited to 'examples/src/main')
-rw-r--r-- | examples/src/main/scala/example.scala | 35 |
1 files changed, 32 insertions, 3 deletions
diff --git a/examples/src/main/scala/example.scala b/examples/src/main/scala/example.scala index e61f8bd..c719ad8 100644 --- a/examples/src/main/scala/example.scala +++ b/examples/src/main/scala/example.scala @@ -30,10 +30,10 @@ object Extractor extends Extractor_1 { implicit val stringExtractor: Extractor[String] = Extractor(_.str) implicit val doubleExtractor: Extractor[Double] = Extractor(_.str.length.toDouble) - implicit val dereferencer: Dereferencer[Extractor] { type Value = Thing } = new Dereferencer[Extractor] { + implicit val derivation: CovariantDerivation[Extractor] { type Value = Thing } = new CovariantDerivation[Extractor] { type Value = Thing def dereference(value: Thing, param: String): Thing = value.access(param) - def delegate[T](extractor: Extractor[T], value: Thing): T = extractor.extract(value) + def call[T](extractor: Extractor[T], value: Thing): T = extractor.extract(value) def combine[Supertype, Right <: Supertype](left: Extractor[_ <: Supertype], right: Extractor[Right]): Extractor[Supertype] = left.orElse(right) @@ -41,7 +41,6 @@ object Extractor extends Extractor_1 { def extract(source: Thing): T = body(source) } } - } trait Extractor_1 extends Extractor_2 { @@ -49,6 +48,36 @@ trait Extractor_1 extends Extractor_2 { def extract(source: Thing): List[T] = List(implicitly[Extractor[T]].extract(source)) } } + trait Extractor_2 { implicit def generic[T]: Extractor[T] = macro Macros.magnolia[T, Extractor[_]] } + +trait Serializer[T] { + def serialize(src: T): String +} + +object Serializer extends Serializer_1 { + implicit val deriv: ContravariantDerivation[Serializer] { type Return = String } = new ContravariantDerivation[Serializer] { + type Return = String + def call[T](typeclass: Serializer[T], value: T): String = typeclass.serialize(value) + def construct[T](body: T => String): Serializer[T] = new Serializer[T] { + def serialize(value: T): String = body(value) + } + def join(xs: List[String]): String = xs.mkString(", ") + } +} + +trait Serializer_1 extends Serializer_2 { + implicit val intSerializer: Serializer[Int] = { t => "int" } + implicit val strSerializer: Serializer[String] = { t => "string" } + implicit val doubleSerializer: Serializer[Double] = { t => "double" } + implicit def listSerializer[T: Serializer]: Serializer[List[T]] = { ts => + println(ts) + s"List[${ts.map { t => implicitly[Serializer[T]].serialize(t) }.mkString("-")}]" + } +} + +trait Serializer_2 { + implicit def generic[T]: Serializer[T] = macro Macros.magnolia[T, Serializer[_]] +} |