カリー化、それが理由
ダニエルは、パラメーターなしのメソッドが必要な理由を説明するのに非常に役立ちました。それらがゼロパラメータメソッドと区別される理由を説明します。
多くの人は、パラメーターのない関数とパラメーターのない関数の違いを、あいまいな形式の構文糖衣と見なしています。実のところ、これは純粋に Scala がカリー化をどのようにサポートしているかの成果物です (完全を期すために、カリー化とは何か、そしてなぜ私たちがカリー化を好むのかについてのより詳細な説明については、以下を参照してください)。
形式的には、関数は、0 個以上のパラメータ リストを持つことができ、それぞれに 0 個以上のパラメータがあります。
これは、以下が有効であることを意味します: def a
、def b()
だけでなく、不自然def c()()
なdef d(x: Int)()()(y: Int)
なども...
関数def foo = ???
にパラメーター リストがありません。関数def bar() = ???
には、パラメーター リストが 1 つだけあり、パラメーターはありません。2 つの形式を混同する追加のルールを導入すると、一貫した言語機能としてのカリー化が弱体化def a
する可能性がdef b()
ありますdef c()()
。def d(x: Int)()()(y: Int)
と同等def e()(x: Int)(y: Int)()()
です。
カリー化が無関係なケースの 1 つは、Java 相互運用を扱う場合です。Java はカリー化をサポートしていないため、"test".length()
(を直接呼び出すjava.lang.String#length()
) のようなゼロ パラメータ メソッドを としても呼び出すための構文糖衣を導入しても問題はありません"test".length
。
カリー化の簡単な説明
Scala は、数学者 Haskell Curry にちなんで名付けられた「currying」と呼ばれる言語機能をサポートしています。
カリー化により、いくつかのパラメーター リストを使用して関数を定義できます。たとえば、次のようになります。
def add(a: Int)(b: Int): Int = a + b
add(2)(3) // 5
inc
の部分適用に関して定義できるようになったため、これは便利ですadd
。
def inc: Int => Int = add(1)
inc(2) // 3
カリー化は、ライブラリを介して制御構造を導入する方法として最もよく見られます。たとえば、次のようになります。
def repeat(n: Int)(thunk: => Any): Unit = (1 to n) foreach { _ => thunk }
repeat(2) {
println("Hello, world")
}
// Hello, world
// Hello, world
repeat
要約すると、カリー化を使用する別の機会がどのように開かれるかを確認してください。
def twice: (=> Any) => Unit = repeat(2)
twice {
println("Hello, world")
}
// ... you get the picture :-)