这可以用 Scala 宏来完成吗?
Can this be done with Scala macros?
我想知道这是否可以用 scala 宏来完成
考虑这个方法:
def doSomething(filter: Item => Boolean) = ...
class Item(properties: Map[String, String]) extends Dynamic {
def selectDynamic(name:String): String = {
properties.getOrElse(name, "")
}
def updateDynamic(name: String)(value: String): Unit = {
addProperty(name, value)
}
}
还有这个用法
doSomething(x=> x.foo == "X" && x.bar == "Y" || x.baz.nonEmpty)
我想做的是将它简化(我正在为那些不太使用 scala 的人编写 DSL)到这个:
doSomething(foo == "X" && bar == "Y" || baz.nonEmpty)
我的假设是,即使使用 Scala 宏,这也可能是不可能的,是吗?
如果是这样,我从哪里开始?我认为这不是一个简单的宏...
你说得对,必须引入标识符。
在他最丑陋的代码和最糟糕的双关语 Metaplasm, Travis Brown called it "Potemkin val-age" 中。宏介绍语法机制,在使用(或滥用)之前导入。
如果您的 属性 名称只是任意数据,Potemkin 定义可能不适合您的用例。
也许像这样收集语法,然后宏可以对其进行操作(与这里的快速转换相反)。
case object is
object when extends Dynamic {
def applyDynamic(f: String)(op: Any) = new P(f, op)
}
case class P(f: String, op: Any) extends Dynamic {
def applyDynamic(op: String)(value: String) = Q(this, op, value)
}
case class Q(p: P, op: String, value: String)
object Test extends App {
implicit def `Q to filter`(q: Q): Item => Boolean = (i: Item) => (q.p.op, q.op) match {
case (is, "equal") => i.properties.get(q.p.f) map (_ == q.value) getOrElse false
case _ => false
}
val items = List (
Item(Map("foo" -> "X", "bar" -> "Y")),
Item(Map("this" -> "that")),
Item(Map("baz" -> "more"))
)
def doSomething(filter: Item => Boolean) = Console println (items filter filter)
doSomething(when foo is equal "X")
}
直到今天早些时候看到这个,我才开始考虑 Dynamic:
我想知道这是否可以用 scala 宏来完成
考虑这个方法:
def doSomething(filter: Item => Boolean) = ...
class Item(properties: Map[String, String]) extends Dynamic {
def selectDynamic(name:String): String = {
properties.getOrElse(name, "")
}
def updateDynamic(name: String)(value: String): Unit = {
addProperty(name, value)
}
}
还有这个用法
doSomething(x=> x.foo == "X" && x.bar == "Y" || x.baz.nonEmpty)
我想做的是将它简化(我正在为那些不太使用 scala 的人编写 DSL)到这个:
doSomething(foo == "X" && bar == "Y" || baz.nonEmpty)
我的假设是,即使使用 Scala 宏,这也可能是不可能的,是吗?
如果是这样,我从哪里开始?我认为这不是一个简单的宏...
你说得对,必须引入标识符。
在他最丑陋的代码和最糟糕的双关语 Metaplasm, Travis Brown called it "Potemkin val-age" 中。宏介绍语法机制,在使用(或滥用)之前导入。
如果您的 属性 名称只是任意数据,Potemkin 定义可能不适合您的用例。
也许像这样收集语法,然后宏可以对其进行操作(与这里的快速转换相反)。
case object is
object when extends Dynamic {
def applyDynamic(f: String)(op: Any) = new P(f, op)
}
case class P(f: String, op: Any) extends Dynamic {
def applyDynamic(op: String)(value: String) = Q(this, op, value)
}
case class Q(p: P, op: String, value: String)
object Test extends App {
implicit def `Q to filter`(q: Q): Item => Boolean = (i: Item) => (q.p.op, q.op) match {
case (is, "equal") => i.properties.get(q.p.f) map (_ == q.value) getOrElse false
case _ => false
}
val items = List (
Item(Map("foo" -> "X", "bar" -> "Y")),
Item(Map("this" -> "that")),
Item(Map("baz" -> "more"))
)
def doSomething(filter: Item => Boolean) = Console println (items filter filter)
doSomething(when foo is equal "X")
}
直到今天早些时候看到这个,我才开始考虑 Dynamic: