与F#中的元组匹配的不完整模式 [英] Incomplete pattern matching a tuple in F#

查看:68
本文介绍了与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屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆