2015-05-20 7 views
7

Ich bin neu bei Scala Macros und ich verbrachte ein paar Tage damit, meine erste zu schreiben. Ich habe ein Problem mit der Quasiknotenverkettung.Scala Quasiquote Verkettung

Es gibt eine Liste von Fallklauseln, sagen wir mal folgendes:

val cases = cq"x => 1 " :: cq"_ => 0 " :: Nil 

Und ich brauche eine Teilfunktion daraus zu bauen. Das Problem ist, dass ich keine Ahnung habe, wie man sie in die letzte Quasiquote einfügt. Die Dokumentation sagt, dass ich etwas tun sollte:

q"{ case ..$cases }" 

aber es funktioniert nicht, wenn ich dies tun.

Gibt es eine Möglichkeit, aus einer solchen Liste eine PartialFunction zu erstellen?

Danke für jede Hilfe.

+0

Ich glaube, das ist der richtige Ansatz. Welchen Fehler hast du genau? – Odomontois

+0

Auch Ihr Muster ist ein bisschen seltsam 'x => 1' passt sich jedem Ausdruck an, wenn Sie auf einen lokalen Wert mit dem Namen' x' verweisen, sollten Sie '\' x \ '=> 1 als patern verwenden – Odomontois

+1

Der Fehler ist der folgende : Ausnahme bei Makroerweiterung: java.lang.IllegalArgumentException: scala.collection.immutable.List (case (x @ _) => 1, case _ => 0) ist keine gültige Repräsentation des Musterübereinstimmungsfalls. –

Antwort

2

Die folgenden Werke für mich mit 2.11.2:

import scala.reflect.macros.Context 
object Macros { 
    def partial: PartialFunction[Int, Int] = macro partialImpl 
    def partialImpl(c: Context): c.Expr[PartialFunction[Int, Int]]= { 
     import c.universe._ 
     val cases = cq"x => 1 " :: cq"_ => 0 " :: Nil 
     val pf = q"{ case ..$cases } : PartialFunction[Int, Int]" 
     c.Expr[PartialFunction[Int, Int]](pf) 

    } 
} 

Dann können Sie Macros.partial(1) nennen, zum Beispiel, oder Macros.partial.isDefinedAt(2).

Beachten Sie, dass, damit dies funktioniert, ich explizit PartialFunction[Int, Int] in der Quasi-Schrift q"{ case ..$cases } : PartialFunction[Int, Int]" verwenden musste. Es funktionierte nicht ohne die explizite Typdefinition (andernfalls wird angenommen PartialFunction[Any, Int]).

Here ist die Spezifikation für Quasi-Syntax für Teilfunktionen. Es funktioniert wie ein reiner Syntaxbaum, aber kann anscheinend nicht als ein typisierter Ausdruck interpretiert werden, außer PartialFunction[Any, T] von einem Makro, außer der Typ wird explizit gemacht.

+0

Pattern-Matching Anon-Funktionen können Funktion oder PartialFunction je nach dem erwarteten Typ sein. –

+0

Ihr Code hat einen Fehler: 'PartialFunction [Int, Int] {Fall ...}' erstellt eine PartialFunction, die für die gesamte Domäne definiert ist. Was Sie wollen, ist stattdessen '{case ...}: PartialFunction [Int, Int]' –

+0

True. Guter Fang. Fest. –