2012-06-24 11 views
7

in F # posso facilmente fareF # generare una sequenza/matrice di date

let a = [1 .. 10];; 

Allora perché non posso fare

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


let dateList = [a .. b] 

dà un errore Type constraint mismatch. The type DateTime is not compatible with type TimeSpan

risposta

14

ci sono due problemi: in primo luogo è necessario specificare l'intervallo che si desidera utilizzare tra gli elementi dell'elenco. Questo sarebbe un TimeSpan, tuttavia non ha un membro statico Zero.

Questo vincolo è richiesto dal skip range operator che richiede il tipo di 'step' di avere statici (+) e Zero membri

È possibile definire la propria struttura che supporta le operazioni necessarie però:

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

È possono poi fare:

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

Edit: Ecco una sintassi alternativa utilizzando i sindacati discriminati che si può preferire:

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

Funziona magnificamente ... Esiste un collegamento che spiega cosa sta succedendo? Perché è richiesto Zero? Anche quell'operatore (+). –

+0

@KnowsNotMuch - Richiesto dall'operatore "skip range" - Ho aggiornato la risposta con un collegamento. – Lee

+1

@KnowsNotMuch - cosa sta effettivamente succedendo - il passo deve iniziare da 0 e poi aumentare - se si guarda la firma, il passaggio non deve avere lo stesso tipo degli endpoint. –

11

Ecco un modo funky di generare un elenco di date. Nota Non mi sto prendendo credito per questo come l'ho preso da qualcun altro.

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

Restituisce:

Val IT: lista DateTime = [01/12/2013 00:00:00; 02/12/2013 00:00:00; 03/12/2013 00:00:00; 04/12/2013 00:00:00]