3

私はScalaを初めて使用しますが、Scalaが次のような「カレー機能」を提供する理由は少し混乱しているようです。

//curried function
def add(lhs: Int)(rhs: Int) = lhs + rhs
//so we can do partially binding like
val add1 = add(1)_

Scalaはすでに通常の機能に「部分適用」を提供しているため、混乱を招きます。

//normal function
def add(lhs: Int, rhs: Int) = lhs + rhs
//also supports partially application
val add1 = add(1, _: Int) 

だから私の質問は:部分適用以外にScalaで通常の関数ではなくカリー化された関数を使用する他のポイントはありますか?

EDT1:返信ありがとうございます。以下のすべての答えから新しいことを学んだと思います。

4

3 に答える 3

8

理論的な動機はさておき (参照:ウィキペディアのカリー化に関する部分関数適用との対比)、実際的な意味があります。最後の引数がコードのブロックである場合、構文ははるかに単純で読みやすくなります。

次の方法を比較します。

def test1(name: String, callback: => Unit) {}
def test2(name: String)(callback: => Unit) {}

2 番目のメソッド呼び出しは、はるかに見栄えがします。比較してください。

test("abc", {
    //some code
})

test2("abc") {
    //some code
}
于 2012-09-28T07:52:13.520 に答える
5
  • より良い構文: add(1,_) の代わりに add(1)
  • パラメーター リストの左から右への型推論。これは、たとえば、コレクションの fold メソッドで使用されます。
  • また、暗黙的なパラメーター リストにも必要です。

もちろん、最後の 2 つは別の方法で実装できたと主張することもできます。

于 2012-09-28T07:51:39.710 に答える
2

私はカリー化の背後にある理論に (まだ) 精通していませんが、カリー化がうまく機能する具体的な状況を少なくとも 1 つ知っています: ブラケットの代わりに中括弧のペアを使用して関数を呼び出すことは、単一パラメーター関数に対してのみ可能です。したがって、それぞれ 1 つのパラメーターを持つ 2 つのパラメーター リストを持つカリー化された関数に対しては実行できますが、1 つのパラメーターに部分的に適用された通常の関数に対しては実行できません。

これは、関数の一部のパラメーターがそれ自体が無名関数である制御構造または DSL を実装する場合に特に役立ちます。これの例は、Programming in Scalaのセクション 9.4 からのものです。

val file = new File("date.txt")

withPrintWriter(file) {
  writer => writer.println(new java.util.Date)
}
于 2012-09-28T07:53:13.953 に答える