Haskell コンパイラが次の定義を最適化するのに十分スマートであることを期待できますか?
h x y = p (m x) (n y)
このようなものに:
h x = let z = m x in \y -> p z (n y)
? m
これは、評価にコストがかかる場合に便利でありh
、 の定義を次のように使用しました。
main = print $ map (h 2) hugeList
しかし、m
評価するのは安くても、その結果を保存するのは高くつくとしたらどうでしょうか? m x = [x .. ]
とp
に応じて、そのリストのさまざまなプレフィックスをトラバースする必要があるとしますn y
。thenm 2
が で共有されていてmap (h 2) hugeList
、いずれかのリスト要素が長いプレフィックスを必要とする場合、後続のすべての要素が結果を返すためにリストの最初の要素のみを必要とする場合でも、大量のメモリが必要になります。
そのため、の自動共有はm x
ペシミゼーションにもなり得るため、すべてのコンパイラが自動的に共有するとは思わないでください。
一般に、共有が有益か有害かをコンパイラが判断するのは難しいため、共有が本当に必要な場合は明示的に共有する必要があります。(とはいえ、場合によっては、必要のない場所でもコンパイラーが共有を導入することを期待してください。)