【发布时间】:2010-05-01 12:57:43
【问题描述】:
我有以下代码:
{-# NOINLINE i2i #-}
i2i :: Int -> Integer
i2i x = toInteger x
main = print $ i2i 2
使用 -ddump-simpl 标志运行 GHC 会给出:
[Arity 1
NoCafRefs
Str: DmdType U(L)]
Main.i2i = GHC.Real.toInteger1
似乎从 Int 到 Integer 的转换是惰性的。为什么会这样 - 有没有什么情况下我可以拥有
(toInteger _|_ ::Int) /= _|_
?
编辑:这个问题更多地与 GHC 严格性分析器有关,而不是与懒惰本身有关。此代码源自探索标准均值函数:
--mean :: Integer -> Integer -> [Integer] -> Double
mean :: Integer -> Int -> [Integer] -> Double
mean acc n [] = fromIntegral acc / fromIntegral n
mean acc n (x:xs) = mean (acc + x) (n + 1) xs
main = print $ mean 0 0 [1..1000000]
此代码在 O(N) 空间上运行。当我取消注释第一行时,空间消耗变为 O(1)。似乎归结为 fromIntegral 调用,而后者又归结为 toInteger。严格分析器不知何故无法推断出转换是严格的,这对我来说似乎很奇怪。
【问题讨论】: