I try computing Ackermann(4,1)
and there\'s a big difference in performance between different languages/compilers. Below are results on my
The following is an idiomatic version that takes advantage of Haskell's lazyness and GHC's optimisation of constant top-level expressions.
acks :: [[Int]]
acks = [ [ case (m, n) of
(0, _) -> n + 1
(_, 0) -> acks !! (m - 1) !! 1
(_, _) -> acks !! (m - 1) !! (acks !! m !! (n - 1))
| n <- [0..] ]
| m <- [0..] ]
main :: IO ()
main = print $ acks !! 4 !! 1
Here, we're lazily building a matrix for all the values of the Ackermann function. As a result, subsequent calls to acks
will not recompute anything (i.e. evaluating acks !! 4 !! 1
again will not double the running time).
Although this is not the fastest solution, it looks a lot like the naïve implementation, it is very efficient in terms of memory use, and it recasts one of Haskell's weirder features (lazyness) as a strength.