aboutsummaryrefslogtreecommitdiff
path: root/examples/shared
diff options
context:
space:
mode:
authorJon Pretty <jon.pretty@propensive.com>2017-11-24 14:26:17 +0000
committerJon Pretty <jon.pretty@propensive.com>2017-11-24 14:26:17 +0000
commitd20a3824ce7719deb328ffed002288bedc398f77 (patch)
tree3c5cb04da66710498759439f8e8c068a0e9502ac /examples/shared
parent192173d811f870e6e9c705c80118e27dc63a898b (diff)
downloadmagnolia-d20a3824ce7719deb328ffed002288bedc398f77.tar.gz
magnolia-d20a3824ce7719deb328ffed002288bedc398f77.tar.bz2
magnolia-d20a3824ce7719deb328ffed002288bedc398f77.zip
Use virtualized `param` if it is available
Diffstat (limited to 'examples/shared')
-rw-r--r--examples/shared/src/main/scala/decode.scala3
-rw-r--r--examples/shared/src/main/scala/default.scala3
-rw-r--r--examples/shared/src/main/scala/eq.scala3
-rw-r--r--examples/shared/src/main/scala/package.scala8
-rw-r--r--examples/shared/src/main/scala/show.scala22
5 files changed, 33 insertions, 6 deletions
diff --git a/examples/shared/src/main/scala/decode.scala b/examples/shared/src/main/scala/decode.scala
index 5b083bd..14ab671 100644
--- a/examples/shared/src/main/scala/decode.scala
+++ b/examples/shared/src/main/scala/decode.scala
@@ -22,9 +22,10 @@ object Decoder {
/** type constructor for new instances of the typeclass */
type Typeclass[T] = Decoder[T]
+ type ParamType[T, P] = Param[Decoder, T] { type PType = P }
/** defines how new [[Decoder]]s for case classes should be constructed */
- def combine[T](ctx: CaseClass[Decoder, T]): Decoder[T] = new Decoder[T] {
+ def combine[T](ctx: CaseClass[Decoder, T, Param[Decoder, T]]): Decoder[T] = new Decoder[T] {
def decode(value: String) = {
val (name, values) = parse(value)
ctx.construct { param =>
diff --git a/examples/shared/src/main/scala/default.scala b/examples/shared/src/main/scala/default.scala
index 4c1b634..aa9dedc 100644
--- a/examples/shared/src/main/scala/default.scala
+++ b/examples/shared/src/main/scala/default.scala
@@ -10,10 +10,11 @@ trait Default[T] { def default: T }
object Default {
type Typeclass[T] = Default[T]
+ type ParamType[T, P] = Param[Default, T] { type PType = P }
/** constructs a default for each parameter, using the constructor default (if provided),
* otherwise using a typeclass-provided default */
- def combine[T](ctx: CaseClass[Default, T]): Default[T] = new Default[T] {
+ def combine[T](ctx: CaseClass[Default, T, Param[Default, T]]): Default[T] = new Default[T] {
def default = ctx.construct { param =>
param.default.getOrElse(param.typeclass.default)
}
diff --git a/examples/shared/src/main/scala/eq.scala b/examples/shared/src/main/scala/eq.scala
index 8ee42a4..6f00458 100644
--- a/examples/shared/src/main/scala/eq.scala
+++ b/examples/shared/src/main/scala/eq.scala
@@ -11,9 +11,10 @@ object Eq {
/** type constructor for the equality typeclass */
type Typeclass[T] = Eq[T]
+ type ParamType[T, P] = Param[Eq, T] { type PType = P }
/** defines equality for this case class in terms of equality for all its parameters */
- def combine[T](ctx: CaseClass[Eq, T]): Eq[T] = new Eq[T] {
+ def combine[T](ctx: CaseClass[Eq, T, Param[Eq, T]]): Eq[T] = new Eq[T] {
def equal(value1: T, value2: T) = ctx.parameters.forall { param =>
param.typeclass.equal(param.dereference(value1), param.dereference(value2))
}
diff --git a/examples/shared/src/main/scala/package.scala b/examples/shared/src/main/scala/package.scala
new file mode 100644
index 0000000..c196dbc
--- /dev/null
+++ b/examples/shared/src/main/scala/package.scala
@@ -0,0 +1,8 @@
+package magnolia
+
+package object examples {
+ implicit class Extensions[T](t: T) {
+ def show(implicit show: Show[String, T]): String = show.show(t)
+ def ===[S >: T: Eq](that: S): Boolean = implicitly[Eq[S]].equal(t, that)
+ }
+}
diff --git a/examples/shared/src/main/scala/show.scala b/examples/shared/src/main/scala/show.scala
index 50b34ee..a2b3c6b 100644
--- a/examples/shared/src/main/scala/show.scala
+++ b/examples/shared/src/main/scala/show.scala
@@ -9,25 +9,41 @@ import scala.language.experimental.macros
* be something other than a string. */
trait Show[Out, T] { def show(value: T): Out }
+case class ShowParam[Out, T, P](label: String, typeclass: Show[Out, P], deref: T => P) {
+ type PType = P
+ def show: Show[Out, PType] = typeclass
+ def dereference(t: T): PType = deref(t)
+}
+
+object Dflt {
+ implicit def any[T]: Dflt[T] = new Dflt[T] { def default: T = null.asInstanceOf[T] }
+}
+
+trait Dflt[T] { def default: T }
+
trait GenericShow[Out] {
/** the type constructor for new [[Show]] instances
*
* The first parameter is fixed as `String`, and the second parameter varies generically. */
type Typeclass[T] = Show[Out, T]
+ type ParamType[T, P] = ShowParam[Out, T, P]
def join(typeName: String, strings: Seq[String]): Out
+ def param[T, P](name: String, typeclassParam: Show[Out, P], default: Option[P], deref: T => P)(implicit auto: Dflt[P]) =
+ ShowParam[Out, T, P](name, typeclassParam, deref)
+
/** creates a new [[Show]] instance by labelling and joining (with `mkString`) the result of
* showing each parameter, and prefixing it with the class name */
- def combine[T](ctx: CaseClass[Typeclass, T]): Show[Out, T] = new Show[Out, T] {
+ def combine[T](ctx: CaseClass[Typeclass, T, ParamType[T, _]]): Show[Out, T] = new Show[Out, T] {
def show(value: T) =
if (ctx.isValueClass) {
val param = ctx.parameters.head
- param.typeclass.show(param.dereference(value))
+ param.show.show(param.dereference(value))
} else {
val paramStrings = ctx.parameters.map { param =>
- s"${param.label}=${param.typeclass.show(param.dereference(value))}"
+ s"${param.label}=${param.show.show(param.dereference(value))}"
}
join(ctx.typeName.split("\\.").last, paramStrings)