Haskell在根据该值调用函数时是否会重新评估该值



假设我有

f :: Int -> MyType
f i = ......
voxel :: MyType
voxel = f 2
function1 :: Double -> MyType -> MyOtherType
function1 x w = ......
function2 :: Double -> MyOtherType
function2 y = function1 y voxel 

现在,假设我调用function2两次,例如function2 1.0然后function2 2.0(我在OpenGL上下文中,MyOtherType是要绘制的图形元素,用户可以使用键盘更改y(。

那么,在function2的第二次调用中,哈斯克尔会重新评估voxel吗?

如果我遇到这种情况,例如 C 语言,我会在voxel中放一个printf来知道答案,但我不能用纯粹的 Haskell 函数做这样的事情(我可以吗?

Haskell没有说会发生什么。

GHC不会重新评估voxel;一般来说,letwhere绑定值最多被评估一次。(但请记住,类多态值的行为类似于函数,其中选择实例是函数应用程序,并且这些函数调用不会被记住,因此显然良性的类多态绑定可能会导致许多重新评估。

你可以用Debug.Trace.trace放一个"printf",但这应该仅用于教育和调试目的。

import Debug.Trace
voxel = trace "evaluated voxel" $ f 2

它可能,也可能不是,这取决于使用情况。评估后,它将保持评估状态,直到它被垃圾回收。只要你在某处有对它的引用,它就不能被垃圾回收。

为什么GHC允许垃圾回收顶级"常数"?举个人为的例子,想象一下我有类似的东西

nats :: [Integer]
nats = [0..]

然后是另一个索引到 nats 的函数。如果 GHC 无法收集nats,它必须将列表存储[1..n](其中n是索引的值(,即使我没有使用大部分列表。

最新更新