gpt4 book ai didi

haskell - Haskell 的惰性是如何发挥作用的?

转载 作者:行者123 更新时间:2023-12-01 23:52:53 25 4
gpt4 key购买 nike

考虑这个将列表中所有元素加倍的函数:

doubleMe [] = []
doubleMe (x:xs) = (2*x):(doubleMe xs)

然后考虑表达式

doubleMe (doubleMe [a,b,c])

很明显,在运行时,它首先扩展到:

doubleMe ( (2*a):(doubleMe [b,c]) )

(这很明显,因为据我所知不存在其他可能性)。

但我的问题是:到底为什么现在扩展到

2*(2*a) : doubleMe( doubleMe [b,c] )

而不是

doubleMe( (2*a):( (2*b) : doubleMe [c] ) )

直觉上,我知道答案:因为 Haskell 很懒。但有人能给我更准确的答案吗?

列表是否有什么特殊之处导致了这种情况,或者这个想法比列表更普遍?

最佳答案

doubleMe (doubleMe [a,b,c]) 不会扩展为 doubleMe ( (2*a):(doubleMe [b,c]) )。它扩展为:

case doubleMe [a,b,c] of
[] -> []
(x:xs) -> (2*x):(doubleMe xs)

即先展开外层函数调用。这是惰性语言和严格语言之间的主要区别:扩展函数调用时,您不会首先评估参数 - 而是用函数调用体替换函数调用,并暂时保留参数不变。

现在需要扩展doubleMe,因为模式匹配需要知道其操作数的结构才能对其求值,因此我们得到:

case (2*a):(doubleMe [b,c]) of
[] -> []
(x:xs) -> (2*x):(doubleMe xs)

现在模式匹配可以替换为第二个分支的主体,因为我们现在知道第二个分支是匹配的分支。因此,我们用 (2*a) 代替 x,用 doubleMe [b, c] 代替 xs,得到:

(2*(2*a)):(doubleMe (doubleMe [b,c]))

这就是我们得出结果的方式。

关于haskell - Haskell 的惰性是如何发挥作用的?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/28302972/

25 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com