2015-05-20 15 views
7

Jestem nowy w makrach scala i spędziłem kilka dni próbując napisać mój pierwszy. Mam problem z konkatenacją quasiquotes.Scala quasiquote konkatenacja

Istnieje lista klauzul case, powiedzmy, co następuje:

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

I muszę zbudować częściową funkcję z niego. Problem polega na tym, że nie mam pojęcia, jak je wkleić w końcowym quasiquote. Dokumentacja mówi, że powinniśmy zrobić coś takiego:

q"{ case ..$cases }" 

ale to nie działa, jeśli to zrobić.

Czy istnieje sposób na zbudowanie częściowej funkcji z takiej listy?

Dzięki za pomoc.

+0

Uważam, że to jest prawidłowe podejście. Jaki błąd masz dokładnie? – Odomontois

+0

Również twój wzorzec jest nieco dziwny 'x => 1' powoduje usunięcie dowolnego wyrażenia, jeśli odwołujesz się do lokalnej wartości o nazwie' x', powinieneś użyć '\' x \ '=> 1' jako patern – Odomontois

+1

Błąd jest następujący : wyjątek podczas rozszerzania makr: java.lang.IllegalArgumentException: scala.collection.immutable.List (case (x @ _) => 1, case _ => 0) nie jest poprawną reprezentacją wzorca dopasowania wzorca. –

Odpowiedz

2

następujące prace dla mnie 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) 

    } 
} 

Następnie można wywołać Macros.partial(1), na przykład, albo Macros.partial.isDefinedAt(2).

Należy zauważyć, że aby to działało, musiałem jawnie użyć PartialFunction[Int, Int] w quasiquote q"{ case ..$cases } : PartialFunction[Int, Int]". Nie działało bez jawnej definicji typu (w innym przypadku zakłada się PartialFunction[Any, Int]).

Here to specyfikacja quasiquote Składnia funkcji częściowych. Działa jak czyste drzewo składniowe, ale najwyraźniej nie może być interpretowane jako typowane wyrażenie z wyjątkiem PartialFunction[Any, T] przez makro, chyba że typ jest jawny.

+0

Wzory pasujące do funkcji anon mogą być Function lub PartialFunction w zależności od oczekiwanego typu. –

+0

Twój kod ma błąd: 'PartialFunction [Int, Int] {case ...}' utworzy PartialFunction, która jest zdefiniowana w całej domenie. Zamiast tego chcesz: '{case ...}: PartialFunction [Int, Int]' –

+0

True. Dobry połów. Naprawiony. –