1 scala
我的直觉说下面的代码可以缩短,但我无法弄清楚如何.你能帮助我吗?
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
}
}
Run Code Online (Sandbox Code Playgroud)
这里有两个提示:
当您需要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
Run Code Online (Sandbox Code Playgroud)
如果您使用正管道操作符(无论是从scalaz,或定义在这里),那么就可以变得更加清晰:
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
Run Code Online (Sandbox Code Playgroud)
更新
由于你只是转换整数/双数,你实际上根本不需要Numeric,你可以做任何事情java.util.Number,在这个过程中删除类型参数:
def asGraphingFunction(f: PartialFunction[Number, _ <: Number]) =
(x: Number) => f.lift(x.intValue) map (_.doubleValue) getOrElse 0.0
Run Code Online (Sandbox Code Playgroud)