5

として具体的な関数(たとえば、タイプ(A) => B)として使用する簡単な方法はありますPartialFunction[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)

}

探していたものを書いたばかりだと思いますが、これはすでにScalaライブラリに存在しますか?

4

2 に答える 2

5

(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は次の正確な意味でそのドメインを明示的に宣言します。値に対してisDefinedAttrueを返す場合、関数の作成者の意図と一致する方法で評価できます。これは、例外がスローされないことを意味するのではなく、単に例外が関数の設計の一部であったことを意味します(文書化する必要があります)。xapply(x)apply(x)

于 2011-07-26T20:14:38.700 に答える
0

いいえ、私は数ヶ月前にそれを見つけようとしましたが、本質的にあなたのものと同じものを自分で書くことになりました。

于 2011-07-26T17:31:01.150 に答える