scala仿函数以算术运算符为参数

时间:2018-01-29 16:04:46

标签: scala functor

我想将算术运算符+,*,/传递给Option monad。 我可以为(Double,Double) => Double

这样的函数math.pow执行此操作
scala> def parseOp2(o1:Option[Double], o2:Option[Double], op: (Double,Double) => Double): Option[Double] =
     |     (o1,o2) match {
     |       case (Some(d1), Some(d2)) => Some(op(d1,d2))
     |       case _ => None
     |     }
parseOp2: (o1: Option[Double], o2: Option[Double], op: (Double, Double) => Double)Option[Double]

scala> parseOp2(Some(2),Some(3),math.pow)
res39: Option[Double] = Some(8.0)

但是这些运营商的签名是什么。我试过了

def parseOp2(o1:Option[Double], o2:Option[Double], op: Double => Double): Option[Double] =
  (o1,o2) match {
    case (Some(d1), Some(d2)) => Some(d1.op(d2))
    case _ => None
  }

1 个答案:

答案 0 :(得分:0)

“运营商”本身没有签名/类型,例如

+

不是有效的Scala表达式。

您最接近的是:

(_ :Double) + (_: Double)

这个东西确实是一个有效的scala表达式,它的类型是(Double, Double) => Double

此外,如果您有一个可以推断出类型的上下文,那么您可以删除显式类型的归属,如下例所示:

def foo(f: (Double, Double) => Double): Unit = println(f(42,3141595))
def foo(_ + _) // no "(_:Double)" necessary here

_ + _表达式的类型将自动推断,它将再次为(Double, Double) => Double。顺便说一下,这适用于任意复杂的函数文字,而不仅仅适用于运算符。因此,例如,如果您像这样定义类Foo

case class Foo(i: Int) { def bar(d: Double) = i / d }

然后奇怪的构造(_: Foo) bar (_: Double)(_: Foo).bar(_: Double)的中缀形式,是(Foo, Double) => Double类型的有效scala表达式:

scala> (_: Foo) bar (_: Double)
res4: (Foo, Double) => Double = $$Lambda$1335/591589887@3303e89e

我希望能回答你的问题以及你问题的大部分可能修改。