왜 partialfunction <: scala에서 기능인가?
-
06-09-2019 - |
문제
스칼라에서 PartialFunction[A, B]
클래스는 유형에서 파생됩니다 Function[A, B]
(스칼라 참조, 12.3.3 참조). 그러나 이것은 나에게 반 직관적 인 것 같습니다. Function
(모두를 위해 정의해야합니다 A
)는 a보다 더 엄격한 요구 사항이 있습니다 PartialFunction
, 일부 장소에서 정의되지 않을 수 있습니다.
내가 accross에 온 문제는 부분 기능이있을 때 사용할 수 없다는 것입니다. Function
부분 함수를 확장합니다. 예를 들어. 난 못해:
(pf orElse (_)=>"default")(x)
(구문이 최소한 원격으로 옳기를 바랍니다)
이 하위 유형이 왜 반대로 이루어 졌습니까? 내가 간과 한 이유가 있습니까? Function
유형이 내장되어 있습니까?
BTW, 그것은 또한 좋을 것입니다 Function1 :> Function0
그래서 나는 위의 예에서 더미 논쟁이 필요하지 않습니다 :-)
하위 유형 문제를 명확히하기 위해 편집하십시오
두 가지 방법의 차이점은 두 가지 예를 살펴보면 강조 할 수 있습니다. 그들 중 어느 것이 옳습니까?
하나:
val zeroOne : PartialFunction[Float, Float] = { case 0 => 1 }
val sinc = zeroOne orElse ((x) => sin(x)/x) // should this be a breach of promise?
둘:
def foo(f : (Int)=>Int) {
print(f(1))
}
val bar = new PartialFunction[Int, Int] {
def apply(x : Int) = x/2
def isDefinedAt(x : Int) = x%2 == 0
}
foo(bar) // should this be a breach of promise?
올바른 솔루션이 없습니다
다른 팁
스칼라에서 (모든 튜링 완전 언어에서와 같이) 함수가 총계라는 것을 보장 할 수는 없습니다.
val f = {x : Int => 1 / x}
이 함수는 0으로 정의되지 않습니다. 부분 기능은 정의되지 않은 위치를 알려주는 기능 일뿐입니다. 그래도 Scala는 원하는 것을 쉽게 할 수 있습니다.
def func2Partial[A,R](f : A => R) : PartialFunction[A,R] = {case x => f(x)}
val pf : PartialFunction[Int, String] = {case 1 => "one"}
val g = pf orElse func2Partial{_ : Int => "default"}
scala> g(1)
res0: String = one
scala> g(2)
res1: String = default
원하는 경우 func2partial 암시 적으로 만들 수 있습니다.
PartialFunction
방법이 있습니다 Function1
따라서 하위 유형이 아닙니다. 그 방법은 isDefinedAt
그리고 orElse
.
당신의 진짜 문제는 그 것입니다 PartialFunction
당신이 정말로 좋아할 때 때때로 추론되지 않습니다. 나는 미래에 다루어지기를 바랍니다. 예를 들어 이것은 작동하지 않습니다.
scala> val pf: PartialFunction[String, String] = { case "a" => "foo" }
pf: PartialFunction[String,String] = <function>
scala> pf orElse { case x => "default" }
<console>:6: error: missing parameter type for expanded function
((x0$1) => x0$1 match { case (x @ _) => "default" })
그러나 이것은 다음과 같습니다.
scala> pf orElse ({ case x => "default" } : PartialFunction[String,String])
res5: PartialFunction[String,String] = <function>
물론 항상 이것을 할 수 있습니다.
scala> implicit def f2pf[T,R](f: Function1[T,R]): PartialFunction[T,R] =
new PartialFunction[T,R] {
def apply(x: T) = f(x)
def isDefinedAt(x: T) = true
}
f2pf: [T,R](f: (T) => R)PartialFunction[T,R]
그리고 지금은 당신이 원하는 것과 같습니다.
scala> pf orElse ((x: String) => "default")
res7: PartialFunction[String,String] = <function>
scala> println(res7("a") + " " + res7("quux"))
foo default