2011-12-16 2 views

답변

32

"가상화 된" 패턴 일치는 기존 matcher의 재 작성이다. 이 작업을 수행하는 동기는 다형성 임베디드 DSL에 대한 패턴 일치의 가상화를 지원하고 2.10과 관련이 없습니다. 울리 아래 코멘트에 말했듯이

가 : 그것은을 위해-함축 컴파일하는 방법과 매우 유사 : 대신 직접 코드를 생성, 그들은이 foreach로 번역되어, mapfilter 등 패턴 매칭은 다음 시리즈로 번역 될 수있다 DSL이 덮어 쓸 수있는 메소드 호출. 디폴트의 ​​구현은 현재의 시멘틱스를 존중 해, 현재의 시멘틱스만큼 효율적이되도록 (듯이)하는 것이 과제입니다. 아드리안이이 목표에 아주 가깝다. '가상화 된'구현은 더 간단하며 현재 구현에서 몇 가지 버그를 수정합니다.

"다형성 임베디드 DSL"은 JVM에서 실행되지 않아야하는 프로그램을 스칼라로 작성할 수있는 아이디어입니다. 즉, scalac은 프로그램이 수행중인 작업을 설명하는 출력을 생성합니다. 그런 다음 특정 아키텍처에 대해 다시 컴파일 할 수 있습니다. 그런 것 have been talked about at ScalaDays 2011.

이 재 작성은 결국 표준 스칼라 패턴 매처가됩니다. 오래된 패턴 일치자는 (이해할 수있는대로) 유지할 수 없다.

+0

"가상 패턴 매처가 패턴 매칭의 가상화를 지원하는 것"은 내가 짐작할 수없는 것이 아니었다. 가상화 패턴 일치가 실제로 무엇인지 설명 할 수 있습니까? –

+24

그것은 comprehensions이 컴파일되는 방법과 매우 비슷합니다. 코드를 직접 생성하는 대신 foreach, map, filter 등으로 변환됩니다. 패턴 일치는 일련의 메소드 호출로 변환 될 수 있으며, DSL 덮어 쓸 수 있습니다. 디폴트의 ​​구현은 현재의 시멘틱스를 존중 해, 현재의 시멘틱스만큼 효율적이되도록 (듯이)하는 것이 과제입니다. 아드리안이이 목표에 아주 가깝다. '가상화 된'구현은 더 간단하며 현재 구현에서 몇 가지 버그를 수정합니다. –

+0

안녕하세요 Iulian - 귀하의 의견에 "인정 된 답변"을 수여 할 수만 있다면! –

8

슬프게도 (유일한) 기존 답변은 수분이 많은 비트가 부족하며 해설에있는 링크는 깨졌습니다. 그래서 내가 여기에 어떤 주스를 추가하도록하겠습니다. 다른 이유가 없다면, 실제로 내 미래의 일을 결정할 때 내 자신의 참조,이 대답은 내가하는 모든 Google 검색 위에 있습니다.

가상화 패턴 일치 프로그램은 언급 한 것처럼 Scala 컴파일러가 패턴 일치를 처리하는 방법을 다시 작성한 것입니다. 그것은 "가상화"부분이 가상화 된 스칼라 작업의 일부라는 의미에서 많은 용도로 사용되었습니다. 이러한 노력은 매크로의 반대입니다. 컴파일 할 때 "실행"되고 실행 시간으로 이동합니다. 올바른 정의의 존재 범위를 이와 같이 문 주어진 예

:

if (false) 1 else 2 

대신 실제로 바이트 지점과 리터럴 컴파일 또는 리터럴 "2"로 최적화되고 다음 문으로 컴파일 된 가져옵니다

__ifThenElse(false, 1, 2) 

자세한 내용과이 유용 할 수있는 몇 가지 예에 대한 scala virtualized wiki를 참조하십시오.

그러나 패턴 일치자를 다시 작성하는 것은 많은 용도로 사용되었습니다. 또 다른 중요한 목표 중 하나는 이전 패턴 일치 알고리즘 인 스파게티 코드, 전체 또는 특수 및 모서리 케이스 및 버그를 추론 할 수 있고 확장 및 개선하기 쉬운 것으로 전환하는 것이 었습니다. 이는 많은 사람들이 수정 한 많은 문제로 인해 패턴 목록 작성자와 관련된 문제에 대한 샘플 코드를 실행하고 문제가 "고정 된"것으로 표시되는 문제 목록을 통과 한 것입니다. 그것은 새로운 버그를 가지고 있지만 훨씬 더 작은 규모입니다.

새 패턴 일치 프로그램이 작동하는 방식에 대한 정보는 거의 없지만 기본적으로 Option 모나드가있는 컴파일러에서 "구현 된"몇 가지 메서드 호출로 변환됩니다. 그런 다음 최적의 바이트 코드를 생성하는 최적화 단계로갑니다.

-Xexperimental 플래그 뒤에 고정되어 있지만 고유 한 정규 표현식을 도입 할 수 있습니다. 로 그 플래그없이 스칼라의 테스트 스위트에서 복사 한 다음 코드를 사용해보십시오 :

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) 
} 

플래그없이 결과는 당신이 기대하는 것입니다 : 그러나, -Xexperimental

scala> Test.main(null) 
bar 

의 대안 일치 "엔진"컴파일됩니다 :

scala> Test.main(null) 
runOrElse(7, ?guard(false,?).flatMap(? =>one(foo)).orElse(one(bar))) 

은, 자세한 내용은, 또한 PatternMatchingMatchMonadInterface에 대한 scaladocs를 참조하십시오.

면책 조항 : 위의 내용은 2.10.0 이후에 master 브랜치의 Scala 버전에서 추출되어 실행되었으므로 차이가있을 수 있습니다. 나는 슬프게도 순수한 2.10.0 또는 2.10.1 환경에서 그것을 테스트 할 수 없다는 것을 알게되었다.

관련 문제