機能Scalaで:なぜ、部分写像<ですか?
-
06-09-2019 - |
質問
Scalaで、PartialFunction[A, B]
クラスは、(スカラ参照、12.3.3を参照)型Function[A, B]
由来します。 (すべてのFunction
のために定義する必要があります)A
は、いくつかの場所で未定義することができPartialFunction
、より厳しい要件を持っているのでしかし、これは、私には直感に反するようです。
私はaccrossに来ました問題は、私は部分的な機能を持っているとき、私は一部の機能を拡張するFunction
を使用することはできませんということでした。例えば。私が行うことはできません。
(pf orElse (_)=>"default")(x)
(ホープ構文は、少なくともリモート右)
なぜ、このサブタイプが逆に行われますか?私はFunction
タイプが内蔵されているという事実のように、見落としてきた任意の理由がありますか?
Function1 :> Function0
はので、私は上記の例の仮引数を持っている必要がない場合は、ところで、それもいいだろう: - )
編集がサブタイプの問題を明確にするために、
2つのアプローチの違いは、2つの例を見ることによって強調することができます。それらのどちらが正しいのですか?
ワンます:
val zeroOne : PartialFunction[Float, Float] = { case 0 => 1 }
val sinc = zeroOne orElse ((x) => sin(x)/x) // should this be a breach of promise?
2:
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?
正しい解決策はありません
他のヒント
(任意のチューリング完全な言語のように)Scalaで機能が合計であるという保証はありませんので。
val f = {x : Int => 1 / x}
この関数は0 A部分写像で定義されていませんが、それが定義されていないところを教えてくれと約束するだけの機能です。それでも、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
sは時々推測されていないということです。私はいくつかの将来の日付で対処されることになります期待しています。例えば、これは動作しません。
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