12

Programming in Scala (制御の抽象化) を見ると、同じ効果を持つ次の 2 つの例を見ました。

1. 高階関数

def withPrintWriter(file: File, op: PrintWriter => Unit) {
  val writer = new PrintWriter(file)
  try {
    op(writer)
  } finally {
    writer.close()
  }
}

2. カリー化機能

def withPrintWriter(file: File)(op: PrintWriter => Unit) {
  val writer = new PrintWriter(file)
  try {
    op(writer)
  } finally {
    writer.close()
  }
}

それらの違いは何ですか?両方の方法で常に同じ結果を達成できますか?

4

5 に答える 5

7

高階関数とは、関数をパラメーターとして受け取るか、関数を返すか、またはその両方を行う関数です。

def f(g: Int => Int) = g(_: Int) + 23

scala> f(_ + 45)
res1: Int => Int = <function1>

scala> res1(4)
res2: Int = 72

これは高階関数で、関数をパラメーターとして取り、別の関数を返します。ご覧のとおり、高階関数はカリー化の前提条件です。カレー関数は次のようになります。

def curry[A,B,C](f: (A,B) => C) = (a: A) => (b: B) => f(a,b)

scala> curry((a: Int, b: Int) => a+b)
res3: Int => (Int => Int) = <function1>

scala> res3(3)
res4: Int => Int = <function1>

scala> res4(3)
res5: Int = 6

あなたの質問に答えるために:それらは2つの異なる概念であり、一方(高階関数)は他方(カリー化)の前提条件です。

于 2013-09-16T14:11:24.163 に答える
0

厳密に言えば、あなたが示した例は実際にはカリー化されたものではなく、複数の引数リストがあるだけです。複数の引数リストを持つ Scala 関数が、多くの状況でカリー化された関数に非常によく似ていることはたまたまあります。ただし、複数の引数リスト関数を呼び出しても、1 つ以上の引数リストを埋めていない場合は、実際には部分適用の例であり、カリー化ではありません。すべての引数を使用して複数の引数リストを呼び出すことは、引数リストごとに 1 回ではなく、1 回の関数呼び出しにすぎません。

複数の引数リスト関数が役立つユース ケースが 2 つあります。1 つ目は、暗黙的なパラメーターの場合です。すべての暗黙的なパラメーターは、明示的なパラメーターとは別の独自の引数リストに含まれている必要があるためです。2 番目の使用例は、他の関数をパラメーターとして受け入れる関数です。関数であるパラメーターが独自の引数リストにある場合は、括弧を省略して中括弧のみを使用できるため、関数呼び出しをある種の制御構造のように見せることができます。 .

それ以外の違いは、純粋に表面的なものです。

于 2013-09-16T23:25:16.857 に答える