0

作者がfoldrと関数構成を使用していくつかのアプリケーションを実装する場合、なぜ関数型プログラミングが重要なのかを読んでいました。私はF#でそれらのいくつかを行いました.例えばmap関数:

let cons a lst = a::lst
let map f lst = List.foldBack (f>>cons) lst []

次に、リスト フィルター関数を実装したくて行き詰まりました。

let filter pred lst = List.foldBack (what-goes-here?) lst []

ここに何が入るの?関数は、入力としてリスト項目、累積フィルタリングされたリストを取り、述語が false を返す場合は同じリストを返し、true を返す場合は cons:ed リストを返す必要があります。

ここでオプションタイプが必要だと思いますが、物事を接着する方法がわかりません。pred と cons (およびおそらく他のプリミティブ) を使用して関数を構成し、すべての配管を行うカスタム ラムダ関数を作成せずにこれを実現することは可能ですか? これは計算式の場合ですか?

4

2 に答える 2

3

あなたの質問に対する実用的な答えは次のとおりです。

whatGoesHere = fun x xs -> if f x then x :: xs else xs

匿名関数、if-then-elseおよびリストはすべて、F#の実践者によってプリミティブと見なされます。これは、このコードを作成するための最も明確で保守しやすい方法です。

残念ながら、あなたは前のレスポンダーからの同等の正解を受け入れておらず、ラムダ式を含まないコードを見ることを主張しています。どういたしまして:

``s``s`ks``s`k`s`ks``s``s`ks``s`k`s`ks``s`k`s`kk``s
`k`s`k``s``s`ks``s`k`s`ks``s`k`s`kk``s``s`ks``s`kki
`ki`k`ki``s``s`ks``s`kki`ki
`k``s``s`ks``s`kk``s`k``s``s`ks``s`kk``s`ks``s`k`s`ks
``s`k`s`kk``s`k`si``s`kki`k``s``s`ks
``s`k`s`ks``s`k`s`kk``s``s`ks``s`kki`ki
`k`kii`ki`k`ki

上記はwhatGoesHere、ブール値とリストの適切な表現を使用したSKIコンビネータ計算であり、Unlambda表記で印刷されています。

便宜上、型なしラムダ計算からSKIコンビネータまでのサンプルコンパイラと、問題に対応するラムダ計算用語のF#定義を次に示します。

http://gist.github.com/3277850

コンビネータ論理とラムダ計算が同等であるため、理論的にはラムダ式は不要ですが、プログラマーとしての意図を表現するためには不可欠です。「関数型プログラミングが重要な理由」は、ラムダ式とヘルパー関数を回避することを決して主張していません。それどころか、高階関数を含む関数を定義する機能は、関数型プログラミングの中核です。関数が構成によって定義されているか、ラムダ計算を明示的に使用しているかはほとんど問題ではありません。どちらも、この論文で説明されている「接着剤」です。

論文(そしておそらくその優れた参考文献)をもう一度読んでから、HaskellまたはCleanをインストールすることをお勧めします。著者がデフォルトで怠惰な純粋な評価モデルを提唱していることを考えると、F#はこれらのアイデアを探求するための優れたプラットフォームではありません。

于 2012-08-06T19:56:27.297 に答える
0
let consT pred a lst = if pred a then a::lst else lst
let filter pred lst = List.foldBack (consT pred) lst []
于 2012-08-04T14:33:08.523 に答える