开发者

Shorten my code

My instinct says that the following code could be made shorter, but I 开发者_StackOverflow社区cannot figure how. Can you help me?

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
  }
}


Two tips here:

  1. As you need the Numeric instances named, it's easier to just de-sugar the context bounds into implicit arguments

  2. Use PartialFunction#lift to convert the PartialFunction[A,B] into an A => Option[B]

Then remove the boilerplate and... voila!

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

If you use a forward pipe operator (either from scalaz, or as defined here), then it can be made even more legible:

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

Update

As you're only converting ints/doubles, you don't actually need Numeric at all, you can do everything via java.util.Number, dropping the type params in the process:

def asGraphingFunction(f: PartialFunction[Number, _ <: Number]) =
  (x: Number) => f.lift(x.intValue) map (_.doubleValue) getOrElse 0.0


What about this?:

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
}

Not shorter but perhaps clearer?! Any comments?

0

上一篇:

下一篇:

精彩评论

暂无评论...
验证码 换一张
取 消

最新问答

问答排行榜