1

Given this function :

e :: Integer -> Integer -> Integer
e _ 1 = 1 
e n m 
 |n == m = e n (n-1) 
 |otherwise = e (n-1) m + e n (m-1)

If I run it in GHCI, the first evaluation has a huge time e 20 1 takes ~10 seconds, but after that calls to even larger numbers are far reduced, ~0.25 seconds. I assume there is some kind of caching happening?

I kind of see why it explodes because each call to e n m makes two more calls, which then each make two calls, etc. so the number of evaluations eventually gets very large, but a lot of them are just the same reference.

Is there anyway to make Haskell realize this, like some kind of automatic lookup table?

5
  • 1
    No there is no caching, this is exactly the reason why this takes that much time. Commented Jul 21, 2018 at 19:37
  • 3
    You can search this site for memoization and see many strategies. Be sure you compile your program instead of time it in the interpreter when you care about performance. Commented Jul 21, 2018 at 19:38
  • You may want to look into the package memoise, which provides memoisation tools. Commented Jul 21, 2018 at 19:55
  • 4
    It is strange that you are seeing the first call take such a long time. Especially e 20 1 which ought to reduce immediately. Try something like print "hello" -- does that also take a long time if it's the first thing you do? Commented Jul 21, 2018 at 21:46
  • I have to wonder if this recurrence has a closed-form solution. Commented Jul 22, 2018 at 19:06

1 Answer 1

3

GHC does not magically produce lookup tables for memoization. That said, there are libraries that make this a lot easier. As @AJFarmar suggests, you could use the memoize package.

import Data.Function.Memoize

e :: Integer -> Integer -> Integer
e = memoFix2 $ \rec -> let e' _ 1 = 1
                           e' n m | n == m = rec n (n-1)
                                  | otherwise = rec (n-1) m + rec n (m-1)
                       in e'
Sign up to request clarification or add additional context in comments.

Comments

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.