これは Haskell の学習からの例です:
ghci> [ x*y | x <- [2,5,10], y <- [8,10,11], x*y > 50]
[55,80,100,110]
では、ここで何が起こっているのか、x*y
2 回または 1 回計算されるのでしょうか。
これは Haskell の学習からの例です:
ghci> [ x*y | x <- [2,5,10], y <- [8,10,11], x*y > 50]
[55,80,100,110]
では、ここで何が起こっているのか、x*y
2 回または 1 回計算されるのでしょうか。
共通の部分式の削除が発生しない限り、2 回計算されます。
インライン展開と最適化レベルに応じて、GHC はリスト内包表記に対して非常に積極的な処理を行う場合があります。
一般に、共通表現を明示的に共有して、共有を保証する必要があります。
コンパイラの動作を確認するには、次のことをお勧めします。
[ product | x <- [2, 5, 10]
, y <- [8, 10, 11]
, let product = x * y
, product > 50]
-O2 オプションを指定してコンパイルしたときにコアを調べると、次の行があります (関連し、簡略化されています)
case (y_aAD * sc_s1Rq) > 50 of
False -> go_XB2 sc1_s1Rr;
True -> (y_aAD * sc_s1Rq):(go_XB2 sc1_s1Rr)
これは、乗算が 2 回計算されていることを明確に示しているため、再計算を防ぐために共通の式を使用することをお勧めします。