tags:

views:

135

answers:

3

I need define some case classes like the following one:

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))
  }
}

i don't like repeat that for > < >= and <=

i also tried this:

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))
  }
}

but that not working :(

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))

Is there a way that pass a operator as a function in scala?

A: 

I'm not familiar with Scala, ut does seem to have support for anonymous functions/lambdas: http://www.scala-lang.org/node/133

Mark LeMoine
A: 

In Scala, those are not operators, but methods. You can lift any method to a function by putting an underscore after it. e.g.

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)
Synesso
I know they are methods, but it seems those methods(>,<,etc) can't be passed as parameters like normal methods
spacedragon
+5  A: 

(a, b) => a > b works fine. Your problem is with the types.

  1. What are V and E in evalute[V, E] supposed to be?

  2. You pass it (a, b) => a > b as the parameter cp: (Ordered[_], Ordered[_]) => Boolean. So you have a: Ordered[_] and b: Ordered[_]. Which is the same as a: Ordered[X] forSome {type X} and b: Ordered[Y] forSome {type Y}. With these types, a > b doesn't make sense.

Alexey Romanov
Yes ,you are right. [V,E] are useless here, i forgot remove them.Actually I want compare two Any value on runtime ,
spacedragon
You can't, because `Any` can't be converted to `Ordered[Any]` and `>` is a method on `Ordered`.
Alexey Romanov
Thanks. I'll just repeat the first way for each operator.
spacedragon