4

私はかなり長い間 haskell を使用しており、ほとんどの Real World Haskell と Learn You a Haskell を読みました。私が知りたいのは、遅延評価を使用する言語にポイントがあるかどうか、特に無限リストを持つことの「利点」があるかどうか、無限リストが非常に簡単にするタスクがあるかどうか、または無限リストでのみ可能なタスクがあるかどうかです。リスト?

4

8 に答える 8

17

これは、非常に些細なことですが、無限リストが特に役立つ場所の実際の日常の有用な例です: 連続するキーから始まる、キーと値のスタイルのデータ構造を初期化するために使用するアイテムのリストがある場合。たとえば、文字列のリストがあり、それらをIntMap0 から数えたいとします。遅延無限リストがなければ、入力リストをたどって、実行中の「次のインデックス」カウンターを維持し、IntMapあなたが行くように。

無限遅延リストでは、リスト自体が実行中のカウンターの役割を果たします。アイテムのリストで使用zip [0..]してインデックスを割り当て、IntMap.fromList最終結果を構築するだけです。

確かに、どちらの場合も本質的に同じことです。しかし、怠惰な無限リストを使用すると、入力リストの長さなどの詳細を気にしたり、余分なカウンターを追跡したりすることなく、概念をより直接的に表現できます。

于 2010-12-20T15:24:43.043 に答える
13

明らかな例は、データ処理を入力から処理したいものに連鎖させることです。たとえば、文字のストリームをレイジー リストに読み込みます。これはレクサーによって処理され、レイジー AST 構造に解析されてからコンパイルおよび実行されるトークンのレイジー リストも生成されます。Unix パイプを使用するようなものです。

于 2010-12-20T15:08:46.817 に答える
8

たとえそれが無限であっても、すべてのシーケンスを 1 か所で定義し、それを使用するコードで必要なものを取得する方が簡単でクリーンな場合が多いことがわかりました。

take 10 mySequence
takeWhile (<100) mySequence

サブセットを生成する、類似しているがまったく同じではない多数の関数を持つ代わりに

first10ofMySequence
elementsUnder100ofMySequence

同じシーケンスの異なるサブセクションが異なる領域で使用されると、利点が大きくなります。

于 2010-12-20T15:18:44.360 に答える
7

John Hughes の古典的な論文Why Functional Programming Mattersで説明および図示されているように、無限のデータ構造 (リストを含む) はモジュール性を大幅に向上させ、再利用性を高めます。たとえば、複雑なコード チャンクをプロデューサー/フィルター/コンシューマーの断片に分解することができ、それぞれが別の場所で役立つ可能性があります。

したがって、コードの再利用に実際の価値が見られるところならどこでも、質問に対する答えが得られます。

于 2010-12-20T21:07:49.960 に答える
6

基本的に、遅延リストを使用すると、必要になるまで計算を遅らせることができます。これは、いつ停止するか、何を事前計算するかが事前にわからない場合に役立ちます。

標準的な例は、ある極限に収束する数値計算のシーケンス u_n です。|u_n - u_{n-1}| のような最初の項を求めることができます。< イプシロン、適切な項数が計算されます。

今、そのような 2 つのシーケンス u_n と v_n があり、イプシロン精度の限界の合計を知りたいとします。アルゴリズムは次のとおりです。

  • epsilon/2 の精度になるまで u_n を計算する
  • v_n を epsilon/2 の精度まで計算する
  • u_n + v_n を返す

すべてが遅延して行われ、必要な u_n と v_n のみが計算されます。単純ではない例が必要になる場合があります。f(u_n) を知っている (つまり、計算方法を知っている) f の連続係数を計算します。

于 2010-12-20T15:11:33.073 に答える
4

音声合成 - Jerzy Karczmarczuk によるこの論文を参照してください。

http://users.info.unicaen.fr/~karczma/arpap/cleeasyn.pdf

Jerzy Karczmarcuk は、べき級数や導関数などの数学オブジェクトをモデル化するために無限リストを使用する他の多くの論文を発表しています。

基本的な音声合成コードを Haskell に変換しました - 正弦波ユニット ジェネレーターと WAV ファイル IO には十分です。パフォーマンスは、1.5GHz Athalon で GHCi を実行するのにちょうど十分でした。コンセプトをテストしたかっただけなので、最適化することはできませんでした。

于 2010-12-20T18:28:58.367 に答える
3

無限/怠惰な構造により、「結び目を結ぶ」というイディオムが可能になります: http://www.haskell.org/haskellwiki/Tying_the_Knot

これの標準的に単純な例は、再帰関係として直接定義されたフィボナッチ数列です。(はい、はい、効率の不満/アルゴリズムの議論を開催してください-ポイントはイディオムです。):fibs = 1:1:zipwith (+) fibs (tail fibs)

ここに別の話があります。私は有限のストリームでのみ動作するコードをいくつか持っていました.ある時点までそれらを作成するためにいくつかのことを行い、その後、ストリーム全体に依存するストリームのさまざまなビットに作用することを含むナンセンスを大量に実行しました。それを別のストリームからの情報とマージするなど。それはかなり良かったのですが、境界条件を処理するために必要な作業がたくさんあることに気付きました。その後、概念的には、無限ストリームで機能しない理由はないことに気付きました。そこで、nil のないデータ型に切り替えました。つまり、リストではなく本物のストリームであり、面倒なことはすべてなくなりました。ある時点を過ぎたデータは必要ないとわかっていても、

于 2010-12-20T17:51:13.130 に答える
3

私の実用的なお気に入りの 1 つはcycle. cycle [False, True]無限リストを生成します[False, True, False, True, False ...]。特に 、xs ! 0 = False、つまりxs ! 1 = True、これは要素のインデックスが奇数かどうかを示しているだけです。これはどこに表示されますか?多くの場所がありますが、Web 開発者なら誰でも知っておくべき場所の 1 つは、行ごとに陰影を交互に表示するテーブルを作成することです。

ここで見られる一般的なパターンは、有限リストに対して何らかの操作を実行したい場合、「やりたいことを実行する」特定の有限リストを構築する必要があるのではなく、すべてのサイズで機能する無限リストを使用できるということです。リストの。camcann の答えは、この流れにあります。

于 2010-12-21T00:44:16.107 に答える