2011-07-26 3 views
5

PartialFunction[A, B]과 같이 구체적인 함수 (예 : (A) => B)의 빠른 함수를 사용할 수 있습니까?콘크리트 스칼라 부분 함수들

(a: A) => a match { case obj => func(obj) } 

암시 적 변환이 어디 있습니까 같은 : 내가 아는 가장 간결한 구문은

implicit def funcAsPartial[A, B](func: A => B) = new PartialFunction[A, B] { 

    def isDefinedAt(a: A) = true 
    def apply(a: A) = func(a) 

} 

난 그냥 내가 찾던 쓴 생각하지만, 이것은 이미 존재 스칼라 라이브러리?

답변

5

(A) => BPartialFunction[A, B]에서 상속되어서는 안되는 동일한 이유로 인해 암시 적 변환으로이 작업을 수행하는 것은 위험합니다. 즉, PartialFunction의 계약에 따라 isDefinedAttrue을 반환 할 때 apply 번으로 안전하게 전화 할 수 있습니다. Function1의 계약은 그러한 보증을 제공하지 않습니다.

암시 적 변환으로 인해 부분적으로 정의되지 않은 함수에 적용하면 계약을 위반하는 부분 함수가 발생합니다. 대신, 변환이 명시 적으로 확인하기 위해 포주를 사용 주석에서 설명하고있는 바와 같이

implicit def funcAsPartial[A, B](f: A => B) = new { 
    /** only use if `f` is defined everywhere */ 
    def asPartial(): PartialFunction[A, B] = { 
     case a => f(a) 
    } 

    def asPartial(isDefinedAt: A => Boolean): PartialFunction[A, B] = { 
     case a if isDefinedAt(a) => f(a) 
    } 
} 

// now you can write 
val f = (i: Int) => i * i 

val p = f.asPartial // defined on all integers 
val p2 = f.asPartial(_ > 0) // defined only on positive integers 

*이, "안전"여기에 무엇을 의미하는지 완전히 명확하지 않을 수 있습니다. 필자가 생각하는 방식은 PartialFunction이 다음과 같은 정확한 의미로 도메인을 명시 적으로 선언한다는 것입니다. isDefinedAt이 값 x에 대해 true를 반환하면 apply(x)을 함수 작성자의 의도와 일치하는 방식으로 평가할 수 있습니다. 그 이 아니기 때문에 apply(x)은 예외를 던지지 않을 것이지만 단지 그 예외가 기능 설계의 일부분이었고 (문서화되어야 함).

+0

감사합니다. Function1이 전체 도메인에서 정의된다는 암시가있었습니다. –

+0

@AaronNovstrup : PartialFunction의 계약에 대한 설명은 의미가 있지만 ScalaDocs에 반영되지 않았습니다 (최소 2.9.1까지). 'PartialFunction'의 ScalaDocs는 다음과 같이 주장합니다. "PartialFunction [A, B] 유형의 부분 함수는 도메인이 반드시 모든 유형의 'A' 값을 포함하지는 않는 단항 함수입니다." 더욱이, 그들은 정의 된 곳 어디에서나 f를 호출하는 것이 안전하다고 (어떤 의미로)'PartialFunction' 리터럴'{case 0 => 1/0}'에 의해 행해진 것처럼 위반하기 쉽습니다. 어디서 정보를 얻었습니까? 버그 신고서를 제출해야합니까? – Blaisorblade

+0

@ 블레어 블레이드 나는 스칼라를 배웠을 때 메일 링리스트에서이 설명을 읽었다 고 생각한다. (나는 그동안 스칼라를 배웠다.) 나는이 대답을 쓸 때 어떤 문서도보고 있지 않았다. 그리고 예,이 계약을 위반하는 것이 쉽습니다 (예 : catch 블록에서 예외를 감싸거나 재발행하는 것). 진정한 요점은 PartialFunctions가 도메인을 정의하지만 일반 함수는 그렇지 않다는 것입니다 (실제로 의미하는 바가 일부 있음). –

0

아니요, 몇 달 전에 하나를 찾으려고했는데 결국 내 자신의 글을 쓰는 것이 본질적으로 당신 것과 같습니다.

+0

'(A) => B는'PartialFunction [A, B]'에서 상속해야한다고 생각합니다. –

+1

나는 그 (전체) 함수가 어디에서나 정의되는 부분 함수 (isDefinedAt (x) = true)라는 사실에 동의합니다. 그러나 마틴 오데 스키 (Martin Odersky)는 기능이 전체 기능으로 보장되지는 않는다고 말하면서, 도메인이 문서화되어 있지 않다는 것입니다. 따라서 PartialFunction은 도메인을 문서화하는 함수입니다. –

+0

http://www.scala-lang.org/node/2750 –