I am trying to implement a simple dp algorithm in Haskell (this is for the Collatz hypothesis problem from Project Euler); here is the C ++ equivalent:
map<int,int> a;
int solve(int x) {
if (a.find(x) != a.end()) return a[x];
return a[x] = 1 + ;
}
So, the code I wrote in Haskell looked like this:
solve :: (Memo, Int) -> (Memo, Int)
solve (mem, x) =
case Map.lookup x mem of
Just l -> (mem, l)
Nothing -> let (mem', l') = {- recursive call -}
mem'' = Map.insert x (1+l') mem'
in (mem'', 1+l')
(I think I’m just overestimating the state monad here, but I’ll remind you that at the moment.) The code that causes the solution is trying to find the highest value that it can give for the parameter no more than K = 1e6:
foldl'
(\(mem,ss) k ->
let (mem',x') = solve (mem, k)
in (mem', (x', k):ss))
(Map.singleton 1 1, [(1,1)]) [2..100000]
The above code does not work with stack overflow. This is to be expected, I understand, because it creates a really great, invaluable tone. So I tried to use
x' `seq` (mem', (x',k):ss)
inside foldl ', and it calculates the correct answer for K = 1e5. But this fails for K = 1e6 (stack overflow in 12 seconds). Then I tried to use
mem'' `seq` l' `seq` (mem'', 1+l')
, ( ).
mem'' `deepseq` l' `seq` (mem'', 1+l')
, -, , deepseq mem '', , n * log (n).
? , , , , , , . , , , , .