Last active
May 13, 2017 20:03
-
-
Save ctongfei/fa15d5e748c764de62be301cc02288bd to your computer and use it in GitHub Desktop.
Implicit Evidence Summoning
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
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] | |
} |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
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 | |
} |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
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