15

私は Scala についてさらに学んでいますが、http://www.scala-lang.org/node/135の無名関数の例を理解するのに少し苦労しています。以下のコードブロック全体をコピーしました。

object CurryTest extends Application {
    def filter(xs: List[Int], p: Int => Boolean): List[Int] =
        if (xs.isEmpty) xs
        else if (p(xs.head)) xs.head :: filter(xs.tail, p)
        else filter(xs.tail, p)

    def modN(n: Int)(x: Int) = ((x % n) == 0)

    val nums = List(1, 2, 3, 4, 5, 6, 7, 8)
    println(filter(nums, modN(2)))
    println(filter(nums, modN(3)))
}

modN 関数の適用について混乱しています

def modN(n: Int)(x: Int) = ((x % n) == 0)

例では、1 つの引数で呼び出されます

modN(2) and modN(3)

modN(n: Int)(x: Int) の構文は何を意味しますか?

1 つの引数で呼び出されるため、両方の引数ではないと想定していますが、nums の値が mod 関数でどのように使用されるかはわかりません。

4

3 に答える 3

47

これは、カリー化 と呼ばれる関数型プログラミングの楽しいことです。f(x,y)基本的に、Moses Schönfinkel と後者の Haskell Curry (Schonfinkeling は奇妙に聞こえるかもしれませんが...)は、{g(x)}(y)複数g(x)(y)の引数の関数を呼び出すという考えを思いつきgました。出力。

例として、関数を取り上げますf(x: Int, y: Int) = x + y。を呼び出すと、予想どおりf(2,3)が生成5されます。しかし、この関数をカリー化するとどうなりますか? as として再定義し、 asf(x:Int)(y: Int)と呼びますf(2)(3)。最初の呼び出しはf(2)、整数yを取り、それに追加する関数を生成します2->したがって、f(2)Int => Intがあり、関数と同等g(y) = 2 + yです。2 番目の呼び出しf(2)(3)は、新しく生成された関数gを引数3で呼び出すため、期待どおりに評価5されます。

これを表示するもう 1 つの方法は、呼び出しのリダクション (関数型プログラマーはこれをベータ リダクションと呼びます - 行ごとにステップする関数型の方法のようなものです) をステップ実行することですf(2)(3)(注: 以下は実際には有効な Scala 構文ではありません)。

f(2)(3)         // Same as x => {y => x + y}
 | 
{y => 2 + y}(3) // The x in f gets replaced by 2
       |
     2 + 3      // The y gets replaced by 3
       |
       5

したがって、このすべての話の後f(x)(y)、次のラムダ式と見なすことができます(x: Int) => {(y: Int) => x + y}- これは有効な Scala です。

これがすべて理にかなっていることを願っています-呼び出しが理にかなっている理由の背景を少し説明しようとしました:)modN(3)

于 2009-10-11T15:08:26.180 に答える
3

ModN 機能を部分的に適用しています。部分関数適用は、関数型言語の主な機能の 1 つです。詳細については、カリー化ポイントフリースタイルに関するこれらの記事を参照してください。

于 2009-10-11T15:01:40.890 に答える
2

その例では、 modNは特定の N で変更する関数を返します。これにより、これを行う必要がなくなります。

def mod2(x:Int): Boolean = (x%2) == 0
def mod3(x:Int): Boolean = (x%3) == 0

2 組のかっこは、メソッドへの引数の受け渡しを停止できる場所を区切ります。もちろん、メソッドの引数リストが 1 つしかない場合でも、プレースホルダーを使用して同じことを行うこともできます。

def modN(n: Int, x: Int): Boolean = (x % n) == 0

val nums = List(1, 2, 3, 4, 5)
println(nums.filter(modN(2, _)))
println(nums.filter(modN(3, _)))
于 2009-10-11T14:53:04.060 に答える