6.4.3 分步分析这个示例

本文通过分步解析高阶函数在不同输入情况下的行为,详细解释了Option.bind和Option.map的工作原理。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

6.4.3 分步分析这个示例

这像这样自信地使用高阶函数,可能需要一些时间,尤其是当它们嵌套时。我们将研究来自前面清单中的代码,通过跟踪来看它是如何工作的,如何通过几个样本输入运行的。从抽象的问题"此代码在一般情况下做什么?",到具体的问题"此代码在特定情况下做什么?",通常可以帮助澄清事宜。

让我们看看会发生什么情况,如果我们输入一个无效的值,作为第一个输入。在这种情况下,从 readInput() 返回的第一个值将是 None。若要看看会发生什么,我们可以通过计算来使用计算结果,显示程序是如何一步一步计算的。你可以在清单 6.12 中看到计算过程如何发生的。

Listing 6.12 Evaluation when the first input is invalid

首先,分析 readAndAdd2 的函数体:

readInput() |> Option.bind (fun num –>
readInput() |> Option.map ((+) num) )

读取来自用户的第一个输入,然后,可以用返回的 None 值替换 readInput() 调用:

None |> Option.bind (fun num –>
readInput() |> Option.map ((+) num) )

再分析 Option.bind 调用。这个 lambda 函数没有被调用,因此,整体的返回的结果是:

None

在第一步中,我们用 None 替换这个调用, 就是当我们输入了一些无效数字(例如,一个空字符串)时,此函数返回的值。 第二步更加有趣。这里,Option.bind 函数获取 None 作为其第二个参数值。然而,None 并不携带任意数,因此,绑定不能调用指定的 lambda 函数,只做一件事,就是立即返回 None。

现在,如果我们第一个输入 20,那么,函数的行为又怎样呢?很明显,会有两个不同的选项:一个是,当第二个输入正确时,另一个是,当它是无效时。清单 6.13 显示了如果第二个输入是 22 会发生什么。

Listing 6.13 Evaluation when both inputs are valid

首先,分析 readAndAdd2 的函数体:

readInput() |> Option.bind (fun num –>
readInput() |> Option.map ((+) num) )

从用户处读取第一个输入。然后,可以用第一个输入代替 readInput() 调用。这里,它携带一个值:

Some(20) |> Option.bind (fun num –>
readInput() |> Option.map ((+) num) )

分析 Option.bind call 调用。它调用这个 lambda 函数,并把 20 作为当的参数值。在代码中,我们用实际的值替换 num 的所有匹配项:

readInput() |> Option.map ((+) 20)

从用户处读取第二个输入。读取第二个输入值

Some(22) |> Option.map ((+) 20)

下一步,我们分析 Option.map 调用。它调用提供的函数,并打包所有调用的结果,在在差别联合 Some 情况下:

Some( (+) 20 22 )

最后,分析 + 去处运算符。计算 20 + 22,保持结果打包在 Some 情况下:

Some(42)

第一步是类似于前一种的情况,但这次,我们调用 Option.bind,以 Some(20) 作为参数值。这个选项的值携带一个数字,可以作为 num 的参数值,传递给我们所提供的 lambda 函数。Option.bind 返回从这个函数得到的结果,因此,下一步的结果将是此函数的主体。我们还用实际值,替换 num 的所有匹配项,即 20。

然后,我们用 readInput() 读下一个输入值,它返回 Some(22)。用 Some(22) 替换 readInput(),我们可以分析 Option.map 函数。此操作分析这个函数,它获取作为一个参数值,另外,打包在 Some 识别器中的结果。因此,我们的下一步显示了,我们需要下一步计算加法,并将结果打包在 Some 中。计算之后,我们最后得到的结果是:Some(42)。

跟着这个分步解释之后,对于 Option.bind 和 Option.map 是如何工作的,你应该有了不错的概念。经过这方面信息的准备,我们可以看一下如何在 F# 和 C# 中,实现这两种操作。

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值