Haskell调用依赖值的函数时会重新求值该值吗?附OpenGL场景代码
voxel on subsequent calls to function2? Short Answer
Nope, Haskell won't re-evaluate voxel when you call function2 2.0 after function2 1.0—it'll reuse the already computed value.
Deep Dive
Let's break down why this works the way it does, using your code as a reference:
First, look at how voxel is defined:
voxel :: MyType voxel = f 2
This is a top-level binding (it lives outside any function), and it's a pure function call (f 2). Haskell's default behavior for top-level pure bindings is value sharing—once the value is computed once, it's cached and reused everywhere it's referenced.
Here's the play-by-play:
- When you first call
function2 1.0, it passesvoxeltofunction1. At this point,voxelis just an unevaluated "thunk" (a placeholder for the expressionf 2). - When
function1actually needs to use the concrete value ofvoxel(to build yourMyOtherTypegraphics element), Haskell will runf 2exactly once, store the resultingMyTypevalue in memory, and replace thevoxelthunk with this computed result. - The second time you call
function2 2.0,voxelnow points directly to that already computedMyTypevalue. There's no reason to re-runf 2—Haskell just grabs the cached value and passes it tofunction1again.
A key point here is that f is pure: its output depends only on its input (2), and it has no side effects. Since f 2 will always produce the same MyType value, sharing that result is completely safe and efficient. If f had side effects (like reading from a file or generating random numbers), this wouldn't hold—but your type signature tells us it's pure, so we're good.
Even if voxel were a local binding inside a function (instead of top-level), as long as it's not redefined per call, Haskell would still share it. But top-level bindings get this sharing behavior automatically in all standard Haskell compilers (like GHC), which is perfect for your OpenGL use case—you don't want to recompute the voxel data every time the user adjusts a value like y!
内容的提问来源于stack exchange,提问作者Stéphane Laurent

