gpt4 book ai didi

F# 中的递归 |发生了什么?

转载 作者:行者123 更新时间:2023-12-02 23:29:00 24 4
gpt4 key购买 nike

我找到了一个 f# 递归函数的基本示例,它接受一个列表并返回一个仅包含偶数整数的列表。大部分内容我都明白,但还是有一点不太明白。

let numbers = [1..4]
let rec even ls =
match ls with
| [] -> []
|head :: tail when head % 2 = 0 -> head :: even tail
|_::tail -> even tail

与 head 匹配的行让我感到困惑。我就是这样读的。当 head 为偶数时,将 head 追加到 tail,然后再次调用 even tail。因为我们将头附加到尾,那岂不是会陷入一遍又一遍地添加头的循环中吗?
另外,最后一行 _::tail 我认为意味着“什么也不做,再次递归”,但是我在 f# 中查找了运算符 _,它说它是通配符模式。这是否本质上意味着如果我的前两场比赛都没有涵盖,就做这件事?

希望有人能解释一下! f# 看起来很有趣,但是来自命令式背景,很难理解。

最佳答案

这是一个模式匹配表达式。读取每一行的方法是这样的:箭头左侧 -> 是如何检查数据的指令,箭头右侧是如何处理数据的指令检查结果。

将此应用于您的案例,请遵循注释(为了清楚起见,我插入了一些换行符):

match ls with    // Look at `ls`

| [] -> // when `ls` is an empty list,
[] // return an empty list

| head :: tail // when `ls` is a `head` attached to a `tail`,
when head % 2 = 0 -> // AND `head` is an even number,
head :: even tail // call `even tail`, attach `head` to it, and return that result

| _::tail -> // when `ls` is "something" attached to a `tail`,
even tail // call `even tail` and return that result

请注意,最后一种情况将适用于第二种情况适用的所有情况。这种歧义是通过案例的顺序来解决的:程序将尝试根据每个案例依次匹配(“查看”,“检查”)数据,并为第一个匹配的案例执行代码。

您似乎忽略了另一个微妙的点:不变性。该列表是不可变的。您无法就地“更新”(“更改”、“更改”)列表。如果您有一个列表,它将始终保持这种状态,编译器保证这一点。相反,数据在程序中演变的方式是基于旧数据创建新数据。特别是,如果您说 a::b,这不会修改列表 b,而是创建一个新列表,其中 a是头,b 是尾。

这些是 F# 中非常基本的概念,事实上您缺少它们,这表明您才刚刚开始了解该语言(也许还刚刚开始了解一般的函数式编程)。如果这是真的,我建议首先阅读一些介绍性 Material 以熟悉基本概念。我最喜欢的是fsharpforfunandprofit.com ,我怎么推荐都不为过。

关于F# 中的递归 |发生了什么?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/48969362/

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