Memoisation


Identity: Memoisation
Category: Data MultiModule
Classifiers: data abstraction
Internal cross references:
External cross references:

Language: This has been described in terms of Haskell, but will apply to any language with abstract data types.

Description: Memoise a definition over an ADT as a value which extends each constructor of the carrier type.

data Tree a 
 = Leaf a |
   Node a (Tree a) (Tree a)

flatten :: Tree a -> [a]

flatten (Leaf x) = [x]
flatten (Node x s t)
  = x : flatten s ++ flatten t



data Tree a
  = Leaf { val::a, flatten::[a] } |
    Node { val::a, left,right::(Tree a), flatten::[a] }

leaf x     = Leaf x [x]

node x l r = Node x l r (x : (flatten l ++ flatten r))

General comment:

Memoisation can be problematic in a lazy language; in order to ensure prompt computation of the memoised value, it is possible to make the constructors strict in their final arguemnts.

Left to right comment:

This refactoring memoises the computation of flatten in the smart constructors leaf and node, so that the final field of each constructor holds the corresponding value of flatten.

Right to left comment:

In this direction the refactoring removes the memoisation, and replaces it with a separate computation of the value of flatten.

Left to right conditions:

The definition of the function to be memoised needs to be primitive recursive: the value of the function on x:xs should depend only on x, xs and the value of the function on xs.

Right to left conditions:

The memoised code needs to have arisen through a transformation such as this.