Current section
Files
Jump to
Current section
Files
lib/memoz.ex
defmodule MemoZ do
@moduledoc """
MemoZ run recursive while memoizing anonymous functions.
"""
@doc """
`init` to your anonymous recursive function, will make memoize.
### Example
MemoZ.init(fn f ->
fn
0 -> 0
1 -> 1
x -> f.(x-1) + f.(x-2)
end
end).(100) #=> 354224848179261915075
"""
def init(f) do
fn x ->
{:ok, pid} = Agent.start_link &Map.new/0
try do
fix(pid, f).(x)
after
Agent.stop pid
end
end
end
defp fix(pid, f) do
fn x ->
x.(x)
end.(
fn x ->
f.(&(get_or_else_update(pid, &1, fn -> x.(x).(&1) end)))
end
)
end
defp get_or_else_update(pid, k, f) do
case Agent.get(pid, &Map.get(&1, k)) do
nil ->
v = f.()
Agent.update(pid, &Map.put(&1, k, v))
v
v -> v
end
end
end