我的直觉说下面的代码可以缩短,但我无法弄清楚如何。你能救我吗?
def asGraphingFunction[A : Numeric, B : Numeric](f: PartialFunction[A, B]): Double => Double = {
val (numericA, numericB) = (implicitly[Numeric[A]], implicitly[Numeric[B]])
(x: Double) => {
val xa: A = numericA.fromInt(x.toInt)
if(f.isDefinedAt(xa))
numericB.toDouble(f(xa))
else
0.0
}
}
答案 0 :(得分:7)
这里有两个提示:
由于您需要命名的Numeric
个实例,因此将上下文边界除去隐式参数更容易
使用PartialFunction#lift
将PartialFunction[A,B]
转换为A => Option[B]
然后移除样板并......瞧!
def asGraphingFunction[A, B](f: PartialFunction[A, B])
(implicit numA: Numeric[A], numB: Numeric[B]) =
(x: Double) => f.lift(numA fromInt x.toInt) map (numB.toDouble) getOrElse 0.0
如果你使用正向管道运算符(来自scalaz,或者定义为here),那么它可以变得更加清晰:
def asGraphingFunction[A, B](f: PartialFunction[A, B])
(implicit numA: Numeric[A], numB: Numeric[B]) =
(x: Double) => (numA fromInt x.toInt) |> f.lift map (numB.toDouble) getOrElse 0.0
<强>更新强>
由于您只是转换整数/双打,实际上根本不需要Numeric
,您可以通过java.util.Number
执行所有操作,在此过程中删除类型参数:
def asGraphingFunction(f: PartialFunction[Number, _ <: Number]) =
(x: Number) => f.lift(x.intValue) map (_.doubleValue) getOrElse 0.0
答案 1 :(得分:1)
这个怎么样?:
import scala.{ PartialFunction => PF }
def asGraphingFunction[A : Numeric, B : Numeric](f: PF[A, B]): Double => Double = {
val pf1: PF[Double,A ] = { case d => numericA.fromInt(d.toInt) }
val pf2: PF[B ,Double] = { case b => numericB.toDouble(b) }
val pf3: PF[Double,Double] = { case _ => 0 }
pf1 andThen f andThen pf2 orElse pf3
}
不短但可能更清楚?!有什么意见吗?