Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

How are Dynamic Programming algorithms implemented in idiomatic Haskell?

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 it, so I was wondering if it is possible to implement DP algorithms in an FP way.

What functional programming constructs can be used to do that?

like image 962
Vanwaril Avatar asked Feb 12 '11 07:02

Vanwaril


People also ask

What is Haskell programming language used for?

Haskell is the main technology that helps us deliver high quality software. There are various criteria to judge software quality, but the most important ones are correctness, performance, and maintainability. Haskell facilitates writing code that scores high on all of these accounts: Correctness.

How is Haskell different from other programming languages?

Unlike some other functional programming languages Haskell is pure. It doesn't allow any side-effects. This is probably the most important feature of Haskell. We've already briefly discussed the benefits of pure, side-effect free, programming - and there's not much more we can say about that.

Why Haskell is the best programming language?

Haskell's advantages include: it, by default, uses lazy evaluation, which means things only get evaluated if they are needed. This can result in faster programs. it includes automatic memory management to make it memory safe and avoid memory leaks and overflows (a common problem in languages like C or C++).


1 Answers

The common way to do this is via lazy memoization. In some sense, the recursive fibonacci function can be considered dynamic programming, because it computes results out of overlapping subproblems. I realize this is a tired example, but here's a taste. It uses the data-memocombinators library for lazy memoization.

import qualified Data.MemoCombinators as Memo  fib = Memo.integral fib'     where     fib' 0 = 0     fib' 1 = 1     fib' n = fib (n-1) + fib (n-2) 

fib is the memoized version, and fib' just "brute forces" the problem, but computes its subproblems using the memoized fib. Other DP algorithms are written in this same style, using different memo structures, but the same idea of just computing the result in a straightforward functional way and memoizing.

Edit: I finally gave in and decided to provide a memoizable typeclass. That means that memoizing is easier now:

import Data.MemoCombinators.Class (memoize)  fib = memoize fib'     where     fib' :: Integer -> Integer  -- but type sig now required      ... 

Instaead of needing to follow the type, you can just memoize anything. You can still use the old way if you like it.

like image 125
luqui Avatar answered Oct 14 '22 05:10

luqui