如何将 > < <= >= 作为函数使用?

6

我需要定义一些类似以下的案例类:

case class Gt(key: String, value: Any) extends Expression {
  def evalute[V, E](f: String => Any) = {
    def compare(v: Any): Boolean = {
      v match {
        case x: Number => x.doubleValue > value.asInstanceOf[Number].doubleValue
        case x: Array[_] => x.forall(a => compare(a))
        case x => x.toString > value.toString
      }
    }
    compare(f(key))
  }
}

我不喜欢反复使用 >、<、>= 和 <= 这些符号。

我也尝试了以下方法:

trait Expression {
  def evalute[V, E](f: String => Any) = true

  def compare(v: Any, value: Any, cp: (Ordered[_], Ordered[_]) => Boolean): Boolean = {
    v match {
      case x: Number => cp(x.doubleValue, value.asInstanceOf[Number].doubleValue)
      case x: Array[_] => x.forall(a => compare(a, value, cp))
      case x => cp(x.toString, value.toString)
    }
  }
}
case class Gt(key: String, value: Any) extends Expression {
  def evalute[V, E](f: String => Any) = {
    compare(f(key), value, ((a, b) => a > b))
  }
}

但是那个不起作用 :(
error: could not find implicit value for parameter ord: scala.math.Ordering[scala.math.Ordered[_ >: _$1 with _$2]]
compare(f(key), value, ((a, b) => a > b))

在Scala中是否有一种方法可以将运算符作为函数传递?


你能否提供一些关于为什么你认为需要那个 case class 的想法?几乎肯定有更好的解决方案来实现你想要的目标,但是如果没有了解你的预期使用场景,就无法知道哪种方案更好。 - Kevin Wright
3个回答

6

(a, b) => a > b 可以正常工作。你的问题在于类型。

  1. evalute[V, E] 中的 VE 应该是什么?

  2. 你将 (a, b) => a > b 作为参数 cp: (Ordered[_], Ordered[_]) => Boolean 传递。因此,你有 a: Ordered[_]b: Ordered[_]。这与 a: Ordered[X] forSome {type X}b: Ordered[Y] forSome {type Y} 相同。对于这些类型,a > b 没有意义。


是的,你说得对。[V,E]在这里是无用的,我忘记把它们删除了。 实际上,我想在运行时比较两个任意值。 - spacedragon
你不能这样做,因为Any无法转换为Ordered[Any],而且>Ordered的一个方法。 - Alexey Romanov
谢谢。我将为每个运算符重复第一种方法。 - spacedragon

0
在Scala中,它们不是运算符,而是方法。您可以通过在其后加下划线将任何方法提升为函数。例如:
Welcome to Scala version 2.8.0.final (Java HotSpot(TM) Client VM, Java 1.6.0_21).
Type in expressions to have them evaluated.
Type :help for more information.

scala> val f: (Int => Boolean) = 1 <= _
f: (Int) => Boolean = <function1>

scala> (0 to 2).map(f)
res0: scala.collection.immutable.IndexedSeq[Boolean] = Vector(false, true, true)

我知道它们是方法,但似乎这些方法(>,<等)不能像普通方法一样作为参数传递。 - spacedragon

0

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接