Haskell and other functional programming languages are built around the premise of not maintaining state. I\'m still new to how functional programming works and concepts in
If you want to use DP with 2 or 3 parameters (for example, when processing strings) you can use immutable array:
import Data.Array.IArray
answer :: String -> Int
answer s = table ! (1, l)
where
l = length s
--signatyres are needed, because GHC doesn't know what kind of Array we need
--string is stored in Array because we need quick access to individual chars
a :: Array Int Char
a = listArray (1, l) s
table :: Array (Int, Int) Int
table = listArray ((1, 1), (l, l)) [f i j | i <- [1..l], j <- [1..l]]
f i j | i > j = 0
| i == j = 1
| (a ! i) == (a ! j) = 2 + table ! (i+1, j-1)
| otherwise = maximum [table ! (i+1, j), table ! (i, j-1)]
This code solves the following task: given a string S, find the subsequence of S of maximum length, which would be a palyndrome (subsequence doesn't need to be continuous).
Basically, 'f' is the resursive function, and array 'table' is a matrix of all its possible values. Because Haskell is lazy, only needed for the answer values of 'f' are computed. In other words, this is recursion with memoization. So use Data.Memocombinators, which is just the same, but already written by somebody else :)