1votos

Abstraer un calendario mensual en F#

por josejuan hace 3 años

Un port directo de la versión en Haskell.

Implementa una API para tu lenguaje preferido, que permita generar un calendario mensual de tal forma que tu API pueda ser utilizada para generar calendarios en cualquier soporte (texto, html, una API gráfica, etc...).

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
// repo con ejemplos en: https://github.com/josejuan/fsharp-calendar 
namespace Calendar 
 
module Render = 
 
    open System 
 
    type Cell = VSeparator 
                | HSeparator 
                | MonthHeader   of DateTime 
                | WeekDayHeader of DateTime 
                | JustDay       of DateTime 
                | EmptyDay 
 
    let makeMonthCalendar (d : DateTime) (weekDay : DayOfWeek): Cell seq seq = 
        let rec monthDayB (q : DateTime) = 
            if q.Month = d.Month 
                then seq { yield JustDay q; yield! monthDayB (q.AddDays(1.)) } 
                else seq { while true do yield EmptyDay } 
        let rec monthDayA (wd : DayOfWeek) = 
            if wd = d.DayOfWeek 
                then monthDayB d 
                else seq { yield EmptyDay; yield! monthDayA (enum<DayOfWeek> ((1 + int wd) % 7)) } 
        seq { 
            yield seq { yield MonthHeader d } 
            yield Seq.unfold (fun (f : DateTime) -> Some((f, f.AddDays(1.)))) d |> 
                    Seq.skipWhile (fun f -> f.DayOfWeek <> weekDay) |> 
                    Seq.take 7 |> 
                    Seq.map WeekDayHeader 
            yield! monthDayA weekDay |> Seq.take 42 |> chunks 7 |> Seq.map Array.toSeq 
                   
 
    let makeCalendar (cols : int) (rows : int) (idate : DateTime) (weekDay : DayOfWeek) : Cell seq seq = 
        let vsep = seq { while true do yield seq { yield VSeparator } } 
        let hsep = seq { while true do yield HSeparator } |> Seq.take (8 * cols - 1) 
        chunks cols (seq { for i in 0 .. (cols * rows - 1) do yield makeMonthCalendar (idate.AddMonths(i)) weekDay }) |> 
        Seq.map Array.toSeq |> 
        Seq.map (Seq.reduce (fun a b -> Seq.zip3 a vsep b |> Seq.map (fun (r, s, t) -> seq { yield! r; yield! s; yield! t }))) |> 
        Seq.reduce (fun a b -> seq { yield! a; yield hsep; yield! b }) 
 
    let renderCalendar : (('b seq -> 't) -> (Cell seq -> 'b) -> int -> int -> int -> int -> DayOfWeek -> 't) = 
        fun joinRows renderCell cols rows year month weekDay -> 
            makeCalendar cols rows (new DateTime(year, month, 1)) weekDay |> 
            Seq.map renderCell |> 
            joinRows 
3 comentarios
0votos

Escrito por jmgomez hace 3 años

Buena

Cómo vas viendo FSharp? (no desde un punto de vista formal, que ya sé lo que piensas xD xD), más bien si ves opciones de que reemplace CSharp en algunas partes de tu flujo de trabajo
0votos

Escrito por josejuan hace 3 años

Pues lo veo más o menos igual XD XD pero tiene puntos interesantes que merecen la pena, para poder emitir un juicio hay que haberlo trasteado bien y yo no lo he hecho, no se si podrá reemplazarlo.

No me disgusta (de hecho me gusta) salir de mi zona de confort, pero siempre que trasteo con F# me salen pitos (como ahora con el tema de las dependencias) pero es una cuestión más de animosidad por mi parte que del lenguaje.

Hay que tener en cuenta que muchas cosas que parecen "culpa" del lenguaje con frecuencia es porque no sabemos hacerlo bien, con calma XD XD

( ¿Qué tal el tema? ;) )
0votos

Escrito por jmgomez hace 3 años

"me salen pitos.." xD xD Ya, entiendo lo que dices. Aparte de que no soy tan purista como tú (ni de lejos, vamos :P)

Sobre lo de las dependencias, creo que es por el algoritmo de inferencia (¿no?), y tampoco lo veo como algo malo (aunque sí coñazo).

El tema va "encaminado", si quieres detalles te escribo ;)

Comenta la solución

Tienes que identificarte para poder publicar tu comentario.