Skip to content

Commit

Permalink
Use genneric functions
Browse files Browse the repository at this point in the history
  • Loading branch information
Release-Candidate committed Apr 16, 2021
1 parent 76f0fa8 commit 2501847
Show file tree
Hide file tree
Showing 5 changed files with 73 additions and 119 deletions.
8 changes: 4 additions & 4 deletions src/Tzolkin/Definitions.fs
Original file line number Diff line number Diff line change
Expand Up @@ -217,9 +217,9 @@ module Definitions =
|> sprintf "glyph_%02d"
|> getPNGFromSVG tzolkinImageHeight

let cacheGlyphs = [ for i in [1 .. 20] do getPNGStreamGlyph <| TzolkinGlyph.T.TzolkinGlyph i ]
let cacheGlyphs = [ for i in [1 .. 20] -> getPNGStreamGlyph <| TzolkinGlyph.T.TzolkinGlyph i ]

let cacheNumbers = [ for i in [1 .. 13] do getPNGStreamNumber <| TzolkinNumber.T.TzolkinNumber i ]
let cacheNumbers = [ for i in [1 .. 13] -> getPNGStreamNumber <| TzolkinNumber.T.TzolkinNumber i ]

// Init ========================================================================================

Expand Down Expand Up @@ -272,7 +272,7 @@ module Definitions =
| SetListNumber newNum ->
match newNum, model.ListTzolkinGlyph with
| 0, None -> { model with ListTzolkinNumber = None
DateList = [ for i in [-20 .. 20] do
DateList = [ for i in [-20 .. 20] ->
model.Date + TimeSpan.FromDays (float i)] },
Cmd.none

Expand Down Expand Up @@ -303,7 +303,7 @@ module Definitions =
| SetListGlyph newGlyph ->
match newGlyph, model.ListTzolkinNumber with
| 0, None -> { model with ListTzolkinGlyph = None
DateList = [ for i in [-20 .. 20] do
DateList = [ for i in [-20 .. 20] ->
model.Date + TimeSpan.FromDays (float i)] },
Cmd.none

Expand Down
72 changes: 38 additions & 34 deletions src/TzolkinDate/Generics.fs
Original file line number Diff line number Diff line change
Expand Up @@ -14,40 +14,39 @@ open System
/// Module holding generic functions to use with all 3 Tzolk’in types.
module Generics=

/// Special 'modulo', always returns positive number and `m`, if
/// `n = 0 (mod m)`.
let internal modulo m n =
match n with
| i when i >= 0 -> if n % m = 0 then m else n % m
| _ -> if n % m = 0 then m else m + (n % m)

/// Convert the given Gregorian date `gregorian` to a Tzolk’in day glyph.
///
/// Params:
/// `gregorian` The Gregorian date to convert.
///
/// Returns:
/// The Tzolk’in day glyph of the given Gregorian date.
let fromDate (referenceDate: string * ^T when ^T: (static member ( + ) : ^T * TimeSpan -> ^T)) gregorian =
/// Convert the given Gregorian date `gregorian` to a Tzolk’in day type.
let inline internal fromDate
(referenceDate: string * ^T)
(gregorian: DateTime)
: ^T
=
let (refDate, refTzolkin) = referenceDate
let formatProvider = System.Globalization.DateTimeFormatInfo.InvariantInfo
let reference = System.DateTime.ParseExact (refDate, "dd.MM.yyyy", formatProvider)
refTzolkin + (gregorian - reference)
let dayDiff: TimeSpan = gregorian - reference
(^T: (static member op_Addition : ^T * TimeSpan -> ^T) refTzolkin, dayDiff)

/// Return the next Gregorian date after `start` with a Tzolk’in day glyph of
/// `tzolkinDate`.
/// If `start` has a Tzolk’in day glyph of `tzolkinDate` return the next Gregorian
/// date with a Tzolk’in day glyph of `tzolkinDate` (260 days later).
///
/// Params:
/// `tzolkinDate` The Tzolk’in day glyph to search for.
/// `start` The Gregorian date to start the search.
///
/// Returns:
/// The next Gregorian date (forward in time after the date `start` that
/// has a Tzolk’in day glyph of `tzolkinDate`.
let getNext referenceDate tzolkinDate (start: DateTime) =
/// Return the next Gregorian date after `start` with a Tzolk’in day type.
let inline internal getNext
(referenceDate: string * ^T)
(numElem: int)
(tzolkinDate: ^T)
(start: DateTime)
=
let startTzolkin = fromDate referenceDate start
let dayDiff = tzolkinDate - startTzolkin
start + System.TimeSpan.FromDays (float dayDiff.Days) // FIXXME
let dayDiff = if tzolkinDate - startTzolkin = 0 then numElem else tzolkinDate - startTzolkin
start + System.TimeSpan.FromDays (float dayDiff)

/// Add a `TzolkinGlyph`to the given list of `TzolkinGlyph`, to a length of `length`.
/// Helper function.
let rec private addDate getTzolkin length num start list =
let rec internal addDate getTzolkin length num start list =
let next = getTzolkin start
let nextNum = num + 1
if nextNum < length
Expand All @@ -67,10 +66,15 @@ module Generics=
/// Returns:
/// A list with the next `numDates` Gregorian dates (forward in time after
/// the date `start`) that have the same Tzolk’in day glyph as `tzolkinDate`.
let getNextList referenceDate numDates tzolkinDate start =
let rec getNextTzolkin = addDate (getNext referenceDate tzolkinDate) numDates
//let getNextList
// (referenceDate: string * ^T)
// (numDates: int)
// (tzolkinDate: ^T)
// (start: DateTime)
// =
// let rec getNextTzolkin = addDate (getNext referenceDate tzolkinDate) numDates

getNextTzolkin 0 start []
// getNextTzolkin 0 start []

/// Return the last Gregorian date before or the same as `start` with a Tzolk’in
/// day glyph of `tzolkinDate`.
Expand All @@ -84,9 +88,9 @@ module Generics=
/// Returns:
/// The last Gregorian date (backwards in time before the date `start` that
/// has a Tzolk’in day glyph of `tzolkinDate`.
let getLast referenceDate tzolkinDate start =
let last = System.TimeSpan.FromDays -260.0 |> (+) (getNext referenceDate tzolkinDate start)
if last = start then last + System.TimeSpan.FromDays -260.0 else last
//let getLast referenceDate tzolkinDate start =
// let last = System.TimeSpan.FromDays -260.0 |> (+) (getNext referenceDate tzolkinDate start)
// if last = start then last + System.TimeSpan.FromDays -260.0 else last

/// Return a list of Gregorian dates before `start` with the same Tzolk’in day glyph
/// `tzolkinDate`. The number of elements in the returned list is `numDates`.
Expand All @@ -102,7 +106,7 @@ module Generics=
/// A list with the last `numDates` Gregorian dates (backwards in time
/// before the date `start`) that have the same Tzolk’in day glyph as
/// `tzolkinDate`.
let getLastList referenceDate numDates tzolkinDate start =
let rec getLastTzolkin = addDate (getLast referenceDate tzolkinDate) numDates
//let getLastList referenceDate numDates tzolkinDate start =
// let rec getLastTzolkin = addDate (getLast referenceDate tzolkinDate) numDates

getLastTzolkin 0 start []
// getLastTzolkin 0 start []
39 changes: 9 additions & 30 deletions src/TzolkinDate/TzolkinDate.fs
Original file line number Diff line number Diff line change
Expand Up @@ -52,31 +52,31 @@ module TzolkinDate =
| { Number = num; Glyph = glph } -> $"{string num} {string glph}"

/// Add days to a `TzolkinDate`.
static member (+)(tzolkinDate, i:int) =
static member ( + ) (tzolkinDate, i: int) =
{ Number = tzolkinDate.Number + i
Glyph = tzolkinDate.Glyph + i }

/// Add days to a `TzolkinDate`, order of `int` and `TzolkinDate` changed.
static member (+)(i:int, tzolkinDate) =
static member ( + ) (i: int, tzolkinDate) =
{ Number = tzolkinDate.Number + i
Glyph = tzolkinDate.Glyph + i }

/// Add two `TzolkinDate`. Doesn't really make sense, what would that be
/// conceptually? But define it anyway.
static member (+)(tzolkinDate1, tzolkinDate2) =
static member ( + )(tzolkinDate1, tzolkinDate2) =
{ Number = tzolkinDate1.Number + tzolkinDate2.Number
Glyph = tzolkinDate1.Glyph + tzolkinDate2.Glyph }

/// Add a `System.TimeSpan` to a `TzolkinDate`.
/// Only makes sense with (at least) days, not hours, minutes, or seconds.
static member (+)(tzolkinDate, timeSpan: System.TimeSpan) =
static member ( + ) (tzolkinDate, timeSpan: System.TimeSpan) =
{ Number = tzolkinDate.Number + timeSpan.Days
Glyph = tzolkinDate.Glyph + timeSpan.Days }

/// Add a `System.TimeSpan` to a `TzolkinDate`, other order of `TimeSpan` and
/// `TzolkinDate`.
/// Only makes sense with (at least) days, not hours, minutes, or seconds.
static member (+)(timeSpan: System.TimeSpan, tzolkinDate) =
static member ( + ) (timeSpan: System.TimeSpan, tzolkinDate) =
{ Number = tzolkinDate.Number + timeSpan.Days
Glyph = tzolkinDate.Glyph + timeSpan.Days }

Expand Down Expand Up @@ -199,15 +199,7 @@ module TzolkinDate =
/// Returns:
/// The Tzolk’in day of the given Gregorian date.
let fromDate gregorian =
let (refDate, refTzolkin) = referenceDate

let formatProvider =
System.Globalization.DateTimeFormatInfo.InvariantInfo

let reference =
System.DateTime.ParseExact(refDate, "dd.MM.yyyy", formatProvider)

refTzolkin + (gregorian - reference)
Generics.fromDate referenceDate gregorian

/// Get the Tzolk’in date of today.
let today = fromDate System.DateTime.Now
Expand Down Expand Up @@ -314,20 +306,7 @@ module TzolkinDate =
/// The next Gregorian date (forward in time after the date `start` that
/// has a Tzolk’in date of `tzolkinDate`.
let getNext tzolkinDate start =
let startTzolkin = fromDate start
let dayDiff = tzolkinDate - startTzolkin
start + System.TimeSpan.FromDays(float dayDiff)

/// Add a `TzolkinDate`to the given list of `tzolkinDate`, to a length of `length`.
/// Helper function.
let rec private addDate getTzolkin length num start list =
let next = getTzolkin start
let nextNum = num + 1

if nextNum < length then
addDate getTzolkin length nextNum next (next :: list)
else
List.rev (next :: list)
Generics.getNext referenceDate 260 tzolkinDate start

/// Return a list of Gregorian dates after `start` with the same Tzolk’in date
/// `tzolkinDate`. The number of elements in the returned list is `numDates`.
Expand All @@ -343,7 +322,7 @@ module TzolkinDate =
/// A list with the next `numDates` Gregorian dates (forward in time after
/// the date `start`) that have the same Tzolk’in dates as `tzolkinDate`.
let getNextList numDates tzolkinDate start =
let rec getNextTzolkin = addDate (getNext tzolkinDate) numDates
let rec getNextTzolkin = Generics.addDate (getNext tzolkinDate) numDates

getNextTzolkin 0 start []

Expand Down Expand Up @@ -384,7 +363,7 @@ module TzolkinDate =
/// before the date `start`) that have the same Tzolk’in dates as
/// `tzolkinDate`.
let getLastList numDates tzolkinDate start =
let rec getLastTzolkin = addDate (getLast tzolkinDate) numDates
let rec getLastTzolkin = Generics.addDate (getLast tzolkinDate) numDates

getLastTzolkin 0 start []

Expand Down
33 changes: 10 additions & 23 deletions src/TzolkinDate/TzolkinGlyph.fs
Original file line number Diff line number Diff line change
Expand Up @@ -293,10 +293,7 @@ module TzolkinGlyph =
/// Returns:
/// 20 if `n` = 0 (mod 20)
/// `n` % 20 else.
let modulo20 n =
match n with
| i when i >= 0 -> if n % 20 = 0 then 20 else n % 20
| _ -> if n % 20 = 0 then 20 else 20 + (n % 20)
let modulo20 = Generics.modulo 20

/// The Tzolk’in day glyph type.
type T =
Expand Down Expand Up @@ -379,10 +376,7 @@ module TzolkinGlyph =
/// Returns:
/// The Tzolk’in day glyph of the given Gregorian date.
let fromDate gregorian =
let (refDate, refTzolkin) = referenceDate
let formatProvider = System.Globalization.DateTimeFormatInfo.InvariantInfo
let reference = System.DateTime.ParseExact (refDate, "dd.MM.yyyy", formatProvider)
refTzolkin + (gregorian - reference)
Generics.fromDate referenceDate gregorian

/// Return the next Gregorian date after `start` with a Tzolk’in day glyph of
/// `tzolkinDate`.
Expand All @@ -397,18 +391,8 @@ module TzolkinGlyph =
/// The next Gregorian date (forward in time after the date `start` that
/// has a Tzolk’in day glyph of `tzolkinDate`.
let getNext tzolkinDate start =
let startTzolkin = fromDate start
let dayDiff = if tzolkinDate - startTzolkin = 0 then 20 else tzolkinDate - startTzolkin
start + System.TimeSpan.FromDays (float dayDiff)

/// Add a `TzolkinGlyph`to the given list of `TzolkinGlyph`, to a length of `length`.
/// Helper function.
let rec private addDate getTzolkin length num start list =
let next = getTzolkin start
let nextNum = num + 1
if nextNum < length
then addDate getTzolkin length nextNum next (next :: list)
else List.rev (next :: list)
Generics.getNext referenceDate 20 tzolkinDate start


/// Return a list of Gregorian dates after `start` with the same Tzolk’in day glyph
/// `tzolkinDate`. The number of elements in the returned list is `numDates`.
Expand All @@ -424,7 +408,7 @@ module TzolkinGlyph =
/// A list with the next `numDates` Gregorian dates (forward in time after
/// the date `start`) that have the same Tzolk’in day glyph as `tzolkinDate`.
let getNextList numDates tzolkinDate start =
let rec getNextTzolkin = addDate (getNext tzolkinDate) numDates
let rec getNextTzolkin = Generics.addDate (getNext tzolkinDate) numDates

getNextTzolkin 0 start []

Expand All @@ -441,7 +425,10 @@ module TzolkinGlyph =
/// The last Gregorian date (backwards in time before the date `start` that
/// has a Tzolk’in day glyph of `tzolkinDate`.
let getLast tzolkinDate start =
let last = System.TimeSpan.FromDays -20. |> (+) (getNext tzolkinDate start)
let last =
System.TimeSpan.FromDays -20.
|> (+) (getNext tzolkinDate start)

if last = start then last + System.TimeSpan.FromDays -20. else last

/// Return a list of Gregorian dates before `start` with the same Tzolk’in day glyph
Expand All @@ -459,7 +446,7 @@ module TzolkinGlyph =
/// before the date `start`) that have the same Tzolk’in day glyph as
/// `tzolkinDate`.
let getLastList numDates tzolkinDate start =
let rec getLastTzolkin = addDate (getLast tzolkinDate) numDates
let rec getLastTzolkin = Generics.addDate (getLast tzolkinDate) numDates

getLastTzolkin 0 start []

Expand Down
40 changes: 12 additions & 28 deletions src/TzolkinDate/TzolkinNumber.fs
Original file line number Diff line number Diff line change
Expand Up @@ -56,10 +56,7 @@ module TzolkinNumber =
/// Returns:
/// 13 if `n` = 0 (mod13)
/// `n` % 13 else.
let modulo13 n =
match n with
| i when i >= 0 -> if n % 13 = 0 then 13 else n % 13
| _ -> if n % 13 = 0 then 13 else 13 + (n % 13)
let modulo13 = Generics.modulo 13

/// The Tzolk’in day number type.
type T =
Expand Down Expand Up @@ -139,12 +136,9 @@ module TzolkinNumber =
/// Returns:
/// The Tzolk’in day number of the given Gregorian date.
let fromDate gregorian =
let (refDate, refTzolkin) = referenceDate
let formatProvider = System.Globalization.DateTimeFormatInfo.InvariantInfo
let reference = System.DateTime.ParseExact (refDate, "dd.MM.yyyy", formatProvider)
refTzolkin + (gregorian - reference)
Generics.fromDate referenceDate gregorian

/// Return the next Gregorian date after `start` with a Tzolk’in daday number of
/// Return the next Gregorian date after `start` with a Tzolk’in day number of
/// `tzolkinDate`.
/// If `start` has a Tzolk’in day number of `tzolkinDate` return the next Gregorian
/// date with a Tzolk’in day number of `tzolkinDate` (260 days later).
Expand All @@ -157,18 +151,8 @@ module TzolkinNumber =
/// The next Gregorian date (forward in time after the date `start` that
/// has a Tzolk’in day number of `tzolkinDate`.
let getNext tzolkinDate start =
let startTzolkin = fromDate start
let dayDiff = if tzolkinDate - startTzolkin = 0 then 13 else tzolkinDate - startTzolkin
start + System.TimeSpan.FromDays (float dayDiff)

/// Add a `TzolkinNumber`to the given list of `TzolkinNumber`, to a length of `length`.
/// Helper function.
let rec private addDate getTzolkin length num start list =
let next = getTzolkin start
let nextNum = num + 1
if nextNum < length
then addDate getTzolkin length nextNum next (next :: list)
else List.rev (next :: list)
Generics.getNext referenceDate 13 tzolkinDate start


/// Return a list of Gregorian dates after `start` with the same Tzolk’in day number
/// `tzolkinDate`. The number of elements in the returned list is `numDates`.
Expand All @@ -184,7 +168,7 @@ module TzolkinNumber =
/// A list with the next `numDates` Gregorian dates (forward in time after
/// the date `start`) that have the same Tzolk’in day numbers as `tzolkinDate`.
let getNextList numDates tzolkinDate start =
let rec getNextTzolkin = addDate (getNext tzolkinDate) numDates
let rec getNextTzolkin = Generics.addDate (getNext tzolkinDate) numDates

getNextTzolkin 0 start []

Expand All @@ -201,7 +185,10 @@ module TzolkinNumber =
/// The last Gregorian date (backwards in time before the date `start` that
/// has a Tzolk’in day number of `tzolkinDate`.
let getLast tzolkinDate start =
let last = System.TimeSpan.FromDays -13.0 |> (+) (getNext tzolkinDate start)
let last =
System.TimeSpan.FromDays -13.0
|> (+) (getNext tzolkinDate start)

if last = start then last + System.TimeSpan.FromDays -13.0 else last

/// Return a list of Gregorian dates before `start` with the same Tzolk’in day number
Expand All @@ -219,7 +206,7 @@ module TzolkinNumber =
/// before the date `start`) that have the same Tzolk’in day number as
/// `tzolkinDate`.
let getLastList numDates tzolkinDate start =
let rec getLastTzolkin = addDate (getLast tzolkinDate) numDates
let rec getLastTzolkin = Generics.addDate (getLast tzolkinDate) numDates

getLastTzolkin 0 start []

Expand All @@ -246,9 +233,6 @@ module TzolkinNumber =
/// Returns:
/// The Maya number as a Unicode symbol.
let toUnicodeNum number =
let modulo20 n =
match n with
| i when i < 1 -> if i % 20 = 0 then 20 else abs (i) % 20
| i -> if i % 20 = 0 then 20 else i % 20
let modulo20 = Generics.modulo 20

numberUnicode.[(modulo20 number) - 1]

0 comments on commit 2501847

Please sign in to comment.