【问题标题】:Can this be done with Scala macros?这可以用 Scala 宏来完成吗?
【发布时间】:2015-03-11 00:07:43
【问题描述】:

我想知道这是否可以用 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 宏,这也可能是不可能的,不是吗?

如果是这样,我从哪里开始?我认为这不是一个简单的宏...

【问题讨论】:

  • 如果doSomething 是一个宏,应该可以启用这个语法。宏可以将doSomething(foo == "X") 转换为doSomething{x => import x._; foo == "X"}
  • 好的,我会尝试深入研究。是否有关于我可以使用的宏的最新资源?
  • 嗯...我认为不可能,我需要匹配一个可以递归的未知结构(有没有办法匹配一个“不能真正编译的任意布尔表达式? ")
  • 好的,一个方向是通过符号...从 2.11 开始,您可以将名称参数用于宏。所以它可能是可行的,但不确定是否值得努力:)
  • 是的,为了使doSomething(foo == "X") 扩展,foo == "X" 首先需要类型正确。

标签: scala scala-macros


【解决方案1】:

你说得对,必须引入标识符。

MetaplasmTravis Brown 在他最丑陋的代码和最糟糕的双关语中称它为"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:https://stackoverflow.com/a/16256935/1296806

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2013-04-27
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2016-12-12
    相关资源
    最近更新 更多