缩短我的代码

时间:2011-03-08 09:03:08

标签: 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
  }
}

2 个答案:

答案 0 :(得分:7)

这里有两个提示:

  1. 由于您需要命名的Numeric个实例,因此将上下文边界除去隐式参数更容易

  2. 使用PartialFunction#liftPartialFunction[A,B]转换为A => Option[B]

  3. 然后移除样板并......瞧!

    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
}

不短但可能更清楚?!有什么意见吗?