I\'ve seen the other post about this, but is there a clean way of doing this in Haskell?
As a 2nd part, can it also be done without making the function monadic?
The package data-memocombinators on hackage provides lots of reusable memoization routines. The basic idea is:
type Memo a = forall r. (a -> r) -> (a -> r)
I.e. it can memoize any function from a. The module then provides some primitives (like unit :: Memo () and integral :: Memo Int), and combinators for building more complex memo tables (like pair :: Memo a -> Memo b -> Memo (a,b) and list :: Memo a -> Memo [a]).