48

Scala では、PartialFunction[A, B]クラスは型から派生しFunction[A, B]ます (Scala リファレンス、12.3.3 を参照)。ただし、これは直感に反するように思えます。なぜなら、 a Function(すべてに対して定義する必要があるA) は、場所によっては定義されていない可能性がある a よりも厳しい要件があるPartialFunctionからです。

私が遭遇した問題は、部分関数がある場合、 a を使用しFunctionて部分関数を拡張できないことです。例えば。できない:

(pf orElse (_)=>"default")(x)

(構文が少なくともリモートで正しいことを願っています)

このサブタイピングが逆に行われるのはなぜですか? Function型が組み込まれているなど、見落としている理由はありますか?

ところで、もしFunction1 :> Function0そうなら、上記の例で仮引数を必要としないのもいいでしょう:-)

サブタイプの問題を明確にするために編集

2 つのアプローチの違いは、2 つの例を見て強調することができます。どちらが正しいですか?

1:

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?
4

2 に答える 2

34

Scala では (他のチューリング完全言語と同様に) 関数が完全であるという保証がないからです。

val f = {x : Int => 1 / x}

その関数は 0 で定義されていません。PartialFunction は、定義されていない場所を示すことを約束する関数です。それでも、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 を暗黙的にすることができます。

于 2009-05-30T23:22:08.593 に答える