Scala宏可以做到这一点吗?

Scala宏可以做到这一点吗?,scala,scala-macros,Scala,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:

我想知道这是否可以用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)为:

我的假设是,即使使用Scala宏,这也可能是不可能的,或者是吗


如果是,我从哪里开始?我假设这不是一个简单的宏…

必须引入标识符是正确的

用他最丑陋的代码和最糟糕的双关语,称之为。宏引入语法机制,该机制在使用(或滥用)之前导入

如果属性名只是任意数据,则Potemkin定义可能不适合您的用例

可能是这样收集语法,然后宏可以对其进行操作(与此处的快速转换相反)


直到今天早些时候看到这一点,我才开始考虑动态:

如果
doSomething
是一个宏,那么应该可以启用此语法。宏可以将
doSomething(foo==“X”)
转换为
doSomething{X=>import X.。\uuu;foo==“X”}
好的,我会尝试深入研究。有一个很好的最新的资源在宏我可以使用吗?嗯。。。我认为这是不可能的,我需要匹配一个可以递归的未知结构(有没有办法匹配“无法真正编译的任意布尔表达式?”)好的,一个方向是通过符号。。。从2.11开始,您可以使用“按名称”参数来创建宏。因此,这可能是可行的,但不确定是否值得付出努力:)是的,为了扩展
doSomething(foo==“X”)
foo==“X”
首先需要输入正确的类型。
doSomething(foo == "X" && bar  == "Y" || baz.nonEmpty)
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")
}