recursion - 这两个定义是相同的还是不同的
问题描述
查看以下定义:
let rec extractOdds list =
match list with
| [] -> []
| x::xs ->
if x%2=0 then extractOdds xs else x::extractOdds xs
和
let rec extractOdds list =
match list with
| [] -> []
| x::xs ->
let rest = extractOdds xs
if x%2=0 then rest else x::rest
我想知道两者是否相同。因为,第一个定义直接使用递归调用。而第二个创建了一个 let 绑定extractOdds xs
并在if
表达式中使用它。
如果两者的实施方式相同或不同,请指导我。
解决方案
两者之间有一个非常小的差异,在实践中没有影响:
- 第一个版本
x%2=0
在评估之前评估条件extractOdds xs
- 第二个版本
extractOdds xs
在评估条件之前调用x%2=0
该顺序将保留在编译后的代码中(对于第一个版本可能会更长一些),因此两个版本略有不同,但这在任何情况下都无法观察到 - 这两个调用没有副作用并且extractOdds xs
不管x%2=0
istrue
还是false
. _
如果您也使用let
绑定重写第一个版本,这可能会更明显:
let rec extractOdds list =
match list with
| [] -> []
| x::xs ->
if x%2=0 then
let rest = extractOdds xs
rest
else
let rest = extractOdds xs
x::rest
现在您可以清楚地看到,条件的顺序和 let 绑定是唯一的区别:
let rec extractOdds list =
match list with
| [] -> []
| x::xs ->
let rest = extractOdds xs
if x%2=0 then
rest
else
x::rest
编辑:可以使用“累加器”参数编写尾递归版本。这样,您以错误的顺序收集元素,因此您需要在返回结果列表之前反转结果列表:
let rec extractOdds acc list =
match list with
| [] -> List.rev acc
| x::xs ->
extractOdds (if x%2=0 then acc else x::acc) xs
推荐阅读
- python - 是否可以在 NumPy 中在没有循环的情况下逐行索引另一个二维数组?
- javascript - 在Javascript中计算对象数组的多个总和
- python - 对具有混合数据类型和相似度阈值的行进行分组
- python - 类型错误:decompress() 缺少 1 个必需的位置参数:'input_path'
- discord - discord.py 无法从本地文件嵌入图像
- html - 处理卡溢出文本
- python - 我无法弄清楚如何在用户 DND 状态计数器循环中从 json 获取公会 ID 和频道 ID
- python - 如何找到一个数据框列的最接近值并返回其他数据框的列值和位置
- javascript - 测试 id 不应该在响应正文中
- python - 使用 loc 从 numpy 数据框中获取单元格值