Functional programming 斐波那契记忆长生不老药

Functional programming 斐波那契记忆长生不老药,functional-programming,elixir,fibonacci,memoization,Functional Programming,Elixir,Fibonacci,Memoization,我在学习函数式编程,我用elixir做了一个简单的斐波那契 我知道在函数式编程中不可能改变值,我编写了一个代码,使fibonacci具有记忆功能,但代码不好。 如何改进此代码 defmodule Fib do def fib_memoized(0, memo) do {0, memo} end def fib_memoized(1, memo) do {1, memo} end def fib_memoized(n, memo \\ %{}) do

我在学习函数式编程,我用elixir做了一个简单的斐波那契

我知道在函数式编程中不可能改变值,我编写了一个代码,使fibonacci具有记忆功能,但代码不好。 如何改进此代码

defmodule Fib do
  def fib_memoized(0, memo) do
    {0, memo}
  end

  def fib_memoized(1, memo) do
    {1, memo}
  end

  def fib_memoized(n, memo \\ %{}) do
    if Map.has_key?(memo, n) do
      { memo[n], memo }
    else
      {n1, memo1} = fib_memoized(n-1, memo)
      {n2, memo2} = fib_memoized(n-2, memo1)

      value = n1+n2

      {value, Map.merge(memo2, %{n => value})}
    end
  end

  def fib(n) do
    { value, _ } = fib_memoized(n)
    value 
  end
end

IO.puts Fib.fib(1000)
在javascript中,可以生成高阶函数,保存“映射”并更新此映射

例:


有可能做出类似的东西吗?

通常,当我必须将状态存储在长生不老药中时,我会启动一个过程来实现。在斐波那契的例子中,一个很适合

可以这样写:

def模块Fib-do
使用代理
def启动do
Agent.start_链接(fn->%{0=>0,1=>1}end,名称:_模块_;
终止
def fib(n)do
cached_value=Agent.get(_模块&(Map.get(&1,n)))
如果缓存的值为
缓存的U值
其他的
v=fib(n-1)+fib(n-2)
Agent.update(_模块_,&(Map.put(&1,n,v)))
v
终止
终止
终止
{:好的,{}=Fib.start
IO.puts Fib.Fib(1000)

您在JS中发布到Elixir的片段的逐字翻译如下:

memorization=fn fun->
fn n,acc->
行政协调会=
如果(!acc[n])执行
进程睡眠(1000)
IO.inspect acc,标签:“放……休息……睡觉……Zzzz……”
地图放置(acc,n,fun.(n))
其他的
行政协调会
终止
{acc,Map.get(acc,n)}
终止
终止
乐趣=记忆化(&&1*2)
{acc,{}=IO.inspect fun.(42,%{}),标签:“结果为42”
{acc,{}=IO.inspect fun.(42,acc),标签:“42的结果”
{acc,{}=IO.inspect fun.(3.14,acc),标签:“3.14的结果”
{{{,}=IO.inspect fun.(3.14,acc),标签:“3.14的结果”
导致:

#只要把。。。需要休息一下。。。睡觉。。。Zzzz…:%{}
#42的结果:{%{42=>84},84}
#42的结果:{%{42=>84},84}
#只是把。。。需要休息一下。。。睡觉。。。Zzzz…:%{42=>84}
#3.14的结果:{%{42=>84,3.14=>6.28},6.28}
#3.14的结果:{%{42=>84,3.14=>6.28},6.28}
有必要通过累加器,因为长生不老药中没有全局状态。哦,等等,真的有


我已经编写了一个详细的示例和现成的代码。

在《真实世界Ocaml》一书中谈到了记忆递归函数。这些知识可以翻译成任何需要通用
记忆功能的语言。它甚至在其中一个例子中使用了斐波那契程序。希望这有帮助:我认为这是一个惯用的解决方案。
function memoization(fn) {
    let memo = {}
    return function (n) {
      if(!memo[n]) {
        memo[n] = fn(n)
      }
      return memo[n]
    }
  }