gpt4 book ai didi

f# - 在 F# 中匹配元组的不完整模式

转载 作者:行者123 更新时间:2023-12-01 11:00:31 25 4
gpt4 key购买 nike

我定义一个点

type TimeSeriesPoint<'T> = 
{ Time : DateTimeOffset
Value : 'T }

和系列

type TimeSeries<'T> = TimeSeriesPoint<'T> list

我假设此列表中的点按时间排序。

我正在尝试压缩两个时间序列,一般来说,它们会有相同时间的点,但其中任何一个都可能缺少一些点。

知道为什么我在下面的代码中收到模式匹配不完整的警告吗?

let zip (series1 : TimeSeries<float>) (series2 : TimeSeries<float>) =
let rec loop revAcc ser1 ser2 =
match ser1, ser2 with
| [], _ | _, [] -> List.rev revAcc
| hd1::tl1, hd2::tl2 when hd1.Time = hd2.Time ->
loop ({ Time = hd1.Time; Value = (hd1.Value, hd2.Value) }::revAcc) tl1 tl2
| hd1::tl1, hd2::tl2 when hd1.Time < hd2.Time ->
loop revAcc tl1 ser2
| hd1::tl1, hd2::tl2 when hd1.Time > hd2.Time ->
loop revAcc ser1 tl2
loop [] series1 series2

如果我这样写,我不会收到任何警告,但它是尾递归吗?

let zip' (series1 : TimeSeries<float>) (series2 : TimeSeries<float>) =
let rec loop revAcc ser1 ser2 =
match ser1, ser2 with
| [], _ | _, [] -> List.rev revAcc
| hd1::tl1, hd2::tl2 ->
if hd1.Time = hd2.Time then
loop ({ Time = hd1.Time; Value = (hd1.Value, hd2.Value) }::revAcc) tl1 tl2
elif hd1.Time < hd2.Time then
loop revAcc tl1 ser2
else
loop revAcc ser1 tl2
loop [] series1 series2

最佳答案

一般来说,在最后一个模式中有一个when守卫是一种反模式。

zip 中,您可以通过删除冗余保护来实现与 zip' 相同的效果:

let zip (series1: TimeSeries<float>) (series2: TimeSeries<float>) =
let rec loop revAcc ser1 ser2 =
match ser1, ser2 with
| [], _ | _, [] -> List.rev revAcc
| hd1::tl1, hd2::tl2 when hd1.Time = hd2.Time ->
loop ({ Time = hd1.Time; Value = (hd1.Value, hd2.Value) }::revAcc) tl1 tl2
| hd1::tl1, hd2::tl2 when hd1.Time < hd2.Time ->
loop revAcc tl1 ser2
| hd1::tl1, hd2::tl2 ->
loop revAcc ser1 tl2
loop [] series1 series2

这两个函数都是尾递归的,因为在递归调用 loop 之后没有额外的工作。

关于f# - 在 F# 中匹配元组的不完整模式,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/11354156/

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