Assume I have
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
Now, assume I call function2
twice, for example function2 1.0
then function2 2.0
(I am in the context of OpenGL
and MyOtherType
is a graphical element to be plotted, and the user can change y
with the keyboard).
Then, at the second call of function2
, does Haskell re-evaluate voxel
?
If I had such a situation in, say for example the C language, I would put a printf
in voxel
to know the answer, but I can't do such a thing with a pure Haskell function (can I?).
Haskell doesn't say what happens.
GHC does not re-evaluate voxel
; generally, let
- and where
-bound values are evaluated at most once. (Though keep in mind that class-polymorphic values behave like functions, where choosing an instance is function application, and these function calls are not memoized, so apparently benign class-polymorphic bindings will probably lead to many reevaluations.)
You can put a "printf
" with Debug.Trace.trace
, but this should be used for educational and debugging purposes only.
import Debug.Trace
voxel = trace "evaluated voxel" $ f 2
It might, it might not, it depends on usage. Once it's evaluated, it'll stay evaluated until it gets garbage collected. As long as you have a reference to it somewhere, it can't be garbage collected.
Why would GHC allow a top level "constant" to be garbage collected? For a contrived example, imagine I have something like
nats :: [Integer]
nats = [0..]
and then another function which indexed into nats
. If GHC couldn't collect nats
, it'd have to store the list [1..n]
(where n
was the value that was indexed) even though I'm not using most of the list.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With