3

I read this answer which made it sound like when a shared value is evaluated, it is only evaluated once and then the result is stored. For example:

x = 2 + 2
y = 2 + x
z = 3 + x

Here, x is evaluated once and then stored as 4, and it is never evaluated again? At least that was my assumption. My code has a value that gets re-calculated every time it is referenced. It is a pure value. When would this happen, and how can I force Haskell to remember the value once it is calculated?

Example:

x = [1, 1, 2]
count = fst $ getCounts x

Here, count gets evaluated every time it is referenced.

Community
  • 1
  • 1
Vlad the Impala
  • 15,572
  • 16
  • 81
  • 124
  • 2
    Are you compiling with optimizations? If so, and still seeing this behavior, then you have likely turned off the monomorphism restriction without actually understanding it. – Daniel Wagner Jan 22 '12 at 05:26
  • How do you know it is? While Haskell compilers can optimise however they like and, when it can show the computation is cheap, GHC may duplicate work, I doubt it would happen in a case with a top-level binding like this, unless `getCounts` is very simple indeed. – ehird Jan 22 '12 at 05:27
  • ehird: I'm using trace to test. Plus, when a simple piece of code takes 5 minutes, you figure it out :P – Vlad the Impala Jan 22 '12 at 05:57

1 Answers1

8

As Daniel Wagner points out, the most likely scenario here is that count is not given an explicit type signature, but you've turned the monomorphism restriction off (e.g. with the NoMonomorphismRestriction language extension). This means that count has a type like

count :: (Num a) => a

This means that GHC treats count like a function (specifically, from the Num typeclass dictionary for any type a, to an a), and so the results are not shared, meaning its value is recomputed on every use.

The best solution is to give count an explicit type signature, e.g.

count :: Int

You should probably do the same for x, too (and, for that matter, all the other top-level definitions in your program).

ehird
  • 40,602
  • 3
  • 180
  • 182