Haskell 为什么它是一个记忆功能?

Haskell 为什么它是一个记忆功能?,haskell,Haskell,有人能给我解释一下,为什么下面的代码是备忘录: fib_mem :: Int -> Integer fib_mem = (map fib [0..] !!) where fib 0 = 1 fib 1 = 1 fib n = fib_mem (n-2) + fib_mem (n-1) 我想你是在问这个如何记忆fibfib本身只是一个普通函数。真正的魔法发生在fib_mem=(映射fib[0..),它将fib记忆起来。这个表达式相当于说fib_mem x=(映射f

有人能给我解释一下,为什么下面的代码是备忘录:

fib_mem :: Int -> Integer
fib_mem = (map fib [0..] !!)
where fib 0 = 1
      fib 1 = 1
      fib n = fib_mem (n-2) + fib_mem (n-1) 

我想你是在问这个如何记忆
fib
fib
本身只是一个普通函数。真正的魔法发生在
fib_mem=(映射fib[0..)
,它将
fib
记忆起来。这个表达式相当于说
fib_mem x=(映射fib[0..])!!x
。让我们将其分解,看看它在做什么:

  • [0..]
    是一个无限列表,从
    [0,1,2,3,…]
    开始无限延续
  • map fib[0..]
    fib
    应用于此列表的每个元素,生成一个列表,其中每个元素都是对应于该元素索引的斐波那契数,因此例如
    8
    位于索引
    5
    这是重要的一步;它通过将其应用于每个数字来记忆
    fib
    ,因此一旦强制执行特定索引处的值,就不必重新计算
  • 然后
    用于在适当的索引处从列表中获取值

如果你的意思是“为什么它是一个记忆功能”,因为它是一个and。

你什么意思?为什么?!这个函数使用了记忆技术,中间结果会被保存并在以后重新使用。现在还不清楚你在问什么。更简单的定义是
let fib::Int->Integer;fib=(fib'!!)其中fib'=1:1:zipWith(+)fib'(tail fib')
。这是的副本。由于技术上的原因,我现在无法将其作为复制品关闭。我要说的是,当“普通函数”
fib
在其实现中使用
fib\u mem
时,还有一点魔力。或者至少,这是技术的一部分。@bradrn
它通过将fib应用于每个数字来记忆fib
它为什么会记忆?因为一旦它应用于一个特定的数字,编译器就知道该值位于列表中的索引处,所以下次只需在列表中查找该值。因此,例如,如果您请求了
fib_mem 5
,编译器将在列表中查找索引
5
,结果是它计算的值
fib 5
。下次您请求
fib 5
时,编译器将再次在列表中查找索引
5
,但是列表现在存储为
[…,fib 5,…]
,而不是
[…,8,…]
,因此它可以简单地查找以前计算的值。