与F#中的元组匹配的不完整模式 [英] Incomplete pattern matching a tuple in F#
问题描述
我定义了一个点
type TimeSeriesPoint<'T> =
{ Time : DateTimeOffset
Value : 'T }
和一系列
type TimeSeries<'T> = TimeSeriesPoint<'T> list
我假设此列表中的点按时间排序.
where I assume the points in this list are ordered by time.
我正在尝试压缩两个时间序列,通常它们会在同一时间点,但是其中两个都可能缺少点.
I am trying to zip two time series, where, in general, they will have points with the same time, but there might be some points missing in either of them.
有什么主意,为什么我在下面的代码中收到模式匹配不完整的警告?
Any idea why I get a warning for incomplete pattern matches in the code below?
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
如果我这样写,我不会得到警告,但是它是尾递归的吗?
If I write it this way, I get no warning, but is it tail recursive?
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
防护是一种反模式.
In general, it is an anti-pattern to have a when
guard in the last pattern.
在zip
中,通过除去冗余保护装置,可以达到与zip'
相同的效果:
In zip
, you can achieve the same effect as zip'
does by removing the redundant guard:
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
之后没有额外的工作.
Both two functions are tail recursive since there is no extra work after a recursive call to loop
.
这篇关于与F#中的元组匹配的不完整模式的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!