最近,我看到了一款针对scala的新的一些 提及“虚拟化”模式匹配器。我错过了解释什么的备忘录.
发布于 2011-12-16 13:35:14
“虚拟化”模式匹配器是对现有匹配程序的重写。这样做的动机是支持多态嵌入式DSL的模式匹配虚拟化,而与2.10无关。
正如尤利安在下面的评论中所说:它非常类似于编译for-理解的方式:它们不是直接生成代码,而是被翻译成foreach__、map__、filter等。然后,模式匹配可以被转换成一系列方法调用,DSL可以覆盖这些调用。默认实现将尊重当前语义,而挑战在于使其与当前语义一样高效。看来阿德里安离这个目标很近了。“虚拟化”实现更简单,并且修复了当前实现中的几个bug。
“多态嵌入式DSL”的思想是,人们可以用scala编写不应该在JVM上运行的程序。也就是说,scalac将产生一个输出来描述程序正在做什么。然后,可以针对特定的体系结构重新编译。这样的事情,已经在ScalaDays上讨论过了。
这种重写最终将成为标准的scala模式匹配器。旧模式匹配器(据我理解)是不可维护的。
发布于 2013-05-13 16:19:21
可悲的是,现有的(唯一)答案在多汁的部分很少,评论上的链接也被打破了。所以让我试着在这里补充一些内容,因为,如果没有其他原因的话,当我决定在将来对它做一些事情的时候,我自己的参考,因为这个答案是在我做的每一个谷歌搜索之上。
如前所述,虚拟化模式匹配器是对Scala编译器处理模式匹配方式的重写。它有许多用途,其中的“虚拟化”部分意味着它是虚拟化scala工作的一部分。这种努力有点与宏相反:它需要在编译时“运行”的东西,然后移动到运行时。
例如,考虑到范围中存在适当的定义,这样的语句如下:
if (false) 1 else 2而不是编译到字节码分支和文字,甚至优化为文字"2",实际上被编译为以下语句:
__ifThenElse(false, 1, 2)有关更多信息和一些示例,请参阅scala虚拟化wiki以了解这些信息的用途。
然而,我说,模式匹配器重写有许多用途。另一个非常重要的目标是将意大利面代码,即旧的模式匹配器、完整的或特殊的、角落的情况和错误,转化为可以更容易地进行推理、扩展和改进的东西。这种重写修复了太多的问题,以至于人们刚刚浏览了问题列表,运行与模式匹配器相关的问题的示例代码,并在工作中将问题标记为“固定的”。它本身确实有新的but,但规模要小得多。
现在,关于新模式匹配器如何工作的信息非常少,但基本上,它转化为几个方法调用,这些调用在编译器中与Option monad一起“实现”。然后进入优化阶段,生成最优字节码。
引入您自己的matcher是可能的,尽管它被锁定在一个-Xexperimental标志后面。尝试以下代码,从Scala的测试套件中复制,并使用和不使用该标志:
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]
def test = 7 match { case 5 => "foo" case _ => "bar" }
}
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 Test extends Impl with Intf with App {
println(test)
}没有标志的结果正是您所期望的:
scala> Test.main(null)
bar然而,使用-Xexperimental,将编译替代匹配的"engine“:
scala> Test.main(null)
runOrElse(7, ?guard(false,?).flatMap(? =>one(foo)).orElse(one(bar)))另外,有关更多信息,请参见PatternMatching和MatchMonadInterface的标量。
免责声明:在2.10.0之后,从主分支上的Scala版本中提取并运行了上述内容,因此可能存在差异。然而,我发现自己很遗憾地缺乏一个纯粹的2.10.0或2.10.1环境来测试它。
https://stackoverflow.com/questions/8533826
复制相似问题