【发布时间】:2020-06-13 22:08:32
【问题描述】:
例如,这不是尾调用:
map _ [] = []
map f (x : xs) = f x : map f xs
由(:) 数据构造函数保护的递归调用,因此它不会像其他语言中的等价物那样建立一个巨大的堆栈。它是这样工作的:
map (+1) (1 : 2 : 3 : [])
2 : map (+1) (2 : 3 : [])
2 : 3 : map (+1) (3 : [])
2 : 3 : 4 : map (+1) []
2 : 3 : 4 : []
为什么不
map (+1) (1 : 2 : 3 : [])
2 : map (+1) (2 : 3 : [])
2 : (3 : map (+1) (3 : []))
2 : (3 : (4 : map (+1) []))
2 : (3 : (4 : []))
2 : (3 : [4])
2 : [3, 4]
[2, 3, 4]
这和WHNF有关,但我还是不能很好理解:(
【问题讨论】:
-
这里没有优化,只是惰性求值。
-
你的“为什么不”的开头看起来和你的“像这样工作”一模一样,除了一些多余的括号,之后的所有内容都只是语法糖。
-
@JosephSible-ReinstateMonica 他们希望
[...]代表一个完全实现的列表,这是我的解释。
标签: haskell recursion functional-programming lazy-evaluation tailrecursion-modulo-cons