diff options
author | Eduardo Julian | 2022-12-02 19:33:00 -0400 |
---|---|---|
committer | Eduardo Julian | 2022-12-02 19:33:00 -0400 |
commit | 94e5802f594a73245fce0fbd885103b8bf210d57 (patch) | |
tree | 65e5799c0be40f5f015b39bfa6c87c9c27fd9424 /stdlib/source/library/lux/world/time | |
parent | b491dfff00219d5206075ea65468e00ab657075d (diff) |
Added some simple time-series handling machinery.
Diffstat (limited to '')
-rw-r--r-- | stdlib/source/library/lux/world/time.lux | 2 | ||||
-rw-r--r-- | stdlib/source/library/lux/world/time/date.lux | 18 | ||||
-rw-r--r-- | stdlib/source/library/lux/world/time/day.lux | 6 | ||||
-rw-r--r-- | stdlib/source/library/lux/world/time/duration.lux | 2 | ||||
-rw-r--r-- | stdlib/source/library/lux/world/time/instant.lux | 78 | ||||
-rw-r--r-- | stdlib/source/library/lux/world/time/month.lux | 6 | ||||
-rw-r--r-- | stdlib/source/library/lux/world/time/series.lux | 124 | ||||
-rw-r--r-- | stdlib/source/library/lux/world/time/solar.lux | 4 |
8 files changed, 196 insertions, 44 deletions
diff --git a/stdlib/source/library/lux/world/time.lux b/stdlib/source/library/lux/world/time.lux index 0848dbbb8..c324966c5 100644 --- a/stdlib/source/library/lux/world/time.lux +++ b/stdlib/source/library/lux/world/time.lux @@ -56,7 +56,7 @@ (<>.either (|> (<text>.at_most 3 <text>.decimal) (<>.codec n.decimal) (<>.after (<text>.this "."))) - (at <>.monad in 0))) + (of <>.monad in 0))) (with_template [<maximum> <parser> <exception> <sub_parser>] [(exception.def .public (<exception> value) diff --git a/stdlib/source/library/lux/world/time/date.lux b/stdlib/source/library/lux/world/time/date.lux index efa497d60..cc05e8a8c 100644 --- a/stdlib/source/library/lux/world/time/date.lux +++ b/stdlib/source/library/lux/world/time/date.lux @@ -56,7 +56,7 @@ (list ["Value" (n#encoded day)] ["Minimum" (n#encoded ..minimum_day)] ["Maximum" (n#encoded (..month_days year month))] - ["Year" (at //year.codec encoded year)] + ["Year" (of //year.codec encoded year)] ["Month" (n#encoded (//month.number month))]))) (def (padded value) @@ -108,10 +108,10 @@ (def (= reference sample) (let [reference (representation reference) sample (representation sample)] - (and (at //year.equivalence = + (and (of //year.equivalence = (the #year reference) (the #year sample)) - (at //month.equivalence = + (of //month.equivalence = (the #month reference) (the #month sample)) (n.= (the #day reference) @@ -125,16 +125,16 @@ (def (< reference sample) (let [reference (representation reference) sample (representation sample)] - (or (at //year.order < + (or (of //year.order < (the #year reference) (the #year sample)) - (and (at //year.equivalence = + (and (of //year.equivalence = (the #year reference) (the #year sample)) - (or (at //month.order < + (or (of //month.order < (the #month reference) (the #month sample)) - (and (at //month.order = + (and (of //month.order = (the #month reference) (the #month sample)) (n.< (the #day reference) @@ -150,7 +150,7 @@ (<>.either (|> (<text>.at_most 3 <text>.decimal) (<>.codec n.decimal) (<>.after (<text>.this "."))) - (at <>.monad in 0))) + (of <>.monad in 0))) (with_template [<minimum> <maximum> <parser> <exception>] [(exception.def .public (<exception> value) @@ -186,7 +186,7 @@ (def (format value) (-> Date Text) (all text#composite - (at //year.codec encoded (..year value)) + (of //year.codec encoded (..year value)) ..separator (..padded (|> value ..month //month.number)) ..separator (..padded (..day_of_month value)))) diff --git a/stdlib/source/library/lux/world/time/day.lux b/stdlib/source/library/lux/world/time/day.lux index cda78a83f..1871c34fe 100644 --- a/stdlib/source/library/lux/world/time/day.lux +++ b/stdlib/source/library/lux/world/time/day.lux @@ -157,10 +157,10 @@ (exception.def .public (invalid_day number) (Exception Nat) (exception.report - (list ["Number" (at n.decimal encoded number)] - ["Valid range" (.text_composite# (at n.decimal encoded (..number {#Sunday})) + (list ["Number" (of n.decimal encoded number)] + ["Valid range" (.text_composite# (of n.decimal encoded (..number {#Sunday})) " ~ " - (at n.decimal encoded (..number {#Saturday})))]))) + (of n.decimal encoded (..number {#Saturday})))]))) (def .public (by_number number) (-> Nat (Try Day)) diff --git a/stdlib/source/library/lux/world/time/duration.lux b/stdlib/source/library/lux/world/time/duration.lux index fec1db917..ebf76fd4a 100644 --- a/stdlib/source/library/lux/world/time/duration.lux +++ b/stdlib/source/library/lux/world/time/duration.lux @@ -131,7 +131,7 @@ ) (def (encoded duration) - (if (at ..equivalence = ..empty duration) + (if (of ..equivalence = ..empty duration) (all text#composite ..positive_sign (nat#encoded 0) diff --git a/stdlib/source/library/lux/world/time/instant.lux b/stdlib/source/library/lux/world/time/instant.lux index eb50f13e5..b6a5589fa 100644 --- a/stdlib/source/library/lux/world/time/instant.lux +++ b/stdlib/source/library/lux/world/time/instant.lux @@ -18,7 +18,7 @@ ["<[1]>" \\parser (.only Parser)]]] [math [number - ["i" int] + ["i" int (.use "[1]#[0]" interval)] ["f" frac]]] [meta ["@" target] @@ -35,48 +35,59 @@ Int (def .public of_millis - (-> Int Instant) + (-> Int + Instant) (|>> abstraction)) (def .public millis - (-> Instant Int) + (-> Instant + Int) (|>> representation)) (def .public (span from to) - (-> Instant Instant Duration) + (-> Instant Instant + Duration) (duration.of_millis (i.- (representation from) (representation to)))) - (def .public (after duration instant) - (-> Duration Instant Instant) - (abstraction (i.+ (duration.millis duration) (representation instant)))) + (with_template [<*> <name>] + [(def .public (<name> duration instant) + (-> Duration Instant + Instant) + (abstraction (<*> (duration.millis duration) (representation instant))))] + + [i.- before] + [i.+ after] + ) (def .public (relative instant) - (-> Instant Duration) + (-> Instant + Duration) (|> instant representation duration.of_millis)) (def .public (absolute offset) - (-> Duration Instant) + (-> Duration + Instant) (|> offset duration.millis abstraction)) (def .public equivalence (Equivalence Instant) (implementation (def (= param subject) - (at i.equivalence = (representation param) (representation subject))))) + (of i.equivalence = (representation param) (representation subject))))) (def .public order (Order Instant) (implementation (def equivalence ..equivalence) (def (< param subject) - (at i.order < (representation param) (representation subject))))) + (of i.order < (representation param) (representation subject))))) (def .public hash (Hash Instant) (implementation (def equivalence ..equivalence) (def hash - (|>> representation (at i.hash hash))))) + (|>> representation (of i.hash hash))))) (`` (def .public enum (Enum Instant) @@ -84,7 +95,7 @@ (def order ..order) (,, (with_template [<name>] [(def <name> - (|>> representation (at i.enum <name>) abstraction))] + (|>> representation (of i.enum <name>) abstraction))] [succ] [pred] ))))) @@ -94,11 +105,21 @@ Instant (..of_millis +0)) +(with_template [<name> <value>] + [(def .public <name> + Instant + (..of_millis <value>))] + + [earliest i#bottom] + [latest i#top] + ) + (def millis_per_day (duration.ticks duration.milli_second duration.day)) (def (date_time instant) - (-> Instant [Date Duration]) + (-> Instant + [Date Duration]) (let [offset (..millis instant) bce? (i.< +0 offset) [days day_time] (if bce? @@ -111,15 +132,18 @@ (duration.of_millis day_time)])) (with_template [<value> <definition>] - [(def <definition> Text <value>)] + [(def <definition> + Text + <value>)] ["T" date_suffix] ["Z" time_suffix] ) (def (clock_time duration) - (-> Duration Time) - (|> (if (at duration.order < duration.empty duration) + (-> Duration + Time) + (|> (if (of duration.order < duration.empty duration) (duration.composite duration.day duration) duration) duration.millis @@ -128,19 +152,20 @@ try.trusted)) (def .public (format instant) - (-> Instant Text) + (-> Instant + Text) (let [[date time] (..date_time instant) time (..clock_time time)] (all text#composite - (at date.codec encoded date) ..date_suffix - (at //.codec encoded time) ..time_suffix))) + (of date.codec encoded date) ..date_suffix + (of //.codec encoded time) ..time_suffix))) (def .public parser (Parser Instant) (do [! <>.monad] - [days (at ! each date.days date.parser) + [days (of ! each date.days date.parser) _ (<text>.this ..date_suffix) - time (at ! each //.millis //.parser) + time (of ! each //.millis //.parser) _ (<text>.this ..time_suffix)] (in (|> (if (i.< +0 days) (|> duration.day @@ -198,7 +223,8 @@ (with_template [<field> <type> <post_processing>] [(def .public (<field> instant) - (-> Instant <type>) + (-> Instant + <type>) (let [[date time] (..date_time instant)] (|> <field> <post_processing>)))] @@ -207,7 +233,8 @@ ) (def .public (day_of_week instant) - (-> Instant Day) + (-> Instant + Day) (let [offset (..relative instant) days (duration.ticks duration.day offset) day_time (duration.framed duration.day offset) @@ -231,7 +258,8 @@ _ (undefined)))) (def .public (of_date_time date time) - (-> Date Time Instant) + (-> Date Time + Instant) (|> (date.days date) (i.* (duration.millis duration.day)) (i.+ (.int (//.millis time))) diff --git a/stdlib/source/library/lux/world/time/month.lux b/stdlib/source/library/lux/world/time/month.lux index b6fc1f8fa..025b38002 100644 --- a/stdlib/source/library/lux/world/time/month.lux +++ b/stdlib/source/library/lux/world/time/month.lux @@ -82,10 +82,10 @@ (exception.def .public (invalid_month number) (Exception Nat) (exception.report - (list ["Number" (at n.decimal encoded number)] - ["Valid range" (.text_composite# (at n.decimal encoded (..number {#January})) + (list ["Number" (of n.decimal encoded number)] + ["Valid range" (.text_composite# (of n.decimal encoded (..number {#January})) " ~ " - (at n.decimal encoded (..number {#December})))]))) + (of n.decimal encoded (..number {#December})))]))) (def .public (by_number number) (-> Nat (Try Month)) diff --git a/stdlib/source/library/lux/world/time/series.lux b/stdlib/source/library/lux/world/time/series.lux new file mode 100644 index 000000000..c529f6636 --- /dev/null +++ b/stdlib/source/library/lux/world/time/series.lux @@ -0,0 +1,124 @@ +(.require + [library + [lux (.except) + [abstract + [equivalence (.only Equivalence)] + [functor (.only Functor)] + [mix (.only Mix)]] + [control + ["[0]" try (.only Try)] + ["[0]" exception (.only Exception)]] + [data + [text + ["%" \\format]] + [collection + ["[0]" array (.only Array) (.use "[1]#[0]" functor mix) + ["/" \\unsafe]]]] + [meta + [type + ["[0]" nominal]]]]] + [// + ["[0]" instant (.only Instant) (.use "[1]#[0]" order)]]) + +(type .public (Event of) + (Record + [#when Instant + #what of])) + +(def (event_equivalence super) + (All (_ of) + (-> (Equivalence of) + (Equivalence (Event of)))) + (implementation + (def (= reference example) + (and (instant#= (the #when reference) (the #when example)) + (of super = (the #what reference) (the #what example)))))) + +(nominal.def .public (Series of) + (Array (Event of)) + + (def .public (equivalence super) + (All (_ of) + (-> (Equivalence of) + (Equivalence (Series of)))) + (implementation + (def (= reference example) + (of (array.equivalence (event_equivalence super)) = + (nominal.representation reference) + (nominal.representation example))))) + + (def .public functor + (Functor Series) + (implementation + (def (each $) + (|>> nominal.representation + (array#each (revised #what $)) + nominal.abstraction)))) + + (def .public mix + (Mix Series) + (implementation + (def (mix $ init) + (|>> nominal.representation + (array#mix (function (_ next it) + ($ (the #what next) it)) + init))))) + + (exception.def .public (disordered [before after]) + (Exception [Instant Instant]) + (exception.report + (list ["(Expected) before" (%.instant before)] + ["(Expected) after" (%.instant after)]))) + + (exception.def .public (duplicated it) + (Exception Instant) + (exception.report + (list ["Time-stamp" (%.instant it)]))) + + (def .public (series it) + (All (_ of) + (-> (List (Event of)) + (Try (Series of)))) + (when it + {.#Item head tail} + (loop (again [previous head + it tail]) + (when it + {.#Item current next} + (if (instant#< (the #when current) (the #when previous)) + (again current next) + (if (instant#= (the #when current) (the #when previous)) + (exception.except ..duplicated [(the #when current)]) + (exception.except ..disordered [(the #when previous) (the #when current)]))) + + {.#End} + {try.#Success (nominal.abstraction + (array.of_list it))})) + + {.#End} + {try.#Success (nominal.abstraction + (array.empty 0))})) + + (def .public size + (All (_ of) + (-> (Series of) + Nat)) + (|>> nominal.representation + /.size)) + + (exception.def .public empty) + + (with_template [<name> <index>] + [(def .public (<name> it) + (All (_ of) + (-> (Series of) + (Try (Event of)))) + (let [it (nominal.representation it)] + (when (array.size it) + 0 (exception.except ..empty []) + @ {try.#Success (/.item <index> it)})))] + + [earliest 0] + [latest (-- @)] + ) + ) diff --git a/stdlib/source/library/lux/world/time/solar.lux b/stdlib/source/library/lux/world/time/solar.lux index 26163e511..0cac56e36 100644 --- a/stdlib/source/library/lux/world/time/solar.lux +++ b/stdlib/source/library/lux/world/time/solar.lux @@ -165,11 +165,11 @@ [tz_now (|> (datetime/timedelta::new +0) datetime/timezone::new datetime/datetime::now - (at ! each datetime/datetime::astimezone)) + (of ! each datetime/datetime::astimezone)) offset (|> tz_now datetime/datetime::tzinfo datetime/datetime::now - (at ! each (|>> datetime/datetime::utcoffset + (of ! each (|>> datetime/datetime::utcoffset datetime/utcoffset::total_seconds f.int (i.* +1000) |