8

String から部分関数へのマップを作成しているときに、予期しない動作に遭遇しました。部分関数をマップ要素として作成すると、正常に機能します。val に割り当てると、代わりに呼び出されます。チェックを呼び出そうとすると、エラーが発生します。これは期待されていますか?私は愚かなことをしていますか?をコメントアウトしてcheck()、呼び出しを確認します。私はscala 2.7.7を使用しています

def PartialFunctionProblem() = {
    def dream()() = {
        println("~Dream~");
        new Exception().printStackTrace()
    }
    val map = scala.collection.mutable.HashMap[String,()=>Unit]()
    map("dream") = dream()      // partial function
    map("dream")()              // invokes as expected
    val check = dream()         // unexpected invocation
    check()                     // error: check of type Unit does not take parameters 
}
4

2 に答える 2

12

便宜上、Scalaではメソッドを呼び出すときに空の親を省略できますが、最初のケースで期待される型がであることがわかる()=>Unitので、すべての親が削除されるわけではありません。代わりに、メソッドを関数に変換します。

ただし、このval check場合、関数呼び出しの結果が変数に割り当てられているように見えます。実際、これら3つすべてがまったく同じことを行います。

val check = dream
val check = dream()
val check = dream()()

メソッドを関数に変換する場合は、引数リストの代わりに_メソッドの後に配置します。したがって、

val check = dream() _

あなたが望むことをします。

于 2010-05-20T04:49:41.723 に答える
5

さて、問題はあなたがそれをすべて間違っているということです。:-)

ここにいくつかの概念的な間違いがあります:

def dream()() = {
    println("~Dream~");
    new Exception().printStackTrace()
}

これは部分的な機能ではありません。これは、 を返す 2 つの空のパラメータ リストを持つカリー化されたメソッドUnitです。

val map = scala.collection.mutable.HashMap[String,()=>Unit]()

このマップの値の型は部分関数ではなく、関数です。具体的には、Function0[Unit]. 部分関数の型はPartialFunction[T, R].

map("dream") = dream()      // partial function

ここで起こることは、Scalaが部分的に適用されたメソッドを関数に変換することです。これは単純な割り当てではありません。型推論は正しい型を推測できるため、Scala は変換を行います。

val check = dream()         // unexpected invocation

ここでは、型推論を支援する期待される型はありません。ただし、空のパラメーター リストは省略できるため、これは単なるメソッド呼び出しです。

于 2010-05-20T15:39:19.877 に答える