sml - 为什么一个折叠尾递归而另一个不是?
问题描述
fun fold1 f acc lst =
case lst of
[] => acc
| hd::tl => fold1 f (f (acc,hd)) tl
fun fold2 f acc lst =
case lst of
[] => acc
| hd::tl => f (fold2 f acc tl, hd)
为什么第一个是尾递归而另一个不是?
我认为它们都是尾递归的。
解决方案
第一个是尾递归的,因为递归调用 (to fold1
) 出现在函数体的末尾(它形成了“尾”):
fold1 f (f (acc,hd)) tl
首先调用f (acc,hd)
,然后将结果(连同f
and tl
)传递给fold1
. 这是函数做的最后一件事;递归fold1
调用的结果被传递给我们的调用者。
第二个不是尾递归的,因为递归调用 (to foldl2
) 不是函数做的最后一件事:
f (fold2 f acc tl, hd)
首先调用fold2 f acc tl
,然后从结果中创建一个元组hd
,然后将该元组传递给f
.
递归调用之后会发生两件事fold2
:元组构造 ( (..., hd)
) 和另一个函数调用 ( f ...
)。特别是,调用的结果fold2
不会直接传递给我们的调用者。这就是为什么这段代码不是尾递归的。
推荐阅读
- c# - 用于删除和创建文件夹的 SSIS 脚本
- powershell - 使用带有 2 列的 powershell 在 CSV 文件上输出序列号和 MAC 地址
- git - Git 与 github 的通信非常慢
- php - 模拟 api 调用就像在 flash 中发生的一样
- java - Java 中未处理的异常错误,即使使用 try-catch
- python - 如何绘制数据,带有 suplots 的预测栏?
- javascript - 为 Vuetify 数据表行添加自定义编号
- ubuntu - 无法解析 kubernetes.default 或服务
- airflow - Airflow 中 XCOM 的最大内存大小
- scala - 从 sbt 插件记录