Is fib evaluated from start for each element of cumfib?
fib = (1:1: zipWith (+) fib (tail fib))
cumfib = [ sum $ take i fib | i<-[1..]]
Or are the first i elements cached and reused for element (i+1) of cumsum?
I am more or less guessing that fib is used in the same lambda expression and hence is is calculated only once.
Furthermore, does the implementation of fib matter regarding how often the i-th Fibonacci number is evaluated? My actual problem concerns prime numbers instead of Fibonacci numbers, which I wish to 'cache' to easily evaluate the prime factors of some number n. However, I only use
takeWhile (\x-> x*x<n) primes
of the primes. Since I evaluate the factors for small n first and later for bigger n, this subset of primes increases, and hence I wonder, how often is primes evaluated if I do:
primes = ... some way of calculating primes ...
helpHandlePrimes ... = ... using primes ...
handlePrimes = ... using primes and helpHandlePrimes ...
Please let me know whether primes evaluates once, multiple times, or whether this cannot be determined from how I formulated the question.
A let-bound term is usually shared within its scope. In particular, a top-level term in a module is shared in the entire program. However, you have to be careful about the type of the term. If the term is a function, then sharing means that just the lambda abstraction is shared, so the function isn't memoized. An overloaded term is internally represented as a function, and therefore sharing is rather meaningless for an overloaded term as well.
So if you have a monomorphic list of numbers, then it's going to be shared. By default, a list such as fib
as you've given will be monomorphic, because of the "monomorphism restriction" (actually here's a case where it's useful). However, these days it's in fashion to disable the monomorphism restriction, so in any case I recommend giving an explicit type signature such as
fib :: [Integer]
to be sure and make it clear to everyone that you're expecting this to be a monomorphic list.