在Scala中,宏可以自然地进行链式比较吗?

时间:2012-11-19 08:51:49

标签: scala comparison syntactic-sugar scala-2.10 scala-macros

Scala不像Python那样提供链式比较:

// Python:
0 < x <= 3
// Scala:
0 < x && x <= 3

具有新宏功能的Scala 2.10能否让程序员编写一个添加此功能的库?或者这超出了Scala's macros的范围?

宏似乎是实现这种语法糖的正确选择,因为它们不会使解析器/编译器复杂化。

2 个答案:

答案 0 :(得分:6)

您不需要宏:

class ChainedComparisons[T : Ordering](val res: Boolean, right: T) {
  def <^ (next: T) = new ChainedComparisons(res && Ordering[T].lt(right, next), next)
  def <=^ (next: T) = new ChainedComparisons(res && Ordering[T].lteq(right, next), next)
}
implicit def chainedComparisonsToBoolean(c: ChainedComparisons[_]) = c.res

class StartChainedComparisons[T : Ordering](left: T) {
  def <^(right: T) = new ChainedComparisons(Ordering[T].lt(left, right), right)
  def <=^(right: T) = new ChainedComparisons(Ordering[T].lteq(left, right), right)
}
implicit def toStartChainedComparisons[T : Ordering](left: T) = new StartChainedComparisons(left)

用法:

scala> val x = 2
x: Int = 2

scala> 1 <^ x : Boolean
res0: Boolean = true

scala> 1 <^ x <^ 3 : Boolean
res1: Boolean = true

scala> 1 <^ x <^ 2 : Boolean
res2: Boolean = false

scala> 1 <^ x <=^ 2 : Boolean
res3: Boolean = true

scala> if (1 <^ x <^ 3) println("true") else println(false)
true

scala> 1 <=^ 1 <^ 2 <=^ 5 <^ 10 : Boolean
res5: Boolean = true

答案 1 :(得分:2)

我不认为Scala宏会在这里提供帮助......(如果我错了,请纠正我,Eugene肯定会检查这个)

宏只能应用于经过类型检查的AST (并且还会生成经过类型检查的AST)。这里的问题是表达式:

0 < x <= 3

评估为:(见another post

((0 < x) <= 3) // type error

<=(i: Int)中没有此类函数Boolean

我没有看到这种表达式编译的方法,因此宏无能为力。

当然,您可以使用自定义类来实现目标,但没有宏(如果需要,我可以给您一个示例),可能的语法可以是0 less x lesseq 3x between (0, 3)