Running the following program will print “space overflow: current size 8388608 bytes.” I have read this and this, but still don’t know how to resolve my problem. I am using foldr, shouldn’t it be guaranteed to be “tail recursive”?
I feel great about Haskell so far until I know I should prevent “space overflow” when using the powerful recursion. 🙂
module Main where
import Data.List
value a b =
let l = length $ takeWhile (isPrime) $ map (\n->n^2 + a * n + b) [0..]
in (l, a ,b)
euler27 = let tuple_list = [value a b | a <-[-999..999] , b <- [-999..999]]
in foldr (\(n,a,b) (max,v) -> if n > max then (n , a * b) else (max ,v) ) (0,0) tuple_list
main = print euler27
EDIT: remove the definiton of isPrime for simplicity
As pierr answered, you should use
foldl'. For more details:foldl'calculates its “left-side” before giving it to your fold step.foldrgives your fold step a “thunk” for the right-side value. This “thunk” will be calculated when needed.Let’s make a sum with
foldrand see how it evaluates:And with
foldl': (tag omitted in code because SO doesn’t display it nicely)In good uses for
foldr, which don’t leak. the “step” must either:Examples of good
foldrusage: