5

高階関数の宣言のセクションで、(33 ページ)と書かれている「F#を使用した関数型プログラミング」という本を読んでいます。

(+) や (<<) などの高階組み込み関数を見てきました。

そしてセクションの最後に

高階関数は、代わりに、let 宣言で次のように引数を指定して定義することもできます。

let weight ro s = ro * s ** 3.0;;

ただし、今日以前に行った質問(当初は「いつ関数を高階関数として作成する必要があるか」というタイトルでした)の最後に、これらの例が実際により高いかどうかに疑問を投げかけているように見えるいくつかの役立つコメントがありました。注文機能。

高階関数のウィキペディアの定義は次のとおりです。

高階関数 (関数形式、関数関数またはファンクターも) は、次の少なくとも 1 つを実行する関数です。(i) 1 つまたは複数の関数を入力として受け取ります。(ii) 関数を出力します。

一方では、 のような関数は(+)weight単一の引数を指定すると関数を返すため、高階関数と見なされる可能性があることがわかります。一方、カリー化された関数として適切に見なされていることがわかります。私は自習プロジェクトとして F# を学んでおり、概念を明確にしたいと考えているため、このサイトの回答と議論は特に役に立ちます。

私の質問は、これらの関数の正しい用語は何か、そしておそらくもっと重要なのは、「高階関数」と「カリー化された関数」という用語を通常どのように使用するかということです。

4

2 に答える 2

4

大まかに言えば、カリー化された関数は高階関数のサブセットです。高階関数は、関数を引数として受け入れるか、結果で関数を返します。カリー化された関数は、最初の引数を受け入れ、2 番目の引数を受け入れる関数などを返す関数として、カリー化された形式で記述された多変量関数です。

以上、トマスが言っていたことです。ただ、ここに微妙なところがあると思います。関数を返すすべての関数がカリー化されているわけではなく、Tomas の「括弧を追加すると (型は変わらない)」というステートメントは F# では不正確だと思います。

具体的には、引数を取り、副作用があり、別の引数を取り、結果を返す別の関数を返す関数を考えてみましょう。

let f x =
  printfn "%d" x
  fun y -> x+y

F# は次の型を推測します。

val f : int -> (int -> int)

一見冗長な括弧が挿入されていることに注意してください。これは、これらの型の間に微妙な違いがあるためだと思います。

さらに、この関数は結果として関数を返しますが、その副作用のために、カリー化された関数としての資格があるとは思いません。これは、カリー化された形式で書き直された多変量関数ではありません...

于 2013-09-20T23:34:13.313 に答える