/ / स्कैला, क्वाला, मैक्रोज़, स्कैला-मैक्रोज़, स्कैला-क्वासिकोट्स में क्वासिकोट्स के साथ मिलान फ़ंक्शन अक्षर

स्कैला, क्वाला, मैक्रोज़, स्कैला-मैक्रोज़, स्कैला-क्वासिकोट्स में क्वासिकोट्स के साथ मिलान फ़ंक्शन अक्षर

यह सवाल मेरे लिए प्रेरणा में समान है पिछले सवाल (हालांकि यह एक समस्या के बारे में है मैं एक में भाग गया अलग संदर्भ)।

मैं quasiquotes के बिना आसानी से एक समारोह शाब्दिक पर पैटर्न मिलान कर सकते हैं:

import scala.reflect.macros.Context
import scala.language.experimental.macros

object QQExample {
def funcDemo(f: Int => String) = macro funcDemo_impl
def funcDemo_impl(c: Context)(f: c.Expr[Int => String]) = {
import c.universe._

f.tree match {
case Function(ps, body) => List(ps, body) foreach println
case _ => c.abort(
c.enclosingPosition,
"Must provide a function literal."
)
}

c.literalUnit
}
}

इस तरह कौन सा काम करता है:

scala> QQExample.funcDemo((a: Int) => a.toString)
List(val a: Int = _)
a.toString()

अब मान लीजिए कि मैं एक ही तरह के मैच को और अधिक लचीला रूप से करने के लिए quasiquotes का उपयोग करना चाहता हूं। निम्नलिखित उस समारोह पर भी मेल खाता है, और प्रिंट करता है जिसे हम उम्मीद करते हैं।

case q"($x: $t) => $body" => List(x, t, body) foreach println

लेकिन अगर मैं पैटर्न में टाइप निर्दिष्ट करना चाहता हूं, तो यह मेल नहीं खाता है:

case q"($x: Int) => $body" => List(x, body) foreach println

और इनमें से कोई भी संकलित नहीं है:

case q"$p => $body"      => List(p,  body) foreach println
case q"($p) => $body"    => List(p,  body) foreach println
case q"..$ps => $body"   => List(ps, body) foreach println
case q"(..$ps) => $body" => List(ps, body) foreach println

क्या quasiquotes के साथ फ़ंक्शन शाब्दिक पर मिलान करते समय पैरामीटर के प्रकार को निर्दिष्ट करना संभव है, या पैरामीटर की अज्ञात संख्या से मिलान करना संभव है?

उत्तर:

उत्तर № 1 के लिए 4

2.10 के लिए नवीनतम स्वर्ग प्लगइन के साथ और वेनिला 2.11 में आप इसे इस तरह से कर सकते हैं:

val q"(..$args) => $body" = f.tree

मैंने अभी इसका परीक्षण किया है स्वर्ग उदाहरण परियोजना निम्नलिखित के साथ Macros.scala:

import language.experimental.macros
import scala.reflect.macros.Context

object Macro {
def apply(f: Any): Any = macro impl
def impl(c: Context)(f: c.Expr[Any]) = { import c.universe._
val q"(..$args) => $body" = f.tree
println(s"args = $args, body = $body")
c.Expr(q"()")
}
}

तथा Test.scala:

object Test extends App {
Macro((x: Int) => x + 1)
}

आप quasiquotes के साथ समारोह पेड़ों को संभालने के बारे में और अधिक पढ़ सकते हैं quasiquote गाइड के संबंधित अध्याय.