F # genereert een reeks/reeks datums

In F # kan ik het gemakkelijk doen

let a = [1 .. 10];;

Waarom kan ik dan niet doen?

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


let dateList = [a .. b]

It gives an error Type constraint mismatch. The type DateTime is not compatible with type TimeSpan

7

2 antwoord

Er zijn twee problemen - ten eerste moet u het interval opgeven dat u wilt gebruiken tussen de elementen van de lijst. Dit zou een TimeSpan zijn, maar het heeft geen statisch Zero -lid.

Deze beperking is vereist door de operator voor overslaan van bereik , waarvoor het 'stap' -type statische vereist (+) en Nul leden

U kunt uw eigen structuur definiëren die echter de vereiste bewerkingen ondersteunt:

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

U kunt dan doen:

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

Edit: Here's an alternative syntax using discriminated unions that you may prefer:

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]
14
toegevoegd
Werkt prachtig ... Is er een link die uitlegt wat er aan de hand is? Waarom is nul vereist? Ook die (+) operator.
toegevoegd de auteur Knows Not Much, de bron
@KnowsNotMuch - Dit wordt vereist door de operator "skip range" - ik heb het antwoord bijgewerkt met een link.
toegevoegd de auteur Lee, de bron
Ik heb een alternatieve methode toegevoegd die erg op elkaar lijkt en ik persoonlijk de voorkeur geef. Ik hoop dat je het niet erg vindt @Lee.
toegevoegd de auteur yamen, de bron
@KnowsNotMuch - wat er feitelijk aan de hand is - de stap moet beginnen bij 0 en dan toenemen - als u naar de handtekening kijkt, hoeft de stap niet hetzelfde type te hebben als de eindpunten.
toegevoegd de auteur John Palmer, de bron

Hier is een funky manier om een ​​lijst met datums te genereren. Merk op dat ik dit helemaal niet op prijs stel omdat ik het van iemand anders heb gekregen.

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;;

Het geeft terug:

val it: DateTime list = [01/12/2013 00:00:00; 02/12/2013 00:00:00;   03/12/2013 00:00:00; 04/12/2013 00:00:00]

11
toegevoegd