As Vitus said, in your example this can be done quite simply. The correct implementation of this idea:
multFib :: Integer -> Int -> Integer multFib mult = multFib' where multFib' = (map m_fib [0..] !!) m_fib 0 = 0 m_fib 1 = 1 m_fib n = mult * (multFib' $ n-2) + mult * (multFib' $ n-1)
However, memoisation is not as strong as in your example here: it will only be used to optimize calls to individual functions, but the result list will not be saved at all between subsequent calls to multFib with the same mult .
To do this, you will need to index your memisation search for both arguments, for example:
multFibFullMemo :: Int -> Int -> Integer multFibFullMemo = \mult n -> memo_table !! mult !! n where memo_table = [ [m_fib mult' n' | n'<-[0..]] | mult' <- [0..] ] m_fib _ 0 = 0 m_fib _ 1 = 1 m_fib mult n = m * (multFibFullMemo mult $ n-2) + m * (multFibFullMemo mult $ n-1) where m = toInteger mult
Obviously, this will not be effective if you intend to use it with larger mult arguments: it always needs to skip the list with the length of this number.
More complex memoisation that does not suffer from such problems is provided by libraries such as MemoTrie .
source share