我一直想知道懒惰评估为何有用.我还没有任何人以有道理的方式向我解释; 最重要的是它最终沸腾到"相信我".
注意:我不是指记忆.
在Haskell中,如何基于第n个Fibonacci数等于第(n-2)个Fibonacci数加上第(n-1)个Fibonacci数的属性生成Fibonacci数?
我见过这个:
fibs :: [Integer]
fibs = 1 : 1 : zipWith (+) fibs (tail fibs)
Run Code Online (Sandbox Code Playgroud)
我真的不明白,或者它是如何产生无限列表而不是包含3个元素的列表.
我如何通过计算实际定义来编写haskell代码,而不是通过使用list函数做一些非常奇怪的事情?
我对Haskell很陌生,我试图围绕Fibonacci序列的懒惰表达如何工作.
我知道之前已经问过这个问题,但是没有一个答案解决了我在查看结果时遇到的问题.
代码是使用的规范 zipWith
fibs = 0 : 1 : zipWith (+) fibs (tail fibs)
Run Code Online (Sandbox Code Playgroud)
我理解以下内容:
zipWith 字面上将两个列表拉到一起tail 抓取除列表的第一个元素之外的所有元素thunks.从我的理解,它首先添加[0,1,<thunk>]和[1,<thunk>]使用zipWith (+)给予[1,<thunk>].所以现在你有
fibs = 0 : 1 : 1 : zipWith (+) fibs (tail fibs)
Run Code Online (Sandbox Code Playgroud)
我用谷歌搜索过的很多参考文献都开始将上面的线"可视化"为
fibs = 0 : 1 : 1 : zipWith (+) [1,1,<thunk>] ([1,<thunk>]).
Run Code Online (Sandbox Code Playgroud)
我的问题是:
为什么 fibs 上面一行中 的组件只对应[1,1,<thunk>] 而不是 [0,1,1,<thunk>]?
不应该fibs包含整个列表加<thunk>?
haskell functional-programming fibonacci lazy-evaluation thunk
我在 Real World Haskell 上遇到了以下句子:
懒惰的评估有一些令人毛骨悚然的效果。假设我们要查找未排序列表的 k 个最小值元素。在传统语言中,显而易见的方法是对列表进行排序并取前 k 个元素,但这很昂贵。为了提高效率,我们将编写一个特殊的函数,一次性获取这些值,并且它必须执行一些中等复杂的簿记。在 Haskell 中,先排序再取的方法实际上表现良好:懒惰确保列表只会被排序到足以找到 k 个最小元素。
他们为此提供了一个代码实现:
minima k xs = take k (sort xs)
Run Code Online (Sandbox Code Playgroud)
但真的是这样吗?我认为即使在 Haskell 中,它也应该做一个完整的列表来取出k元素。(想象一下在列表末尾有最小的数字)。我在这里错过了什么吗?
我正在写一个斐波那契序列生成器,我试图理解Haskell中的以下代码
fibs = 1 : 1 : zipWith (+) fibs (tail fibs)
我理解是什么zipWith,但我不完全知道程序如何执行以及它为什么会生成所有的斐波那契数字.我试图理解为什么它不会在函数式语言中使用环境概念终止,如下所示:
最初,因为Haskell的懒惰评估,env应该是fibs : [1,1,x],然后进行评估fibs,解释器评估在这种情况下的x哪个zipWith (+) fibs (tail fibs).在进行评估时zipWith,它fibs : [1,1,2,x]再次得益于Haskell的懒惰评估.并且fibs在这个时候env必然[1,1,2,x].但是,为了进行全面评估fibs,它会继续评估x,我们将回到之前的步骤.
它是否正确?
此外,我注意到当我运行上面的程序时ghci,它立即提示它当前计算的斐波那契序列,为什么?一旦完成所有计算,它不应该打印结果吗?