Solving the Burst Balloon problem using Dynamic Programming
Your use of Array for memoization can be extracted into array-memoize.

If one can stop instead of having negative balloons decrease score, go can be condensed into one case.

import Data.Function.ArrayMemoize (arrayMemoFix)
import Data.Array ((!), listArray)

burstDP :: [Int] -&gt; Int
burstDP l = arrayMemoFix ((0,0), (len+1, len+1)) go (1, len) where
  go ds (left, right) = maximum $ 0 :
    [ds (left, k-1) + ds (k+1, right) + b (left-1)*b k*b (right+1) | k &lt;- [left..right]]
  b = (!) $ listArray (0, len+1) (1 : l ++ [1])
  len = length l


If you don't care too much about performance, we can also memoize directly on the balloon list:

burstDP :: [Int] -&gt; Int
burstDP = memoFix3 go 1 1 where go ds l r b = maximum
  [ ds left l x + ds right x r + l*x*r
  | (left, x:right) &lt;- zip (inits b) (tails b)
  ]