-- Hoogle documentation, generated by Haddock -- See Hoogle, http://www.haskell.org/hoogle/ -- | Type-safe time library. -- -- See README.md for details. @package o-clock @version 1.2.0 -- | This module introduces Rat kind and all necessary functional. module Time.Rational -- | Data structure represents the rational number. Rational number can be -- represented as a pair of natural numbers n and m -- where m is nor equal to zero. data Rat (::%) :: Nat -> Nat -> Rat -- | More convenient name for promoted constructor of Rat. type (:%) = '(::%) -- | Type family for normalized pair of Nats — Rat. type family (m :: Nat) % (n :: Nat) :: Rat infixl 7 % -- | Overloaded multiplication. type family (*) (a :: k1) (b :: k2) :: MulK k1 k2 -- | Overloaded division. type family (/) (a :: k1) (b :: k2) :: DivK k1 k2 -- | The result kind of overloaded multiplication. type family MulK (k1 :: Type) (k2 :: Type) :: Type -- | The result kind of overloaded division. type family DivK (k1 :: Type) (k2 :: Type) :: Type -- | Greatest common divisor for type-level naturals. -- -- Example: -- --
-- >>> :kind! Gcd 9 11 -- Gcd 9 11 :: Nat -- = 1 ---- --
-- >>> :kind! Gcd 9 12 -- Gcd 9 12 :: Nat -- = 3 --type family Gcd (m :: Nat) (n :: Nat) :: Nat -- | Normalization of type-level rational. -- -- Example: -- --
-- >>> :kind! Normalize (9 % 11) -- Normalize (9 % 11) :: Rat -- = 9 :% 11 ---- --
-- >>> :kind! Normalize (9 % 12) -- Normalize (9 % 12) :: Rat -- = 3 :% 4 --type family Normalize (r :: Rat) :: Rat -- | Division of type-level rationals. -- -- If there are Rat with Nats a and b and -- another Rat with c d then the following -- formula should be applied: <math> -- -- Example: -- --
-- >>> :kind! DivRat (9 % 11) (9 % 11) -- DivRat (9 % 11) (9 % 11) :: Rat -- = 1 :% 1 --type family DivRat (m :: Rat) (n :: Rat) :: Rat -- | Comparison of type-level rationals, as a function. -- --
-- >>> :kind! (1 :% 42) >=% (5 :% 42) -- (1 :% 42) >=% (5 :% 42) :: Bool -- = 'False ---- --
-- >>> :kind! (5 :% 42) >=% (1 :% 42) -- (5 :% 42) >=% (1 :% 42) :: Bool -- = 'True ---- --
-- >>> :kind! (42 :% 1) >=% (42 :% 1) -- (42 :% 1) >=% (42 :% 1) :: Bool -- = 'True --type family (m :: Rat) >=% (n :: Rat) :: Bool infix 4 >=% -- | Rational numbers, with numerator and denominator of Natural -- type. type RatioNat = Ratio Natural -- | This class gives the integer associated with a type-level rational. class KnownRat (r :: Rat) ratVal :: KnownRat r => RatioNat -- | Performs action with introduced DivRat constraint for rational -- numbers. withRuntimeDivRat :: forall (a :: Rat) (b :: Rat) r. (KnownRat a, KnownRat b) => (KnownRat (a / b) => r) -> r -- | Constraint alias for DivRat units. type KnownDivRat a b = (KnownRat a, KnownRat b, KnownRat (a / b)) instance (GHC.TypeNats.KnownNat a, GHC.TypeNats.KnownNat b) => Time.Rational.KnownRat (a Time.Rational.:% b) -- | This module contains time unit data structures and functions to work -- with time. module Time.Units -- | Time unit is represented as type level rational multiplier with kind -- Rat. newtype Time (rat :: Rat) Time :: RatioNat -> Time [unTime] :: Time -> RatioNat type Second = 1 / 1 type Millisecond = Second / 1000 type Microsecond = Millisecond / 1000 type Nanosecond = Microsecond / 1000 type Picosecond = Nanosecond / 1000 type Minute = 60 * Second type Hour = 60 * Minute type Day = 24 * Hour type Week = 7 * Day type Fortnight = 2 * Week -- | Type family for prettier show of time units. type family UnitName (unit :: Rat) :: Symbol -- | Constraint alias for KnownSymbol UnitName. type KnownUnitName unit = KnownSymbol (UnitName unit) -- | Constraint alias for KnownUnitName and KnownRat for time -- unit. type KnownRatName unit = (KnownUnitName unit, KnownRat unit) -- | Returns type-level Symbol of the time unit converted to -- String. unitNameVal :: forall (unit :: Rat). KnownUnitName unit => String -- | Creates Time of some type from given Natural. time :: RatioNat -> Time unit -- | Similar to floor, but works with Time units. -- --
-- >>> floorUnit @Day (Time $ 5 % 2) -- 2d ---- --
-- >>> floorUnit (Time @Second $ 2 % 3) -- 0s ---- --
-- >>> floorUnit $ ps 42 -- 42ps --floorUnit :: forall (unit :: Rat). Time unit -> Time unit -- | Returns the greatest integer not greater than given Time. floorRat :: forall (unit :: Rat) b. Integral b => Time unit -> b -- | Convert time to the Num in given units. -- -- For example, instead of writing -- --
-- foo :: POSIXTime -- foo = 10800 -- 3 hours ---- -- one can write more safe implementation: -- --
-- foo = toNum @Second $ hour 3 ---- -- Examples: -- --
-- >>> toNum @Second @Natural $ hour 3 -- 10800 ---- --
-- >>> toNum @Minute @Int $ hour 3 -- 180 ---- --
-- >>> toNum @Hour @Natural $ hour 3 -- 3 --toNum :: forall (unitTo :: Rat) n (unit :: Rat). (KnownDivRat unit unitTo, Num n) => Time unit -> n -- | Creates Second from given Natural. -- --
-- >>> sec 42 -- 42s --sec :: RatioNat -> Time Second -- | Creates Millisecond from given Natural. -- --
-- >>> ms 42 -- 42ms --ms :: RatioNat -> Time Millisecond -- | Creates Microsecond from given Natural. -- --
-- >>> mcs 42 -- 42mcs --mcs :: RatioNat -> Time Microsecond -- | Creates Nanosecond from given Natural. -- --
-- >>> ns 42 -- 42ns --ns :: RatioNat -> Time Nanosecond -- | Creates Picosecond from given Natural. -- --
-- >>> ps 42 -- 42ps --ps :: RatioNat -> Time Picosecond -- | Creates Minute from given Natural. -- --
-- >>> minute 42 -- 42m --minute :: RatioNat -> Time Minute -- | Creates Hour from given Natural. -- --
-- >>> hour 42 -- 42h --hour :: RatioNat -> Time Hour -- | Creates Day from given Natural. -- --
-- >>> day 42 -- 42d --day :: RatioNat -> Time Day -- | Creates Week from given Natural. -- --
-- >>> week 42 -- 42w --week :: RatioNat -> Time Week -- | Creates Fortnight from given Natural. -- --
-- >>> fortnight 42 -- 42fn --fortnight :: RatioNat -> Time Fortnight -- | Converts from one time unit to another time unit. -- --
-- >>> toUnit @Hour (minute 120) -- 2h ---- --
-- >>> toUnit @Second (ms 7) -- 7/1000s ---- --
-- >>> toUnit @Week (Time @Day 45) -- 6+3/7w ---- --
-- >>> toUnit @Second @Minute (Time 3) -- 180s ---- --
-- >>> toUnit (day 42000000) :: Time Second -- 3628800000000s --toUnit :: forall (unitTo :: Rat) (unitFrom :: Rat). KnownDivRat unitFrom unitTo => Time unitFrom -> Time unitTo -- | Convenient version of threadDelay which takes any time-unit and -- operates in any MonadIO. -- --
-- >>> threadDelay $ sec 2 -- >>> threadDelay (2 :: Time Second) -- >>> threadDelay @Second 2 --threadDelay :: forall (unit :: Rat) m. (KnownDivRat unit Microsecond, MonadIO m) => Time unit -> m () -- | Similar to getCPUTime but returns the CPU time used by the -- current program in the given time unit. The precision of this result -- is implementation-dependent. -- --
-- >>> getCPUTime @Second -- 1064046949/1000000000s --getCPUTime :: forall (unit :: Rat) m. (KnownDivRat Picosecond unit, MonadIO m) => m (Time unit) -- | Similar to timeout but receiving any time unit instead of -- number of microseconds. -- --
-- >>> timeout (sec 1) (putStrLn "Hello O'Clock") -- Hello O'Clock -- Just () ---- --
-- >>> timeout (ps 1) (putStrLn "Hello O'Clock") -- Nothing ---- --
-- >>> timeout (mcs 1) (putStrLn "Hello O'Clock") -- HellNothing --timeout :: forall (unit :: Rat) m a. (MonadIO m, KnownDivRat unit Microsecond) => Time unit -> IO a -> m (Maybe a) instance GHC.Generics.Generic (Time.Units.Time rat) instance GHC.Enum.Enum (Time.Units.Time rat) instance GHC.Classes.Ord (Time.Units.Time rat) instance GHC.Classes.Eq (Time.Units.Time rat) instance Time.Units.KnownUnitName unit => GHC.Show.Show (Time.Units.Time unit) instance Time.Units.KnownUnitName unit => GHC.Read.Read (Time.Units.Time unit) instance GHC.Base.Semigroup (Time.Units.Time rat) instance GHC.Base.Monoid (Time.Units.Time rat) -- | This module introduces Timestamp data type and corresponding -- functions for operations with time. module Time.Timestamp -- | Similar to Time but has no units and can be negative. newtype Timestamp Timestamp :: Rational -> Timestamp -- | Converts unix time to Timestamp. fromUnixTime :: Real a => a -> Timestamp -- | Returns the result of comparison of two Timestamps and the -- Time of that difference of given time unit. -- --
-- >>> timeDiff @Second (Timestamp 4) (Timestamp 2) -- (GT,2s) ---- --
-- >>> timeDiff @Minute (Timestamp 4) (Timestamp 2) -- (GT,1/30m) ---- --
-- >>> timeDiff @Second (Timestamp 2) (Timestamp 4) -- (LT,2s) ---- --
-- >>> timeDiff @Minute (Timestamp 2) (Timestamp 4) -- (LT,1/30m) --timeDiff :: forall (unit :: Rat). KnownDivRat Second unit => Timestamp -> Timestamp -> (Ordering, Time unit) -- | Returns the result of addition of Time with Timestamp -- elements. -- --
-- >>> sec 5 `timeAdd` (Timestamp 4) -- Timestamp (9 % 1) ---- --
-- >>> minute 1 `timeAdd` (Timestamp 5) -- Timestamp (65 % 1) --timeAdd :: forall (unit :: Rat). KnownDivRat unit Second => Time unit -> Timestamp -> Timestamp -- | Returns the result of multiplication of two Time elements. timeMul :: forall (unit :: Rat). KnownRat unit => RatioNat -> Time unit -> Time unit -- | Operator version of timeMul. -- --
-- >>> 3 *:* sec 5 -- 15s ---- --
-- >>> 2 *:* 3 *:* sec 5 -- 30s ---- --
-- >>> 3 *:* 5 *:* sec 7 -- 105s ---- --
-- >>> ms 2000 +:+ 2 *:* sec 3 -- 8s --(*:*) :: forall (unit :: Rat). KnownRat unit => RatioNat -> Time unit -> Time unit infixr 7 *:* -- | Returns the result of division of two Time elements. timeDiv :: forall (unit :: Rat). KnownRat unit => Time unit -> Time unit -> RatioNat -- | Operator version of timeDiv. -- --
-- >>> sec 15 /:/ sec 3 -- 5 % 1 --(/:/) :: forall (unit :: Rat). KnownRat unit => Time unit -> Time unit -> RatioNat infix 7 /:/ -- | Sums times of different units. -- --
-- >>> minute 1 +:+ sec 1 -- 61s --(+:+) :: forall (unitResult :: Rat) (unitLeft :: Rat). KnownDivRat unitLeft unitResult => Time unitLeft -> Time unitResult -> Time unitResult infixl 6 +:+ -- | Substracts time amounts of different units. When the minuend is -- smaller than the subtrahend, this function will throw Underflow :: -- ArithException. -- --
-- >>> minute 1 -:- sec 1 -- 59s --(-:-) :: forall (unitResult :: Rat) (unitLeft :: Rat). KnownDivRat unitLeft unitResult => Time unitLeft -> Time unitResult -> Time unitResult infixl 6 -:- -- | Compute the difference between two amounts of time. The result is -- returned in two components: the ordering (which input is larger) and -- the numeric difference (how much larger). Unlike -:-, does not -- throw ArithException. -- --
-- >>> sec 5 -%- sec 3 -- (GT,2s) ---- --
-- >>> sec 5 -%- sec 6 -- (LT,1s) --(-%-) :: forall (unitResult :: Rat) (unitLeft :: Rat). KnownDivRat unitLeft unitResult => Time unitLeft -> Time unitResult -> (Ordering, Time unitResult) infix 6 -%- instance GHC.Classes.Ord Time.Timestamp.Timestamp instance GHC.Classes.Eq Time.Timestamp.Timestamp instance GHC.Read.Read Time.Timestamp.Timestamp instance GHC.Show.Show Time.Timestamp.Timestamp -- | This module introduces function to format and parse time in desired -- way. module Time.Series -- | Type-level list that consist of all times. type AllTimes = '[Fortnight, Week, Day, Hour, Minute, Second, Millisecond, Microsecond, Nanosecond, Picosecond] -- | Creates the list of time units in descending order by provided the -- highest and the lowest bound of the desired list. Throws the error -- when time units are not in the right order. -- -- Usage example: -- --
-- >>> seriesF @(Hour ... Second) $ hour 3 +:+ minute 5 +:+ sec 3 +:+ ms 123 -- "3h5m3+123/1000s" --type family (from :: Rat) ... (to :: Rat) :: [Rat] -- | Class for time formatting. -- -- Examples -- --
-- >>> seriesF @'[Day, Hour, Minute, Second] (minute 4000) -- "2d18h40m" ---- --
-- >>> seriesF @'[Day, Minute, Second] (minute 4000) -- "2d1120m" ---- --
-- >>> seriesF @'[Hour, Minute, Second] (sec 3601) -- "1h1s" ---- --
-- >>> seriesF @'[Hour, Second, Millisecond] (Time @Minute $ 3 % 2) -- "90s" ---- --
-- >>> seriesF @'[Hour, Second] (minute 0) -- "0h" ---- --
-- >>> seriesF @'[Hour, Minute, Second] (Time @Day (2 % 7)) -- "6h51m25+5/7s" ---- -- The received list should be in descending order. It would be verified -- at compile-time. Example of the error from ghci: -- --
-- >>> seriesF @'[Millisecond, Second] (minute 42) -- ... -- • List of units should be in descending order -- • In the expression: seriesF @'[Millisecond, Second] (minute 42) -- In an equation for ‘it’: -- it = seriesF @'[Millisecond, Second] (minute 42) -- ... --class SeriesF (units :: [Rat]) seriesF :: forall (someUnit :: Rat). (SeriesF units, KnownRatName someUnit) => Time someUnit -> String -- | Similar to seriesF, but formats using all time units of the -- library. -- --
-- >>> unitsF $ fortnight 5 -- "5fn" ---- --
-- >>> unitsF $ minute 4000 -- "2d18h40m" --unitsF :: forall unit. KnownRatName unit => Time unit -> String -- | Class for time parsing. -- -- Empty string on input will be parsed as 0 time of the required time -- unit: -- --
-- >>> seriesP @'[Hour, Minute, Second] @Second "" -- Just (0s) ---- -- Examples -- --
-- >>> seriesP @'[Day, Hour, Minute, Second] @Minute "2d18h40m" -- Just (4000m) ---- --
-- >>> seriesP @'[Day, Minute, Second] @Minute "2d1120m" -- Just (4000m) ---- --
-- >>> seriesP @'[Hour, Minute, Second] @Second "1h1s" -- Just (3601s) ---- --
-- >>> seriesP @'[Hour, Second, Millisecond] @Minute "90s" -- Just (1+1/2m) ---- --
-- >>> seriesP @'[Hour, Second] @Second "11ns" -- Nothing ---- --
-- >>> seriesP @'[Hour, Minute] @Minute "1+1/2h" -- Nothing ---- --
-- >>> seriesP @'[Hour, Minute] @Minute "1+1/2m" -- Just (1+1/2m) ---- --
-- >>> seriesP @'[Hour, Minute] @Minute "1h1+1/2m" -- Just (61+1/2m) ---- -- Note: The received list should be in descending order. It would -- be verified at compile-time. class SeriesP (units :: [Rat]) seriesP :: forall (someUnit :: Rat). (SeriesP units, KnownRatName someUnit) => String -> Maybe (Time someUnit) -- | Similar to seriesP, but parses using all time units of the -- library. -- --
-- >>> unitsP @Second "1m" -- Just (60s) ---- --
-- >>> unitsP @Minute "2d18h40m" -- Just (4000m) --unitsP :: forall unit. KnownRatName unit => String -> Maybe (Time unit) instance Time.Series.SeriesP '[] instance Time.Units.KnownRatName unit => Time.Series.SeriesP '[unit] instance (Time.Units.KnownRatName unit, Time.Series.SeriesP (nextUnit : units), Time.Series.DescendingConstraint (Time.Series.IsDescending (unit : nextUnit : units))) => Time.Series.SeriesP (unit : nextUnit : units) instance Time.Series.SeriesF '[] instance Time.Units.KnownRatName unit => Time.Series.SeriesF '[unit] instance (Time.Units.KnownRatName unit, Time.Series.SeriesF (nextUnit : units), Time.Series.DescendingConstraint (Time.Series.IsDescending (unit : nextUnit : units))) => Time.Series.SeriesF (unit : nextUnit : units) -- | This module reexports main functionality. -- -- More information about O'Clock features can be found here: -- https://github.com/serokell/o-clock#readme module Time