Deena George
Deena George

Reputation: 11

Shorten my code

My instinct says that the following code could be made shorter, but I 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
  }
}

Upvotes: 1

Views: 214

Answers (2)

Kevin Wright
Kevin Wright

Reputation: 49695

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

Upvotes: 7

Peter Schmitz
Peter Schmitz

Reputation: 5844

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?

Upvotes: 1

Related Questions