8

在 F# 中,我可以轻松做到

let a = [1 .. 10];;

那为什么我不能

let a = DateTime.Parse("01/01/2012")
let b = DateTime.Parse("01/01/2020")


let dateList = [a .. b]

它给出了一个错误Type constraint mismatch. The type DateTime is not compatible with type TimeSpan

4

2 回答 2

18

有两个问题 - 首先,您需要指定要在列表元素之间使用的间隔。这将是一个TimeSpan,但它没有静态Zero成员。

跳过范围运算符需要此约束,它要求“步骤”类型具有静态(+)Zero成员

但是,您可以定义自己的结构来支持所需的操作:

type TimeSpanW = { span : TimeSpan } with
  static member (+) (d:DateTime, wrapper) = d + wrapper.span
  static member Zero = { span = new TimeSpan(0L) }

然后你可以这样做:

let ts = new TimeSpan(...)
let dateList = [a .. {span = ts} .. b]

编辑:这是使用您可能更喜欢的可区分联合的替代语法:

type Span = Span of TimeSpan with
  static member (+) (d:DateTime, Span wrapper) = d + wrapper
  static member Zero = Span(new TimeSpan(0L))

let ts = TimeSpan.FromDays(1.0)
let dateList = [a .. Span(ts) .. b]
于 2012-06-24T10:04:22.073 回答
12

这是一种生成日期列表的时髦方法。请注意,当我从其他人那里得到它时,我对此没有任何信任。

open System
let a = new DateTime(2013,12,1)
let b = new DateTime(2013,12,5)
Seq.unfold (fun d -> if d < b then Some(d, d.AddDays(1.0)) else None) a
 |> Seq.toList;;

它返回:

验证它:日期时间列表 = [01/12/2013 00:00:00; 2013 年 2 月 12 日 00:00:00;2013 年 3 月 12 日 00:00:00;04/12/2013 00:00:00]

于 2013-12-03T21:26:13.753 回答