日期范围的F#生成器?

Kev*_*Won 5 f# generator

我正在尝试编写一个使用生成器语法生成DateTimes列表的函数:

let dateRange = 

    let endDate = System.DateTime.Parse("6/1/2010")
    let startDate = System.DateTime.Parse("3/1/2010")

    seq {
          for date in startDate..endDate do
              if MyDateClass.IsBusinessDay(date) then yield date
        }
Run Code Online (Sandbox Code Playgroud)

但生成器('seq')块无法正确解析.它需要一个时间跨度.虽然生成器语法看起来非常适合我想要做的事情,但除了两个数字之外的任何东西都是非直观的.

  1. 是否可以使用生成器语法来创建DateTime范围?
  2. 是否有更好的方式来思考如何创建范围比我写的(即'in'子句)

kvb*_*kvb 11

如果TimeSpan有静态Zero属性,那么你可以做类似的事情startDate .. TimeSpan(1,0,0,0) .. endDate.即使它没有,你可以创建一个包装器来做同样的事情:

open System

type TimeSpanWrapper = { timeSpan : TimeSpan } with
  static member (+)(d:DateTime, tw) = d + tw.timeSpan
  static member Zero = { timeSpan = TimeSpan(0L) }

let dateRange =
    let endDate = System.DateTime.Parse("6/1/2010")
    let startDate = System.DateTime.Parse("5/1/2010")
    let oneDay = { timeSpan = System.TimeSpan(1,0,0,0) }

    seq {
          for date in startDate .. oneDay .. endDate do
             if MyDateClass.IsBusinessDay(date) then yield date
        }
Run Code Online (Sandbox Code Playgroud)


Ale*_*erg 5

.NET中两个DateTime对象之间的arithemetic差异始终是TimeSpan,这是您的第一个问题.如果您有TimeSpan,它将不会实现IEnumerable <>,因此不能用作序列.但是,您可以编写自己的序列表达式:

let rec dates (fromDate:System.DateTime) (toDate:System.DateTime) = seq {
            if fromDate <= toDate then 
                yield fromDate
                yield! dates (fromDate.AddDays(1.0)) toDate
            }
Run Code Online (Sandbox Code Playgroud)

您可以使用它来创建一个包含范围内所有日期的序列,然后过滤结果:

let result = dates startDate endDate |> Seq.filter (fun dt -> IsBusinessDate(dt))
Run Code Online (Sandbox Code Playgroud)