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