2011-03-08 6 views
1

본능은 다음 코드를 더 짧게 만들 수 있다고 말하지만 어떻게 설명 할 수는 없습니다. 나 좀 도와 줄 수있어? 어떤이에 대한내 코드 단축

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

저는 스칼라에 대해 알지 못합니다 만, 왜 코드를 "더 짧게"만드려고하는지 특별한 이유가 있습니까? 그것은 나에게 상당히 읽을 수있는 것처럼 보입니다. 코드 줄 수보다 중요하지 않습니까? –

+0

@ 마이클 - 그들은 손에 손을 잡고,이 내 대답을 참조하십시오 –

답변

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 
} 

하지 짧은 그러나 아마 명확

을? :?! 다른하실 말씀 있나요? 여기

7

두 팁 :

  1. 당신이라는 Numeric 인스턴스를 필요로하는, 그것은

  2. 사용 PartialFunction#liftA => Option[B]PartialFunction[A,B]를 변환 할 상황이 암시 인수

    에 경계 단지 해제 설탕보다 쉽게

그런 다음 상용구를 제거하고 ... voila! 당신이 (here 정의 중 하나 scalaz에서, 또는으로) 앞으로 파이프 연산자를 사용하는 경우

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 

, 그것은 훨씬 더 읽기 쉽게 만들 수 있습니다 :

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 

업데이트

당신이로 int/double을 변환하는 것만으로도 실제로는 Numeric이 필요하지 않습니다. java.util.Number을 통해 모든 작업을 수행 할 수 있습니다.이 과정에서 형식 매개 변수를 삭제합니다.

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

좋은! 내 접근 방식보다 낫다. 투표하세요! :디 –