2013-03-06 12 views
5

In risposta a this question, ho iniziato a implementare un'espressione 'dove' in stile Haskell in Scala utilizzando il ramo macro-paradiso. Il codice è disponibile allo scala-where. Ora posso scrivere qualcosa di simile al seguente:Macro non tipizzata Scala in infisso posizione

val result = where (f1(1) * f2(2), { 
    def f1(x : Int) = x + 1 
    def f2(x : Int) = x + 2 
}) 

Tuttavia, quello che mi piacerebbe davvero fare è di essere in grado di chiamare questo in posizione infisso:

val result = (f1(1) * f2(2)) where { 
    def f1(x : Int) = x + 1 
    def f2(x : Int) = x + 2 
} 

Normalmente, questo genere di cose sarebbe facile, ma non riesco a vedere come farlo con la macro chiamata. L'espressione (f1 (1) * f2 (2)) non verrà digitata prima dell'applicazione macro, quindi qualcosa come la creazione di una classe di valore implicita non funziona. C'è un modo per ottenere questo tipo di sintassi altrimenti?

In mancanza di questo, basta avere due liste di parametri e quindi si può fare:

val result = where (f1(1) * f2(2)) { 
    def f1(x : Int) = x + 1 
    def f2(x : Int) = x + 2 
} 

sarebbe bello, ma anche questo sembra difficile. Si può chiamare una macro con due liste di parametri?

risposta

2

Per la prima opzione: penserei che potresti convertire la conversione implicita in una macro non tipizzata, no?

Per la seconda opzione: è possibile chiamare una macro con più elenchi di parametri, sì. Più elenchi sul sito chiamata si tradurrà in più elenchi presso il sito di definizione, ad esempio:

def myMacro(a: _)(b: _) = macro myMacro_impl 

def myMacro_impl(c: Context)(a: c.Tree)(b: c.Tree): c.Tree = { ... } 

sarebbe chiamato come:

myMacro(...)(...) 
+1

Due parametro cosa è grande, grazie! In qualche modo l'avevo perso. – Impredicative

+1

Per quanto riguarda la conversione implicita, non sono sicuro di come ottenere l'hook nel sistema macro. Non penso che possa essere una conversione implicita, dal momento che sicuramente l'albero deve essere stato digitato per cercare le conversioni? – Impredicative

+0

Forse hai ragione, anche se penserei che saresti in grado di fare 'implicit def conv = macro conv_impl; def conv_impl (c: Context) (x: c.Tree): c.Expr [T] 'e deve essere essenzialmente di tipo' Any => T' –

1

Risposta: a partire dal 2013/03/08, non è possibile utilizzare macro non tipizzate in una posizione infissa. Citato da Eugene Burmako sul scala-user mailing list:

Attualmente l'argomento a sinistra deve essere typechecked prima eventuali calci di risoluzione implicita nel fatto che si può scrivere "class foo (x: _)". È una svista - la sintassi di sottolineatura dovrebbe essere che funziona solo in macro non tipizzate.

Per riferimento, il più vicino sono venuto ad essere in grado di fare questo è stato il seguente: lista

implicit class HasWhere(val exp : _) { 
def where(block : Unit) = macro whereInfix 
} 

def whereInfix(c : Context)(block : c.Expr[Unit]) = { 
    import c.universe._ 

    val exp = Select(c.prefix.tree, TermName("exp")) 
    val Expr(Block((inner, _))) = block 
    val newinner = inner :+ exp 
    Block(newinner : _*) 
} 
Problemi correlati