2017-01-10 10 views

答えて

1

スキームでは、約束事は、必ずしもまだ実行されていないタスクを持つ値であり、値を決して使用しない場合、決して計算されません。要するに、そうでなければ熱心なスキームで怠惰な評価を行う方法です。典型的な方法は、リストの代わりにストリームの計算を行うことです。

リストでは、高次関数を使用してリストを作成し、関心のある値をフィルターに掛けた後、これらの値を変換したり、必要な値を生成するのに十分な点を置き換えることができます。これは、各ステップを抽象化することができますので、1つのステップのみを実行し、プログラム全体を作成するロジックを作成できますが、このシナリオでは、最初のステップが完了してから次のステップが最初の場合は、0から1000の間の最初の素数を検索して、各ステップのすべての数値を反復処理してもそれほど効果的でない可能性があります。ここでストリームが入ってくるところです。

ストリームでは、コードは同じように見えますが、中間結果は必要に応じて作成されます。ストリームは、パートが約束しているペアであり、そうでなければペアを作るコードは、値が使用されるまで遅延されます。すべてのステップで次のステップに十分なデータが生成されます。したがって、最初のステップで最後のステップの要素の20%だけを繰り返して、最終結果を計算していれば十分です。ステップ。このような構造では、0から1までのすべての数値が1だけ増えたように、初期ストリームも無限大になります。

ストリームを使用するとペナルティが発生します。とにかくすべての要素を訪問するアルゴリズムを作ったとします。アルゴリズムのストリーム・バージョンは、作成された約束事と、怠惰なことなく計算を実行することと比べて、プログラムのオーバーヘッドを与えるので、遅くなる。

Hal Abelson explaining streamsとその賛否両論に興味があるかもしれません。

ストリームの代わりにレイジー評価があります。 1つはgeneratorsです。ここでは、ジェネレータを使用してジェネレータを生成する合成可能なプロシージャを作成することもできます。反復はストリームのように必要になります。

もう1つの代替方法はtransducersです。これも構成可能であり、ストリームやジェネレータと同じように反復しますが、ジェネレータとは異なり、ストリームやジェネレータなどの無限のシーケンスは、基礎となる構造がサポートしていない限り初期データにすることはできません。

この回答で約束または他の手法を使用する利点は、スキーム固有ではありません。彼らはすべての熱心なプログラミング言語に当てはまります!

関連する問題