Skip to content

Commit

Permalink
Merge pull request #49 from mikejcurry/add-imp-support
Browse files Browse the repository at this point in the history
Use imp summon macro to summon type class instance for apply
  • Loading branch information
mpilquist committed Dec 23, 2015
2 parents 10fc612 + 6e01351 commit 4d537dc
Show file tree
Hide file tree
Showing 2 changed files with 15 additions and 3 deletions.
4 changes: 2 additions & 2 deletions build.sbt
Original file line number Diff line number Diff line change
Expand Up @@ -34,7 +34,8 @@ lazy val commonSettings = Seq(
Resolver.sonatypeRepo("snapshots")
),
libraryDependencies ++= Seq(
"org.scalatest" %%% "scalatest" % "3.0.0-M7" % "test"
"org.scalatest" %%% "scalatest" % "3.0.0-M7" % "test",
"org.spire-math" %% "imp" % "0.2.0"
),
addCompilerPlugin("org.scalamacros" %% "paradise" % "2.1.0" cross CrossVersion.full),
licenses += ("Three-clause BSD-style", url("https://github.com/mpilquist/simulacrum/blob/master/LICENSE")),
Expand Down Expand Up @@ -144,4 +145,3 @@ lazy val noPublishSettings = Seq(
publishLocal := (),
publishArtifact := false
)

14 changes: 13 additions & 1 deletion core/src/main/scala/simulacrum/typeclass.scala
Original file line number Diff line number Diff line change
Expand Up @@ -6,6 +6,7 @@ import scala.reflect.macros.whitebox.Context

import macrocompat._


/**
* Annotation that may be applied to methods on a type that is annotated with `@typeclass`.
*
Expand Down Expand Up @@ -298,7 +299,17 @@ class TypeClassMacros(val c: Context) {

def generateCompanion(typeClass: ClassDef, tparam0: TypeDef, proper: Boolean, comp: Tree) = {
val tparam = eliminateVariance(tparam0)
val summoner = q"def apply[$tparam](implicit instance: ${typeClass.name}[${tparam.name}]): ${typeClass.name}[${tparam.name}] = instance"

// The apply method uses the imp macro to summon the appropriate instance, but as imp is a
// macro itself, an import is required in the generated tree to allow the macro to be called
// in the generated tree.
val summonerImports = q"""
import scala.language.experimental.macros
"""

val summoner = q"""
def apply[$tparam](implicit ev: ${typeClass.name}[${tparam.name}]): ${typeClass.name}[${tparam.name}] =
macro imp.summon[${typeClass.name}[${tparam.name}]]"""

val liftedTypeArg = if (proper) None else Some {
// We have a TypeClass[F[_ >: L <: U]], so let's create a F[X >: L <: U] for a fresh name X
Expand Down Expand Up @@ -359,6 +370,7 @@ class TypeClassMacros(val c: Context) {
val companion = q"""
$mods object $name extends ..$bases {
..$body
$summonerImports
$summoner
..$opsMembers
}
Expand Down

0 comments on commit 4d537dc

Please sign in to comment.