首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >scala的实验虚拟模式匹配器是什么?

scala的实验虚拟模式匹配器是什么?
EN

Stack Overflow用户
提问于 2011-12-16 11:59:10
回答 2查看 2.7K关注 0票数 43

最近,我看到了一款针对scala的新的一些 提及“虚拟化”模式匹配器。我错过了解释什么的备忘录.

EN

回答 2

Stack Overflow用户

回答已采纳

发布于 2011-12-16 13:35:14

“虚拟化”模式匹配器是对现有匹配程序的重写。这样做的动机是支持多态嵌入式DSL的模式匹配虚拟化,而与2.10无关。

正如尤利安在下面的评论中所说:它非常类似于编译for-理解的方式:它们不是直接生成代码,而是被翻译成foreach__、map__、filter等。然后,模式匹配可以被转换成一系列方法调用,DSL可以覆盖这些调用。默认实现将尊重当前语义,而挑战在于使其与当前语义一样高效。看来阿德里安离这个目标很近了。“虚拟化”实现更简单,并且修复了当前实现中的几个bug。

“多态嵌入式DSL”的思想是,人们可以用scala编写不应该在JVM上运行的程序。也就是说,scalac将产生一个输出来描述程序正在做什么。然后,可以针对特定的体系结构重新编译。这样的事情,已经在ScalaDays上讨论过了

这种重写最终将成为标准的scala模式匹配器。旧模式匹配器(据我理解)是不可维护的。

票数 32
EN

Stack Overflow用户

发布于 2013-05-13 16:19:21

可悲的是,现有的(唯一)答案在多汁的部分很少,评论上的链接也被打破了。所以让我试着在这里补充一些内容,因为,如果没有其他原因的话,当我决定在将来对它做一些事情的时候,我自己的参考,因为这个答案是在我做的每一个谷歌搜索之上。

如前所述,虚拟化模式匹配器是对Scala编译器处理模式匹配方式的重写。它有许多用途,其中的“虚拟化”部分意味着它是虚拟化scala工作的一部分。这种努力有点与宏相反:它需要在编译时“运行”的东西,然后移动到运行时。

例如,考虑到范围中存在适当的定义,这样的语句如下:

代码语言:javascript
复制
if (false) 1 else 2

而不是编译到字节码分支和文字,甚至优化为文字"2",实际上被编译为以下语句:

代码语言:javascript
复制
__ifThenElse(false, 1, 2)

有关更多信息和一些示例,请参阅scala虚拟化wiki以了解这些信息的用途。

然而,我说,模式匹配器重写有许多用途。另一个非常重要的目标是将意大利面代码,即旧的模式匹配器、完整的或特殊的、角落的情况和错误,转化为可以更容易地进行推理、扩展和改进的东西。这种重写修复了太多的问题,以至于人们刚刚浏览了问题列表,运行与模式匹配器相关的问题的示例代码,并在工作中将问题标记为“固定的”。它本身确实有新的but,但规模要小得多。

现在,关于新模式匹配器如何工作的信息非常少,但基本上,它转化为几个方法调用,这些调用在编译器中与Option monad一起“实现”。然后进入优化阶段,生成最优字节码。

引入您自己的matcher是可能的,尽管它被锁定在一个-Xexperimental标志后面。尝试以下代码,从Scala的测试套件中复制,并使用和不使用该标志:

代码语言:javascript
复制
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)
}

没有标志的结果正是您所期望的:

代码语言:javascript
复制
scala> Test.main(null)
bar

然而,使用-Xexperimental,将编译替代匹配的"engine“:

代码语言:javascript
复制
scala> Test.main(null)
runOrElse(7, ?guard(false,?).flatMap(? =>one(foo)).orElse(one(bar)))

另外,有关更多信息,请参见PatternMatchingMatchMonadInterface的标量。

免责声明:在2.10.0之后,从主分支上的Scala版本中提取并运行了上述内容,因此可能存在差异。然而,我发现自己很遗憾地缺乏一个纯粹的2.10.0或2.10.1环境来测试它。

票数 8
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/8533826

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档