This package has some functions to turn recursive functions into dynamic programming recursive functions, for better performance:
Unfortunately, they only have an example for the simplest type of function, and there are no examples on how to use a function of 2 variables. Where can I find an example of how to, for example, turn [Int] -> Int -> Int
function into a dynamic-programming function? The documentation says memo2 takes two Memo
s as first arguments, but I'm not sure what that means.
Solution:
As Hammar described, instead of defining a function as:
foo :: [Int] -> Int -> Int
foo list value = ...
to use memo2:
import qualified Data.MemoCombinators as Memo
foo = Memo.memo2 (Memo.list Memo.integral) Memo.integral foo'
where ... (define foo' with recursive calls to foo.)
Per types and documentation, I believe
should be memoised per
(disclaimer: I haven't used data-memocombinators).
The library defines the type
Memo a
, which is a "memoizer" for functions taking arguments of typea
. The key to understanding how to use this library is to understand how to use and compose these memoizers.In the simple case, you have a single argument function and a simple memoizer, for example a Fibonacci function and a memoizer for
Integral
arguments. In such a case, we obtain the memoized function by applying the memoizer to the function to be memoized:Some memoizers take arguments to customize their behavior, for example
arrayRange
. In the following example,fib n
will only be memoized ifn
is between 1 and 100.The library also provides combinators for building more complex memoizers out of simple ones. For example,
list
, which turns a memoizer fora
into a memoizer for[a]
.Finally, to memoize functions of multiple arguments there are the functions
memo2
andmemo3
, which take a memoizer for each argument plus a function and returns a memoized function.So to memoize your two-argument function, we will need to use
memo2
. We can use theintegral
memoizer for theInt
argument, and for the[Int]
argument we can uselist integral
. Putting this together, we get something like this:However, you can also use more specific memoizers if you know the numbers are in some specified range. For example, if the numbers in the list are between 1 and 10 and the second argument is between 15 and 20:
Whether this makes sense or not, depends on your application.