(A) => B
から継承してはならないのと同じ理由で、暗黙の変換でこれを行うのは危険PartialFunction[A, B]
です。つまり、PartialFunctionのコントラクトは、apply
どこisDefinedAt
に戻っても安全に*呼び出すことができることを保証しますtrue
。Function1の契約はそのような保証を提供しません。
暗黙の変換は、どこでも定義されていない関数に適用すると、そのコントラクトに違反するPartialFunctionになります。代わりに、ポン引きを使用して変換を明示的にします。
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
trueを返す場合、関数の作成者の意図と一致する方法で評価できます。これは、例外がスローされないことを意味するのではなく、単に例外が関数の設計の一部であったことを意味します(文書化する必要があります)。x
apply(x)
apply(x)