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
- 然后
代码>用于在适当的索引处从列表中获取值
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,…]
,因此它可以简单地查找以前计算的值。