13

デフォルトで厳密なコードにコンパイルされる GHC のブランチがあると聞いたことがありますが、遅延は注釈によって有効にできます。(IIRC、彼は金融会社がブランチを開発し、それを製品コードに使用していると言いました。)それは本当ですか?見つからない。

その人はまた、厳密な評価は遅延評価 (デフォルト) よりも実用的であるという意見がますます受け入れられるようになっていることを示唆しました。Haskellメーリングリストでこれが確認されたわけではありませんが、おそらくそこの人々は実践志向ではないからでしょうか?

厳密な Haskell で見つけたのは、$!andのような明示的なものだけrnfです。遅延評価は非常に洗練されていると思いますが、Haskell でプログラムを開発して、スペース リークを回避し、予測可能なパフォーマンスを得たいと考えています。

免責事項: 私は厳格さを主張しているわけではありません。厳密な Haskell などを見てみたいだけです。

4

5 に答える 5

12

あなたは弟子を探しています。

したがって、Haskell では 2 種類の怠惰を区別する必要があります。怠惰な I/O があります。これは忌まわしく、反復ライブラリ (恥知らずなプラグイン: 私のパイプライブラリを含む) によって解決されます。次に、純粋な計算には遅延がありますが、これについてはまだ議論の余地がありますが、遅延の主な利点を要約してみます。

怠惰はより効率的です

簡単な例は次のとおりです。

any = foldr (||) False

anyリスト内のいずれかの値が であるかどうかを調べますTrue。これは最初の までの要素のみを評価するTrueため、リストが非常に長くても問題ありません。

遅延は必要な分だけ計算します。つまり、2 つの遅延計算を連鎖させると、結果として得られる計算の時間の複雑さを実際に改善できます。 このスタック オーバーフロー コメントは、この別の良い例を示しています。

これは、反復ライブラリがリソース効率が非常に高い理由と同じ理由です。結果を生成するために必要な作業のみを行うため、非常に使いやすいセマンティクスで非常に効率的なメモリとディスクの使用につながります。

怠惰は本質的により構成可能です

これは、厳密言語と関数型言語の両方でプログラミングしたことのある人にはよく知られていますが、実際には、インスタンスpipesを許可する唯一のバージョンが遅延バージョンであるライブラリで作業しているときに、これの限定的な証明をうっかり示してしまいました。Categoryパイプは実際には、純粋なIdentityモナドを含むどのモナドでも機能するため、私の証明は純粋なコードにも変換されます。

これが、一般的に遅延性が実際にプログラミングの未来であると私が信じる本当の理由ですが、Haskell が遅延性を「正しく」実装したかどうかについては未解決の問題であると私は考えています。

于 2012-05-28T14:29:14.330 に答える
5

GHCによる投機的評価に関する Robert Ennals の博士論文について聞いたことがあるようです。彼は「spec_eval」フォークと呼ばれる GHC のフォークを作成しました。そこでは投機的評価が行われました。Haskell は明示的に怠惰ではなく非厳密であるため、spec_eval実際に違いが生じるまで厳密でした。すべてのケースで高速でしたが、GHC に大きな変更を加える必要があり、マージされませんでした。

この質問は、このサイトで以前に回答されています。

于 2012-11-29T01:09:07.063 に答える
3

なぜ Haskell の怠惰を避けてはならないのかについて、いくつかの良いことが言われていますが、元の質問は未解決のままだと思います。

Haskell での関数の適用は厳密ではありません。つまり、関数の引数は必要な場合にのみ評価されます。

~ Haskell Report 2010 > 定義済みの型とクラス # 厳密な評価

ただし、これは少し誤解を招きます。実装は、必要になる前に関数の引数を評価できますが、限られた範囲でしか評価できません。非厳密なセマンティクスを保持する必要があります。したがって、引数の式が無限ループを引き起こし、その引数が使用されていない場合、その引数を使用した関数呼び出しは無限ループしてはなりません。

したがって、完全に「怠惰」ではない方法で Haskell を実装すること許可されていますが、それでも「厳格」にすることはできません。これは一見矛盾しているように見えますが、そうではありません。あなたがチェックしたいと思うかもしれないいくつかの関連トピック:

  • Eager Haskell、デフォルトで熱心な評価を使用する Haskell プログラミング言語の実装。これはあなたが考えていたことだと思います (ただし、GHC のブランチではありません)。
  • 投機的実行と投機的並列処理 (投機パッケージなどを参照)。
  • Optimistic Evaluation、厳密性最適化による GHC の高速化に関する SPJ の論文。
于 2012-05-29T08:27:26.120 に答える
2

私の理解が正しければ、私たちが知っているように、厳密な Haskell はモナド I/O を持つことはできません。Haskell の考え方は、すべての Haskell コードが純粋であり (State モナドのように機能する IO アクションを含む)、"main" が IO () 型の値をランタイムに与え、それがシーケンス演算子を繰り返し強制するというものです >>= .

Tekmo の投稿に対する反論として、Robert Harper のブログ * http://existentialtype.wordpress.com/2011/04/24/the-real-point-of-laziness/ および関連の記事を参照してください。それは双方向に行きます。

私の経験では、怠惰は最初は難しいですが、慣れれば問題ありません。

怠惰を擁護する古典的な作品は、Hughes の論文「Why Functional Programming Matters」であり、簡単に見つけることができるはずです。

于 2012-05-28T17:34:48.720 に答える