Skip to content

Instantly share code, notes, and snippets.

@freewind
Last active August 29, 2015 14:24
Show Gist options
  • Select an option

  • Save freewind/72f1a34d6d11739d4373 to your computer and use it in GitHub Desktop.

Select an option

Save freewind/72f1a34d6d11739d4373 to your computer and use it in GitHub Desktop.
Incomplete macro code
package com.thoughtworks.scalazMonadFactory
import scala.language.experimental.macros
import scala.annotation.{tailrec, compileTimeOnly}
import scala.language.implicitConversions
import scala.language.higherKinds
import scalaz.Applicative
object ComprehensionApplicative {
def apply[F[_]]: Applicative[F] = macro applyImpl
def applyImpl(c: scala.reflect.macros.whitebox.Context): c.Tree = {
import c.universe._
import c.universe.Flag._
c.info(c.enclosingPosition, showRaw(c.macroApplication), true)
val TypeApply(_, List(fTypeTree)) = c.macroApplication
val ast = reify {
new Applicative[Seq] {
override def point[A](a: => A): Seq[A] = Seq(a)
override def ap[A, B](fa: => Seq[A])(ff: => Seq[(A) => B]): Seq[B] = for {
a <- fa
f <- ff
} yield f(a)
}
}
c.info(c.enclosingPosition, showRaw(ast), true)
Block(
List(
ClassDef(
Modifiers(FINAL), TypeName("$anon"), List(),
Template(
List(AppliedTypeTree(
Ident(scalaz.Applicative),
List(fTypeTree))),
noSelfType,
List(DefDef(Modifiers(), termNames.CONSTRUCTOR, List(), List(List()), TypeTree(),
Block(List(Apply(Select(Super(This(typeNames.EMPTY), typeNames.EMPTY), termNames.CONSTRUCTOR), List())),
Literal(Constant(())))), DefDef(Modifiers(OVERRIDE), TermName("point"),
List(TypeDef(Modifiers(PARAM), TypeName("A"), List(), TypeBoundsTree(TypeTree(), TypeTree()))),
List(List(
ValDef(
Modifiers(PARAM | BYNAMEPARAM),
TermName("a"),
Ident(TypeName("A")),
EmptyTree))),
AppliedTypeTree(fTypeTree,
List(Ident(TypeName("A")))), Apply(Select(Ident(scala.collection.Seq), TermName("apply")),
List(Ident(TermName("a"))))), DefDef(Modifiers(OVERRIDE), TermName("ap"),
List(TypeDef(Modifiers(PARAM), TypeName("A"), List(), TypeBoundsTree(TypeTree(), TypeTree())),
TypeDef(Modifiers(PARAM), TypeName("B"), List(), TypeBoundsTree(TypeTree(), TypeTree()))),
List(List(ValDef(Modifiers(PARAM | BYNAMEPARAM), TermName("fa"), AppliedTypeTree(Ident(scala.< byname >),
List(AppliedTypeTree(fTypeTree, List(Ident(TypeName("A")))))), EmptyTree)),
List(ValDef(Modifiers(PARAM | BYNAMEPARAM), TermName("ff"), AppliedTypeTree(Ident(scala.< byname >),
List(AppliedTypeTree(fTypeTree, List(AppliedTypeTree(Ident(scala.Function1),
List(Ident(TypeName("A")), Ident(TypeName("B")))))))), EmptyTree))), AppliedTypeTree(
fTypeTree,
List(Ident(TypeName("B")))), Apply(Apply(Select(Ident(TermName("fa")), TermName("flatMap")),
List(Function(List(ValDef(Modifiers(PARAM), TermName("a"), TypeTree(), EmptyTree)),
Apply(Apply(Select(Ident(TermName("ff")), TermName("map")),
List(Function(List(ValDef(Modifiers(PARAM), TermName("f"), TypeTree(), EmptyTree)),
Apply(Select(Ident(TermName("f")), TermName("apply")), List(Ident(TermName("a"))))))),
List(Select(Ident(scala.collection.Seq), TermName("canBuildFrom"))))))),
List(Select(Ident(scala.collection.Seq), TermName("canBuildFrom"))))))))),
Apply(Select(New(Ident(TypeName("$anon"))), termNames.CONSTRUCTOR), List()))
???
}
}
package com.thoughtworks.scalazMonadFactory
import org.junit._
class ComprehensionApplicativeTest {
@Test
def testArrayPoint(): Unit = {
val arrayApplicative = ComprehensionApplicative[Array]
Assert.assertArrayEquals(Array("hello, applicative"), arrayApplicative.point("hello, applicative"))
}
// @Test
// def testArrayAp(): Unit = {
//
// }
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment