一応補足ですが,現在の GHC では full laziness が入るタイミングが調整されていて,
はどちらも
なので,スーパーコンビネータかどうかは指標の一つではありますが,実際にはどう最適化が入るかによって CAF になるかはかなり左右されます
factMemo :: Int -> Integer factMemo = (map fact' [0..] !!) where fact' 0 = 1 fact' n = fromIntegral n * factMemo (n - 1) fact :: Int -> Integer fact x = map fact' [0..] !! x where fact' 0 = 1 fact' n = fromIntegral n * fact (n - 1)
はどちらも
fact'
は外に出されます.このため, map fact' [0..]
も CAF として扱われます. GHCi のバイトコード出すパスでは, core 2 core のパスが少し簡略化されてるので, full laziness が真面目に入ってないだけだと思いますね.なので,スーパーコンビネータかどうかは指標の一つではありますが,実際にはどう最適化が入るかによって CAF になるかはかなり左右されます