2012-06-24 8 views
7

en Fa # que pueda hacer fácilmenteF # genera una secuencia/matriz de fechas

let a = [1 .. 10];; 

Entonces por qué no puedo hacer

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


let dateList = [a .. b] 

Se da un error Type constraint mismatch. The type DateTime is not compatible with type TimeSpan

Respuesta

14

hay dos problemas: en primer lugar, debe especificar el intervalo que desea utilizar entre los elementos de la lista. Esto sería un TimeSpan, sin embargo, no tiene un miembro estático Zero.

Esta restricción es requerida por el skip range operator que requiere el tipo 'paso' para tener estáticas (+) y Zero miembros

Puede definir su propia estructura que soporta las operaciones necesarias sin embargo:

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

Usted a continuación, puede hacer:

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

Editar: Aquí hay una sintaxis alternativa utilizando uniones discrimina que es posible que prefiera:

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

Funciona muy bien ... ¿Hay un enlace que explique qué está pasando? ¿Por qué se requiere cero? También ese operador (+). –

+0

@KnowsNotMuch - Esto es requerido por el operador de "rango de omisión" - He actualizado la respuesta con un enlace. – Lee

+1

@KnowsNotMuch - lo que está sucediendo en realidad - el paso tiene que comenzar en 0 y luego aumentar - si observa la firma, el paso no tiene que tener el mismo tipo que los puntos finales. –

11

Aquí está una manera cobarde de generar una lista de fechas. Tenga en cuenta que no estoy tomando ningún crédito por esto en absoluto ya que lo obtuve de otra persona.

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

Devuelve:

Val IT: lista de 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]