gpt4 book ai didi

haskell - 为什么 toInteger::Int -> Integer 是惰性的?

转载 作者:行者123 更新时间:2023-12-02 15:39:52 24 4
gpt4 key购买 nike

我有以下代码:

{-# 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 调用,而 fromIntegral 调用又归结为 toInteger。严格分析器以某种方式无法推断转换是严格的,这对我来说似乎很奇怪。

最佳答案

对您的编辑的回应:累积参数的 O(N) 空间泄漏的危险是众所周知的,至少对于 Haskell 程序员来说是这样。应该众所周知但并非如此的是,无论什么语言,您都不应该相信优化器能为程序的空间和时间行为提供渐近保证。 我不明白我自己编写的简单优化器的含义,更不用说像 GHC 前端那样的复杂东西,以及严格分析器、内联器和其他所有东西。

关于你的两个问题,

Why doesn't GHC's strictness analyzer optimize this particular code, when it does optimize very similar code?

谁知道? (也许 Simon PJ 知道,也许不知道。)如果您关心性能,则不应该依赖严格性分析器。这给我们带来了第二个隐含的问题:

How can I avoid O(N) space costs on this function and on every other function that uses accumulating parameters?

通过在累积参数上添加严格注释,强制在每次尾递归调用时对它们进行评估。

关于haskell - 为什么 toInteger::Int -> Integer 是惰性的?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/2749997/

24 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com