2011-07-26 5 views
5

PartialFunction[A, B]として具体的な関数(型の例:(A) => B)としてすばやく使用できますか?私の知っている最も簡潔な構文は次のとおりです。私はちょうど私が探していたものを書いたと思いますが、これは既に存在しない具体的なものからのスカラPartialFunctions

implicit def funcAsPartial[A, B](func: A => B) = new PartialFunction[A, B] { 

    def isDefinedAt(a: A) = true 
    def apply(a: A) = func(a) 

} 

(a: A) => a match { case obj => func(obj) } 

どこでも暗黙的な変換は、のようなものがありますScalaライブラリ?

答えて

5

(A) => BPartialFunction[A, B]から継承されるべきでないという同じ理由で、暗黙の変換でこれを行うと、危険です。つまり、PartialFunctionの契約では、isDefinedAttrueを返す場合は、applyと安全に電話できることが保証されます。 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がドメインを次のような正確な意味で明示的に宣言していることです。が値xに対してtrueを返す場合、apply(x)は関数の作成者の意図と一貫して評価できます。そのではありません。つまり、apply(x)は例外をスローしませんが、単にその例外が関数の設計の一部であった(そして文書化されるべきである)ことを意味します。

+0

ありがとうございます。私は、Function1がドメイン全体にわたって定義されていると誤解していました。 –

+0

@AaronNovstrup:PartialFunctionの契約の説明は意味をなさない唯一のものですが、少なくとも2.9.1まではScalaDocsに反映されていません。 'PartialFunction'のScalaDocsは次のように主張しています:" PartialFunction [A、B] '型の部分関数は、ドメインが必ずしも' A'型のすべての値を含むわけではない単項関数です。さらに、 'PartialFunction'という文字列' {case 0 => 1/0} 'のように、定義されていればどこでもfを呼び出すのは安全です(どのような意味で)安全であると主張することは決してありません。 あなたはその情報をどこで取得しましたか?バグレポートを提出する必要がありますか? – Blaisorblade

+0

@ Blaisorblade私はScalaを勉強していたときにメーリングリストでこの説明を読んでいると思いますが、これは私がこの答えを書いたときには何のドキュメントも見ていませんでした。そして、はい、この契約に違反することは(たとえば、catchブロック内で例外をラップ/再スローするなど)簡単に、さらには多少一般的です。本当のポイントは、PartialFunctionsはドメインを定義していますが、通常の関数はそうではありません。 –

0

いいえ、私は数ヶ月前に見つけようとしましたが、あなた自身と本質的に同じです。

+0

'(A)=> B'は、PartialFunction [A、B]から継承する必要があります。 –

+1

(total)Functionはどこでも定義される部分的な関数である(isDefinedAt(x)= true)ということで、私はそれに同意します。しかし、Martin Odersky氏は、Functionが完全なFunctionであることが保証されていないと言うと、そのドメインが文書化されていないということだけです。ですから、PartialFunctionはそのドメインを文書化する関数です。 –

+0

http://www.scala-lang.org/node/2750 –

関連する問題