2012-06-24 11 views
7

In F # ich leichtF # erzeugt eine Folge/Reihe von Terminen

tun kann
let a = [1 .. 10];; 

Warum nicht kann ich

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


let dateList = [a .. b] 

einen Fehler zwei Type constraint mismatch. The type DateTime is not compatible with type TimeSpan

Antwort

14

Es gibt gibt Probleme - zuerst müssen Sie das Intervall angeben, das Sie zwischen Elementen der Liste verwenden möchten. Dies wäre ein TimeSpan, jedoch hat es kein statisches Zero Mitglied.

wird diese Einschränkung durch die skip range operator erforderlich, die die ‚Stufe‘ Typ statische (+) und Zero Mitglieder

definieren Sie Ihre eigene Struktur zu haben erfordert, die jedoch die erforderlichen Operationen unterstützt: Sie

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

kann dann tun:

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

Bearbeiten: Hier ist eine alternative Syntax diskriminiert Gewerkschaften, die Sie bevorzugen:

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] 
+0

Funktioniert wunderbar ... Gibt es einen Link, der erklärt, was vor sich geht? Warum ist Zero erforderlich? Auch dieser (+) Operator. –

+0

@KnowsNotMuch - Dies wird vom Operator "Skip Range" benötigt - ich habe die Antwort mit einem Link aktualisiert. – Lee

+1

@KnowsNotMuch - was tatsächlich passiert - der Schritt muss bei 0 beginnen und dann erhöhen - wenn Sie die Signatur betrachten, muss der Schritt nicht den gleichen Typ wie die Endpunkte haben. –

11

Hier ist eine flippige Weise, eine Liste von Daten zu generieren. Hinweis: Ich nehme keine Anerkennung dafür, wie ich es von jemand anderem bekommen habe.

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

Es gibt:

val es: 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]