-
-
Save ariwaranosai/8250902e91e88ed206a83fdb7c5ee52c to your computer and use it in GitHub Desktop.
SI-2712 by the examples
This file contains 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 scalaz.{Monad} | |
import scalaz.OptionT | |
import scala.concurrent.Future | |
import scala.concurrent.ExecutionContext.Implicits.global | |
import scalaz.std.scalaFuture._ | |
import scala.language.existentials | |
import scala.language.experimental.macros | |
import scala.language.higherKinds | |
import scala.annotation.{ StaticAnnotation, tailrec } | |
import scala.reflect.api.Universe | |
import scala.reflect.macros.{ blackbox, whitebox } | |
trait P[I, A] { | |
def map[B](f: A => B): P[I, B] = new P[I, B] {} | |
def flatMap[B](f: A => P[I, B]): P[I, B] = new P[I, B] {} | |
} | |
object P { | |
implicit def pInstances[I] = | |
new Monad[({type λ[A] = P[I, A]})#λ] { | |
override def point[A](a: => A): P[I, A] = new P[I, A] {} | |
override def map[A, B](m: P[I, A])(f: A => B): P[I, B] = m.map(f) | |
override def bind[A, B](m: P[I, A])(f: A => P[I, B]): P[I, B] = m.flatMap(f) | |
} | |
} | |
type P2[A] = P[Int, A] | |
implicitly[Monad[P2]] // OK | |
implicitly[Monad[({type λ[A] = P[Int, A]})#λ]] // OK | |
// WITH HIGHER KINDED: implicits on Monad transformer | |
implicitly[Monad[({type λ[A] = OptionT[Future, A]})#λ]] // OK | |
// now using P, it needs to infer Monad[P2] or Monad[({type λ[A] = P[Int, A]})#λ ) | |
// type lambda fails | |
implicitly[Monad[({type λ[A] = OptionT[({type λ[A] = P[Int, A]})#λ, A]})#λ]] // KO | |
optionTMonadPlus[({type λ[A] = P[Int, A]})#λ] // OK | |
// type alias fails too | |
implicitly[Monad[({type λ[A] = OptionT[P2, A]})#λ]] // KO | |
optionTMonadPlus[P2] // OK | |
// TYPE LAMBDA IN MACRO | |
// In a scala file | |
package test | |
trait Gen[F[_]] | |
object Gen { | |
def apply[F[_]](implicit gen: Gen[F]): Gen[F] = gen | |
implicit def materialize[F[_]]: Gen[F] = | |
macro GenMacros.materialize[F] | |
} | |
class GenMacros(val c: whitebox.Context) { | |
import c.universe._ | |
def materialize[T[_]](implicit tTag: WeakTypeTag[T[_]]): Tree = { | |
val tpe = weakTypeOf[T[_]] | |
val clsName = TypeName(c.freshName()) | |
val r = q""" | |
final class $clsName extends _root_.test.Gen[$tpe] { } | |
new $clsName() | |
""" | |
println(r) | |
r | |
} | |
} | |
// compile and call it | |
Gen[Future] // OK | |
/* | |
{ | |
final class fresh$macro$1 extends _root_.utils.Gen[scala.concurrent.Future] { | |
def <init>() = { | |
super.<init>(); | |
() | |
}; | |
<empty> | |
}; | |
new fresh$macro$1() | |
} | |
*/ | |
Gen[P2] // OK | |
/* | |
{ | |
final class fresh$macro$2 extends _root_.utils.Gen[P2] { | |
def <init>() = { | |
super.<init>(); | |
() | |
}; | |
<empty> | |
}; | |
new fresh$macro$2() | |
} | |
*/ | |
Gen[({type λ[A] = P[Int, A]})#λ] // KO | |
/* F is not inferred due to SI-2712 :( | |
{ | |
final class fresh$macro$3 extends _root_.utils.Gen[F] { | |
def <init>() = { | |
super.<init>(); | |
() | |
}; | |
<empty> | |
}; | |
new fresh$macro$3() | |
} | |
*/ | |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment