問題タブ [strictness]
For questions regarding programming in ECMAScript (JavaScript/JS) and its various dialects/implementations (excluding ActionScript). Note JavaScript is NOT the same as Java! Please include all relevant tags on your question; e.g., [node.js], [jquery], [json], [reactjs], [angular], [ember.js], [vue.js], [typescript], [svelte], etc.
haskell - スタック スペースのオーバーフロー (mapM に関連している可能性があります)
ディレクトリ内の各画像ファイルに対して 1 つのコマンドを含むシェル スクリプトを作成するプログラムを作成しています。ディレクトリには 667,944 個の画像があるため、厳密性と遅延性の問題を適切に処理する必要があります。
これが私に与える簡単な例ですStack space overflow
。を使用してより多くのスペースを与えると機能しますが、ほとんどのメモリで実行でき+RTS -Ksize -RTS
、すぐに出力を生成できるはずです。だから、私は Haskell wiki と Haskell の wikibook で厳密性に関するものを読んで、問題を解決する方法を見つけようとしました。それは私を悲しませている mapM コマンドの 1 つであると思いますが、まだ解決していません。問題を分類するための厳密さについて十分に理解していません。
関連すると思われる SO に関するその他の質問をいくつか見つけました ( Is mapM in Haskell strict? Why does this program get a stack overload? and Is Haskell's mapM not lazy? )、しかし啓発はまだ私を逃れています。
編集:テスト #1
これがサンプルの最新バージョンです。
コマンドでコンパイルしますghc --make -O2 amy2.hs -rtsopts
。コマンド./amy2 ~/nosync/GalaxyZoo/table2/images/ wombat
で実行すると、次のようになります
代わりにコマンド./amy2 ~/nosync/GalaxyZoo/table2/images/ wombat +RTS -K20M
で実行すると、正しい出力が得られます...最終的には:
...等々。
haskell - 整数アキュムレータの厳密な評価
カスタムlength
関数での古典的な最初の試みを次に示します。
そして、ここに末尾再帰バージョンがあります:
ただし、(n+1)
厳密に評価されるわけではありませんが、代わりに Haskell はサンクを作成しますよね?
これは、サンクの作成を防ぎ、厳密な評価を強制する正しい方法(n+1)
ですか?
seq
の代わりに同じ効果を得るにはどうすればよい$!
ですか?
haskell - IO モナドによる論理 AND の厳密性
Haskell で簡単なプログラムを作成しようとしています。基本的に、2 つのシェル コマンドを並行して実行する必要があります。コードは次のとおりです。
しかし、コマンド "foo" は ExitFailure を返し、"bar" は決して実行されないと予想します。これはそうではありません!どちらも実行され、両方ともコンソールにエラーが表示されます。
同時に
完全によく評価されます。これは、2 番目の引数が計算されないことを意味します。アプリのシステム コマンドで同じことを行うにはどうすればよいですか?
haskell - 弱頭の正常な形と評価の順番
私は弱い頭の通常の形と配列についてたくさん読んだ。しかし、Haskell の評価順序の背後にあるロジックを想像するのはまだ難しい
いつ、どのように使用するかを示す一般的な例ですが、一般的な例がどのように使用されるかはまだわかりません
スタック オーバーフローが発生する可能性があります。を使用した別の折り畳み定義seq
はそうではありませんが
私が読んだ seq の説明から、著者は次のことを明確にするために非常に注意を払っています:
- の最初の引数は
seq
、2 番目の引数の前に評価されるとは限りません - の最初の引数は、
seq
弱頭正規形にのみ評価されます - の最初の引数の評価は、
seq
2 番目の引数が WHNF に評価される場合にのみ発生します。
では、上記が正しければ (そうですか?)、なぜfoldl'
のようにオーバーフローしないのfoldl
でしょうか?
一歩減らすとこうなるじゃないですか。
上記では、実行する必要がある関数適用があるため、の 2 番目の引数はseq
WHNF にありません。seq
2 番目の引数の WHNF に到達する前に、hereの最初の引数を評価することが保証されていますか?
haskell - Generic インスタンスのすべての値を列挙するときの無限再帰
私の別の答えとして、列挙可能な s の斜めにトラバースされたインスタンスを提供する次のコードを作成しました( Universe
そこGeneric
のバージョンからわずかに更新されていますが、同じロジックを使用しています):
(Omega
おそらく問題とは関係ありませんが、質問の一部でした。)
これは、次のような再帰的なものであっても、ほとんどの型で機能します。
例:
ただし、上記の型はすべて再帰コンストラクターを最初から持っていないことに注意してください。実際(そしてこれが問題です)、次のように分岐します。
の評価順序に何か問題があるのではないかと最初は思ったのですOmegas
が、左右を入れ替えてもうまく(2)
いくだけで失敗するというのが正しい動作だと思います。T7
T6
私の現在の疑いは、universe
in lineへの呼び出しの(1)
評価が早すぎることです。たとえば、次の例も発散しますが、リストには値が1 つだけある必要があり、評価する必要さえありません。
したがって、唯一のインスタンス は、必要ではありませんが、 list 内でT8 (T8 (...) ... )
評価されます! この効果がどこから来ているのかわからない - それはそれ自身のインスタンスの再帰的な使用ですか? しかし、なぜ「右再帰」型は正しく動作し、「左再帰」型 ( ) は正しく動作しないのでしょうか?Universe
T6
T7
これは厳しさの問題ですか?もしそうなら、コードのどの部分ですか?私のUniverse
インスタンス?Generic
? そして、それを修正する方法は?それが問題なら、GHC 7.6.3を使用します。
haskell - より厳密な Control.Monad.Trans.Writer.Strict
したがって、次のようになります。
いくつかのKey
とVal
。
収集された出力を見ない限り、すべて問題なく動作します。
ただし、 を調べたい場合はw
、スタック オーバーフローが発生します。
(>>=)
その理由は、 forWriter
が次のように定義されているためだと思います。
大規模なWriter a
計算を行うと、長い一連の mappend が作成されます。w <> (w' <> (w'' <> ...))
この場合、Map.union
これはマップの背骨で厳密な a です。したがって、ユニオンの大きなシーケンスを構築する場合、スタックをオーバーフローする Map を強制するとすぐに、すべてを評価する必要があります。
私たちが望むのは、結合を早期に実行することです。より厳密な Strict.Writer が必要です。
だから私の質問は:これはいくつかの「標準」ライブラリに存在しますか? そうでない場合、なぜですか?