Skip to content

Instantly share code, notes, and snippets.

@ctongfei
Last active May 13, 2017 20:03
Show Gist options
  • Save ctongfei/fa15d5e748c764de62be301cc02288bd to your computer and use it in GitHub Desktop.
Save ctongfei/fa15d5e748c764de62be301cc02288bd to your computer and use it in GitHub Desktop.
Implicit Evidence Summoning
import scala.language.experimental.macros
import scala.language.higherKinds
/**
* @author Tongfei Chen
*/
trait ImplicitSummoner1[Ev[_]] {
/**
* Retrieves the implicit algebraic structure implicitly defined in this scope.
* @param ev The implicit object to be retrieved
*/
def apply[A](implicit ev: Ev[A]): Ev[A] = macro ImplicitSummoning.summon1[Ev, A]
}
trait ImplicitSummoner2[Ev[_, _]] {
/**
* Retrieves the implicit algebraic structure implicitly defined in this scope.
* @param ev The implicit object to be retrieved
*/
def apply[A, B](implicit ev: Ev[A, B]): Ev[A, B] = macro ImplicitSummoning.summon2[Ev, A, B]
}
trait ImplicitSummoner3[Ev[_, _, _]] {
/**
* Retrieves the implicit algebraic structure implicitly defined in this scope.
* @param ev The implicit object to be retrieved
*/
def apply[A, B, C](implicit ev: Ev[A, B, C]): Ev[A, B, C] = macro ImplicitSummoning.summon3[Ev, A, B, C]
}
trait ImplicitSummonerH1[Ev[_[_]]] {
/**
* Retrieves the implicit algebraic structure implicitly defined in this scope.
* @param ev The implicit object to be retrieved
*/
def apply[A[_]](implicit ev: Ev[A]): Ev[A] = macro ImplicitSummoning.summonH1[Ev, A]
}
trait ImplicitSummonerH2[Ev[_[_, _]]] {
/**
* Retrieves the implicit algebraic structure implicitly defined in this scope.
* @param ev The implicit object to be retrieved
*/
def apply[A[_, _]](implicit ev: Ev[A]): Ev[A] = macro ImplicitSummoning.summonH2[Ev, A]
}
trait ImplicitSummonerH1H1[Ev[_[_], _[_]]] {
/**
* Retrieves the implicit algebraic structure implicitly defined in this scope.
* @param ev The implicit object to be retrieved
*/
def apply[A[_], B[_]](implicit ev: Ev[A, B]): Ev[A, B] = macro ImplicitSummoning.summonH1H1[Ev, A, B]
}
import scala.reflect.macros._
import scala.language.higherKinds
/**
* Enables zero-overhead summoning of implicit typeclass instances (as
* compared to the standard [[implicitly]], which has a method call overhead).
* @author Tongfei Chen
*/
object ImplicitSummoning {
def summon1[Ev[_], A](c: Context)(ev: c.Expr[Ev[A]]): c.Expr[Ev[A]] = ev
def summon2[Ev[_, _], A, B](c: Context)(ev: c.Expr[Ev[A, B]]): c.Expr[Ev[A, B]] = ev
def summon3[Ev[_, _, _], A, B, C](c: Context)(ev: c.Expr[Ev[A, B, C]]): c.Expr[Ev[A, B, C]] = ev
def summonH1[Ev[_[_]], A[_]](c: Context)(ev: c.Expr[Ev[A]]): c.Expr[Ev[A]] = ev
def summonH2[Ev[_[_, _]], A[_, _]](c: Context)(ev: c.Expr[Ev[A]]): c.Expr[Ev[A]] = ev
def summonH1H1[Ev[_[_], _[_]], A[_], B[_]](c: Context)(ev: c.Expr[Ev[A, B]]): c.Expr[Ev[A, B]] = ev
}
object Eq extends ImplicitSummoner1[Eq]
object MetricSpace extends ImplicitSummoner2[MetricSpace]
object Functor extends ImplicitSummonerH1[Functor]
object Arrow extends ImplicitSummonerH2[Arrow]
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment