For example, say this is my function:
let fib = n => {
switch (n) {
case 0: return 0
case 1: return 1
default: return fib(n - 1) + fib(n - 2)
}
}
I can then implement a basic memoize function...
let memoize = fn => {
let cache = new Map // mutates!
return _ => {
if (!cache.has(_)) {
cache.set(_, fn(_))
}
return cache.get(_)
}
}
... And use it to implement a memoized fib:
let fib2 = memoize(n => {
switch (n) {
case 0: return 0
case 1: return 1
default: return fib2(n - 1) + fib2(n - 2)
}
})
However, that memoize
function uses mutable state internally. I can reimplement memoize
as a monad, so every time we call fib
it returns a tuple of [value, fib] where fib
now has something in cache, leaving the original fib
unmodified.
The downside of the monad approach is it is not idiomatic JavaScript, and is hard to use without a static type system.
Is there some other way to implement a memoize
function that avoids mutation, without resorting to monads?