缩短我的代码

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)

Kev*_*ght 7

这里有两个提示:

  1. 当您需要Numeric命名的实例时,将上下文绑定到隐式参数中更容易

  2. 使用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)