haskell-jp / questions #104 at 2023-06-20 15:01:54 +0900

https://haskell.jp/blog/posts/2020/strict-gotchas.html
strictは!をつけてくれるのですが、!のseqではなくdeepseqに置き換えたい場合はどうすればいいでしょうか。
https://hackage.haskell.org/package/deepseq-1.4.8.1/docs/Control-DeepSeq.html#v:force ViewPatterns(+BangPatterns)と Control.DeepSeq.force の組み合わせですかね
(Strict拡張が前提ならBangPatternsは不要です)
ありがとうございます。しかし、それだと大幅な書き換えが必要になりますね。
「全ての関数のすべての引数に ! をつけて回る」はそんなに害がないことが多いですが、「全ての関数のすべての引数 x!(force -> x) に置き換える」はパフォーマンスにおいて基本的に有害なのでやめた方が良いかと思います。 deepseq は、一度既に deepseq 済みのデータ構造であっても、データ構造全体をトラバースして評価済みであることを確認・保証するという動作をするので、一度されればもうコストがかからない seq と違って、いつも何度でもデータ構造自体のサイズに比例した時間がかかります。
問題の切り分けのためにそういうのが欲しい時があります。
let (p,q) = 

なものを
let !(p,q) = 

と変換したりしますが、pやqに!がつかないのが既存のstrictだと使いにくいです。
リークがある場合の書き換えを減らしたいです。
それが大変なのはそれはそうで、でもそういうのを大域的な書き換えなしにやる方法って思いつかないですね…。「いちいち ! 」を避けようとすると型でセーフガードをつける方に行っちゃうので…。
ghc pluginでcore言語とかでseqとなっているところをdeepseqに置き換えをすればいいような気がしてきました。
どのレベルで置き換えをするかは要検討ですが。
StrictはdesugerのところでCore言語にする前のところでseqを入れるのですが、
そのseqはcase文として入れるので、core言語で明示的にseqというのは入らないですね。
ghc pluginでは無理でghcそのものに手を入れないと無理そうでした。