Ackermann very inefficient with Haskell/GHC

后端 未结 7 908
小鲜肉
小鲜肉 2020-12-23 13:58

I try computing Ackermann(4,1) and there\'s a big difference in performance between different languages/compilers. Below are results on my

7条回答
  •  [愿得一人]
    2020-12-23 14:10

    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.

提交回复
热议问题