Haskell 哈斯凯尔:这是为什么——一个记忆化的例子?

Haskell 哈斯凯尔:这是为什么——一个记忆化的例子?,haskell,dynamic-programming,lazy-evaluation,memoization,Haskell,Dynamic Programming,Lazy Evaluation,Memoization,您好,我从以下位置查看此示例: 我只是想知道为什么这会起作用,因为对我来说,如果你调用memoized_fib(n-2),那么你就是在“创建”一个新的列表并用它做一些事情,在你从中返回后,包含部分结果的列表就会消失?因此,记忆的fib(n-1)根本不会从中受益?记忆的fib是一个,在避免创建新内容方面,它与文字常量一样好。无变量⇒ 没有东西可以绑定新东西⇒ 不创造新东西(简而言之)。我可以解释missingno的观察,它可以帮助你理解你所看到的行为。理解where子句的作用很重要 您提供的代码是

您好,我从以下位置查看此示例:


我只是想知道为什么这会起作用,因为对我来说,如果你调用
memoized_fib(n-2)
,那么你就是在“创建”一个新的列表并用它做一些事情,在你从中返回后,包含部分结果的列表就会消失?因此,记忆的fib(n-1)根本不会从中受益?

记忆的fib
是一个,在避免创建新内容方面,它与文字常量一样好。无变量⇒ 没有东西可以绑定新东西⇒ 不创造新东西(简而言之)。

我可以解释missingno的观察,它可以帮助你理解你所看到的行为。理解
where
子句的作用很重要

您提供的代码是

memoized_fib = (map fib [0 ..] !!)
    where fib = ...
你喜欢哪一种

memoized_fib = let fib = ...
               in \n -> map fib [0 ..] !! n
memoized_fib = \n -> let fib = ...
                     in map fib [0 ..] !! n
missingno展示了以下内容,看起来像一个简单的eta扩展,但事实并非如此

memoized_fib n = map fib [0 ..] !! n
    where fib = ...
去糖衣

memoized_fib = let fib = ...
               in \n -> map fib [0 ..] !! n
memoized_fib = \n -> let fib = ...
                     in map fib [0 ..] !! n

在前一种情况下,您可以看到
fib
结构在
memorized_fib
的调用之间共享,而在后一种情况下,
fib
每次都被重构。

您显示的代码取决于给定编译器的行为。下面是Tom Ellis建议的脱糖衣:

memoized_fib = 
    let   fib 0 = 0
          fib 1 = 1
          fib n = memoized_fib (n-2) + memoized_fib (n-1)
    in
       (map fib [0 ..] !!)
没有任何东西可以保证列表
映射fib[0..]
将被重用,即“共享”。特别是当你省略了类型签名,就像我做的那样,使它成为一个多态定义

最好明确列出清单,给它起个名字:

memoized_fib n = 
    let   fib 0 = 0
          fib 1 = 1
          fib n = g (n-2) + g (n-1)
          g = (fibs !!)
          fibs = map fib [0 ..]
    in
       g n

这是。

如果您将定义更改为
memoized_fib n=map fib[0..],则备忘录将打破您的思维方式!!n
。我不知道害羞,但也许其他人可以解释一下。这是一个关于haskell堆的伟大系列,它可能也解释了这一点(不确定),但即使不是,它也是一本很好的读物!那么这是否意味着只有一个
memized\u fib
实例?如何判断函数是否为CAF?谢谢:)是的,只有一个。您可以对照链接文章中的定义进行检查;)首先谢谢,我无意冒犯,但这里的问题是,在我点击链接后,我发现我对Super combinator一无所知,在点击链接后,我发现我不知道什么是combinator,然后它被定义为“没有自由变量的函数”,自由变量?从没听说过。在学习Haskell之前,我可能错过了最重要的一件事,即首先学习lambda微积分和范畴理论!是的,一点lambda微积分和范畴理论不会有什么坏处@多拉夫蒙:绝对是兰姆达微积分。它是现代函数语言的核心。另一方面,只有当你想编写或理解利用范畴理论结果的库的内部结构时,范畴理论才是必要的。为什么它是共享的?你是说再次调用时,
memonized\u fib=let fib=…
不会重新声明
fib
?它重用先前的
fib
?这是否意味着它等同于在
memorized\u fib
函数外部定义
fib
?是的,它等同于在
memorized\u fib
函数外部定义
fib