2013-03-26 10 views
14

ハスケルで遅延評価をオフにすることはできますか?ハズケで遅延評価をオフにする

これを容易にするライブラリの特定のコンパイラフラグはありますか?

パフォーマンスを向上させることができるかどうかを確認するために、以前書いた古いプログラムで新しいものを試したかったのです。

+0

私は答えがいいと思います。これを読んで、最適化やプロファイルを行うことができます:http://book.realworldhaskell.org/read/profiling-and-optimization.html –

+3

これは、言語のpalの一番下にあります。あなたが熱望したいと思う具体的なものがありますか? – bchurchill

+0

@bchurchill好奇心でいっぱいです – pyCthon

答えて

33

怠惰なことを厳しくする方法はたくさんあります。あなたは:

  1. 偽のパターンマッチを明示的に挿入してください。
  2. seqまたはそれに近い相対($!)を使用してください。
  3. BangPatternsを使用してください。
  4. 種類に厳密性の注釈を使用します。

詳細情報here

+4

偽のパターンマッチとは何ですか? –

+5

@NikitaVolkovたとえば、リストの場合、 'foo'を' [] - > fooの 'case xs; _:_ - > foo'となります。 –

+2

'seq'や' $! 'を使っても、式全体を完全に評価する必要はありません。例えば、あなたのリストの計算で 'seq'を使うと、結果リストを熱心に評価しますが、これは単にリストの先頭項目を保持するconsです。ヘッドメンバーとテールリスト全体がまだ評価されていない可能性があります。完全な式が完全に評価されるようにするには、 'deepseq'オプションがあります。つまり' NFData'型のクラスをインスタンス化する必要があります。もう一つは、結果の型に合わせて厳密に強制する関数です。 – Steve314

17

ハスケルのI/Oシステムが依存しているため、怠惰をオフにすることはできません。遅延評価がなければ、このプログラムは、これまで何も出力せずにビジーループに実行します:

main = forever (putStrLn "Hello!") 

forever cが無限プログラムであるためです。怠惰評価では、プログラムは次の命令を実行するのに必要なだけ計算されます。あなたは怠惰をオフにした場合、すべての機能は基本的にforever機能させる(>>)を含め、厳しくなっては発散する:

forever c = let cs = c >> cs in cs 

ただし、コンストラクタやパターンに正格性注釈を追加することができます。関数が厳密である場合、その引数は、引数が必要であるかどうかに関係なく、結果の評価の一部として強制されます。これは熱心な評価に似ています。

+5

これはあなたが怠惰を止めることができないことを証明するものではありません。 'forever'は特に明白な問題関数です - 同様の問題の原因となるものはあまり明白ではありませんが、十分に執念のある人は、Lazinessを無効にして動作するHaskellサブセットを特定して扱うことができます。 +1とにかく - それはまだ良い点です。 – Steve314

+3

永遠に定義することができます '永遠のc = cの= \ _ - >永遠のc' これは厳格な評価でも動作します。 –

11

ダニエル・ワグナー氏が挙げたことに加えて、同様の質問Is there a Haskell compiler or preprocessor that uses strict evaluation?を見ることができます。

  • 回答は、「どこでもnfdataとRNFを使う」ハスケルの厳格なバージョンを作成し、唯一の怠惰が明示的に
  • ghc plugin
  • monad.reader 12で説明しようとDDCコンパイラが含まれる - solrize
  • 、より

主な提案は、プロファイリングツールを使用して、Haskellを最適化する方法を学ぶことですi厳密でない評価がオフになった。

3

簡単な回答はありません。より複雑な答えは、ハスケルが関数を構築して評価する計算モデルが怠惰に動作するということです。あなたが他の答えで読んでいるように、いくつかの関数の評価を強制的に早くしてから正常にする方法がありますが、それはときどき偶然です。しかし、正式な形式を持たない有効なHaskellの大部分があります。これには、IO機能と大量の標準的なプレリュードが含まれます。

結論:ハスケルでの遅延評価をやめる方法がなくなり、Ruby of Javaでポインタ演算をC言語で無効にするか、OOを無効にする方法があります。この質問があなたを連れて行くだろうが、これはずっと遠いと思う。 (--strictモードはありませんが)実際に雨穴の深さを確認したい場合は、Simon Peyton Jonesの "Implementing Lazy Functional Languages on Stock Hardware: The Spineless Tagless G-machine"が有益な冒険です。

+0

あなたはその論文の更新されたリンクを持っていますか?リストにあるものは壊れています。 – jrk

+0

http://citeseerx.ist.psu.edu/viewdoc/summary?doi=10.1.1.53.3729 –

6

pH(http://csg.csail.mit.edu/projects/languages/ph.shtml) と呼ばれるHaskellの亜種がありますが、厳密ではないセマンティクスを提供しながら熱心な評価を使用します。 Haskellの報告書は、それが非厳格な言語であると慎重に言います。怠惰は、厳密でないことを記述し、明らかに実装する明白な方法です。

したがって、「厳密でないセマンティクスを維持しながら別の評価システムを使用できますか?」という質問があれば、pHを見ることができます。あなたの質問が "表面構文を共有するが、デフォルトでは厳密なHaskellのバージョンがあるかどうか"であれば、それは他の答えでカバーされていると思う。

2

strict-identityパッケージには、Identityモナドの厳密なバージョンがあります。

あなたはここでそれを見つけることができます: はhttps://hackage.haskell.org/package/strict-identity

使用量がこのようなものになります。使用されているが

foo = runStrictIdentity $! do 
    x <- f a b 
    y <- g x y 
    return $! x + y 

たびreturnをか>>=を結合し、2つの部分は、seqを使用して評価与えていますあなたのデータ構造があまりにも深くないならば、合理性を合理的に保証します。これは、数や基本的な構造のために機能します。

関連する問題