Skip to content

Instantly share code, notes, and snippets.

@Blaisorblade
Created August 8, 2012 22:22
Show Gist options
  • Save Blaisorblade/3299381 to your computer and use it in GitHub Desktop.
Save Blaisorblade/3299381 to your computer and use it in GitHub Desktop.
Testing pattern matcher virtualization
$ ~/opt/scala-2.10.0-M6/bin/scalac -Xexperimental ./test-src/epfl/test4-functions/TestPatMat.scala
./test-src/epfl/test4-functions/TestPatMat.scala:63: error: type mismatch;
found : Prog.this.Rep[Prog.this.Rep[Int]] => Prog.this.M[String]
required: Prog.this.Rep[Int] => Prog.this.M[?]
def test = repInt(7) match { case 5 => "foo" case _ => "bar" }
^
one error found
package scala.virtualization.lms
package epfl
package test4
trait Intf {
type Rep[+T]
type M[+T] = Rep[Maybe[T]]
val __match: Matcher
abstract class Matcher {
// runs the matcher on the given input
def runOrElse[T, U](in: Rep[T])(matcher: Rep[T] => M[U]): Rep[U]
def zero: M[Nothing]
def one[T](x: Rep[T]): M[T]
def guard[T](cond: Rep[Boolean], then: => Rep[T]): M[T]
def isSuccess[T, U](x: Rep[T])(f: Rep[T] => M[U]): Rep[Boolean] // used for isDefinedAt
}
abstract class Maybe[+A] {
def flatMap[B](f: Rep[A] => M[B]): M[B]
def orElse[B >: A](alternative: => M[B]): M[B]
}
implicit def proxyMaybe[A](m: M[A]): Maybe[A]
implicit def repInt(x: Int): Rep[Int]
implicit def repBoolean(x: Boolean): Rep[Boolean]
implicit def repString(x: String): Rep[String]
}
trait Impl extends Intf {
type Rep[+T] = String
object __match extends Matcher {
def runOrElse[T, U](in: Rep[T])(matcher: Rep[T] => M[U]): Rep[U] =
("runOrElse("+ in +", ?" + matcher("?") + ")")
def zero: M[Nothing] = "zero"
def one[T](x: Rep[T]): M[T] = "one("+x.toString+")"
def guard[T](cond: Rep[Boolean], then: => Rep[T]): M[T] =
"guard("+cond+","+then+")"
def isSuccess[T, U](x: Rep[T])(f: Rep[T] => M[U]): Rep[Boolean] =
("isSuccess("+x+", ?" + f("?") + ")")
}
implicit def proxyMaybe[A](m: M[A]): Maybe[A] = new Maybe[A] {
def flatMap[B](f: Rep[A] => M[B]): M[B] = m + ".flatMap(? =>"+ f("?") +")"
def orElse[B >: A](alternative: => M[B]): M[B] = m + ".orElse("+ alternative +")"
}
def repInt(x: Int): Rep[Int] = x.toString
def repBoolean(x: Boolean): Rep[Boolean] = x.toString
def repString(x: String): Rep[String] = x
}
object TestPatMat {
trait Prog extends Intf {
println("NOTE: doesn't work yet :-(")
def test = repInt(7) match { case 5 => "foo" case _ => "bar" }
println(test)
}
new Prog with Impl
}
$ ~/opt/scala-2.10.0-M6/bin/scalac -Xexperimental virtpatmat_staging-altered.scala
virtpatmat_staging-altered.scala:34: error: type mismatch;
found : Intf.this.Rep[Intf.this.Rep[Int]] => Intf.this.M[String]
required: Intf.this.Rep[Int] => Intf.this.M[?]
def test3(i: Rep[Int]) = i match { case j => "foo3: " + j } //type error!
^
one error found
//Copied from ./test/files/run/virtpatmat_staging.scala in the compiler sources
//for 2.10.0-M6.
import language.implicitConversions
import language.higherKinds
trait Intf {
type Rep[+T]
type M[+T]
val __match: MatchStrategy
abstract class MatchStrategy {
// runs the matcher on the given input
def runOrElse[T, U](in: Rep[T])(matcher: Rep[T] => M[U]): Rep[U]
def zero: M[Nothing]
def one[T](x: Rep[T]): M[T]
def guard[T](cond: Rep[Boolean], thenBranch: => Rep[T]): M[T]
def isSuccess[T, U](x: Rep[T])(f: Rep[T] => M[U]): Rep[Boolean] // used for isDefinedAt
}
abstract class Matcher[+A] {
def flatMap[B](f: Rep[A] => M[B]): M[B]
def orElse[B >: A](alternative: => M[B]): M[B]
}
implicit def proxyMaybe[A](m: M[A]): Matcher[A]
implicit def repInt(x: Int): Rep[Int]
implicit def repBoolean(x: Boolean): Rep[Boolean]
implicit def repString(x: String): Rep[String]
def test: Rep[String] = 7 match { case 5 => "foo" case _ => "bar" }
//def test2(i: Int) = i match { case j => "foo2: " + j }
def test2(i: Int): Rep[Int] = i match { case j => j }
def test3(i: Rep[Int]) = i match { case j => "foo3: " + j } //type error!
}
trait Impl extends Intf {
type Rep[+T] = String
type M[+T] = Rep[Matcher[T]]
object __match extends MatchStrategy {
def runOrElse[T, U](in: Rep[T])(matcher: Rep[T] => M[U]): Rep[U] = ("runOrElse("+ in +", ? =>" + matcher("?") + ")")
def zero: M[Nothing] = "zero"
def one[T](x: Rep[T]): M[T] = "one("+x.toString+")"
def guard[T](cond: Rep[Boolean], thenBranch: => Rep[T]): M[T] = "guard("+cond+","+thenBranch+")"
def isSuccess[T, U](x: Rep[T])(f: Rep[T] => M[U]): Rep[Boolean] = ("isSuccess("+x+", ? => " + f("?") + ")")
}
implicit def proxyMaybe[A](m: M[A]): Matcher[A] = new Matcher[A] {
def flatMap[B](f: Rep[A] => M[B]): M[B] = m + ".flatMap(? =>"+ f("?") +")"
def orElse[B >: A](alternative: => M[B]): M[B] = m + ".orElse("+ alternative +")"
}
def repInt(x: Int): Rep[Int] = x.toString
def repBoolean(x: Boolean): Rep[Boolean] = x.toString
def repString(x: String): Rep[String] = "\"%s\"" format x
}
object Test extends Impl with Intf with App {
println(test)
println(test2(2))
//println(test2(test2(2)))
//println(test3(3))
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment