{-# LANGUAGE CPP, DeriveDataTypeable, DeriveFunctor, DeriveFoldable, DeriveGeneric, RankNTypes, Safe #-}

{-|
Module      : Text.Numerals.Class
Description : A module that contains the typeclasses on which the rest of the module works.
Maintainer  : hapytexeu+gh@gmail.com
Stability   : experimental
Portability : POSIX

A module that defines the typeclasses that are used in the rest of the module. The 'NumToWord' class
is the typeclass that is used by all algorithmic conversion tools.
-}

module Text.Numerals.Class (
    -- * Typeclasses
    NumToWord(toCardinal, toOrdinal, toShortOrdinal, toWords, toTimeText, toTimeText')
  , ValueSplit(valueSplit)
    -- * Types of numbers
  , NumberType(Cardinal, Ordinal, ShortOrdinal)
    -- * Segmenting a number
  , NumberSegment(NumberSegment, segmentDivision, segmentValue, segmentText, segmentRemainder)
  , MNumberSegment
    -- * Segments of time
  , ClockSegment(OClock, Past, QuarterPast, ToHalf, Half, PastHalf, QuarterTo, To)
  , DayPart(Night, Morning, Afternoon, Evening)
  , DaySegment(DaySegment, dayPart, dayHour)
  , toDayPart, toDaySegment, toClockSegment
  , hourCorrection
    -- * Convert the current time to words
  , currentTimeText, currentTimeText'
    -- * Utility type synonyms
  , NumberToWords,  FreeNumberToWords
  , MergerFunction, FreeMergerFunction, ValueSplitter, FreeValueSplitter, NumberSegmenting
  , ClockText
  ) where

import Control.DeepSeq(NFData, NFData1)

import Data.Data(Data)
import Data.Default.Class(Default(def))
#if __GLASGOW_HASKELL__ < 803
import Data.Semigroup((<>))
#endif
import Data.Text(Text)
import Data.Time.Clock(getCurrentTime, utctDayTime)
import Data.Time.LocalTime(TimeOfDay(TimeOfDay), TimeZone, timeToTimeOfDay, utcToLocalTimeOfDay)

import GHC.Generics(Generic, Generic1)

import Test.QuickCheck(choose)
import Test.QuickCheck.Arbitrary(Arbitrary(arbitrary, shrink), Arbitrary1(liftArbitrary), arbitrary1, arbitraryBoundedEnum)

import Text.Numerals.Internal(_genText, _shrinkText)

-- | A type alias for a function that maps a number to a 'Text' object.
type NumberToWords i = i -> Text

-- | A type alias for a 'NumberToWords' function, with a free 'Integral'
-- variable.
type FreeNumberToWords = forall i . Integral i => NumberToWords i

-- | A type alias of a function that is used to merge the names of two numbers according
-- to gramatical rules. The type parameter is the type of the numbers to merge.
type MergerFunction i = i -> i -> Text -> Text -> Text

-- | A type alias of a 'MergerFunction' function with a free 'Integral' variable.
type FreeMergerFunction = forall i . Integral i => MergerFunction i

-- | A type alias of a function that maps a number to a 2-tuple that contains a
-- number and the word for that number. This number is normally the largest
-- number smaller than the given number. In case no name exists for a number
-- smaller than the given one 'Nothing' is returned.
type ValueSplitter i = i -> Maybe (i, Text)

-- | A type alias of a 'ValueSplitter' function, with a free 'Integral'
-- variable.
type FreeValueSplitter = forall i . Integral i => ValueSplitter i

-- | A type alias of a function that converts a number to a 'NumberSegment' for that number.
type NumberSegmenting i = i -> NumberSegment i

-- | A data type used to convert a number into segments. Each segment has an
-- optional division and remainder part, together with a value and the name of
-- that value in a language.
data NumberSegment i = NumberSegment {
    NumberSegment i -> MNumberSegment i
segmentDivision :: MNumberSegment i  -- ^ The optional division part. 'Nothing' if the division is equal to one.
  , NumberSegment i -> i
segmentValue :: i  -- ^ The value of the given segment.
  , NumberSegment i -> Text
segmentText :: Text  -- ^ The name of the value of the given segment, in a specific language.
  , NumberSegment i -> MNumberSegment i
segmentRemainder ::  MNumberSegment i  -- ^ The optional remainder part. 'Nothing' if the remainder is equal to zero.
  } deriving (Typeable (NumberSegment i)
DataType
Constr
Typeable (NumberSegment i)
-> (forall (c :: * -> *).
    (forall d b. Data d => c (d -> b) -> d -> c b)
    -> (forall g. g -> c g) -> NumberSegment i -> c (NumberSegment i))
-> (forall (c :: * -> *).
    (forall b r. Data b => c (b -> r) -> c r)
    -> (forall r. r -> c r) -> Constr -> c (NumberSegment i))
-> (NumberSegment i -> Constr)
-> (NumberSegment i -> DataType)
-> (forall (t :: * -> *) (c :: * -> *).
    Typeable t =>
    (forall d. Data d => c (t d)) -> Maybe (c (NumberSegment i)))
-> (forall (t :: * -> * -> *) (c :: * -> *).
    Typeable t =>
    (forall d e. (Data d, Data e) => c (t d e))
    -> Maybe (c (NumberSegment i)))
-> ((forall b. Data b => b -> b)
    -> NumberSegment i -> NumberSegment i)
-> (forall r r'.
    (r -> r' -> r)
    -> r -> (forall d. Data d => d -> r') -> NumberSegment i -> r)
-> (forall r r'.
    (r' -> r -> r)
    -> r -> (forall d. Data d => d -> r') -> NumberSegment i -> r)
-> (forall u.
    (forall d. Data d => d -> u) -> NumberSegment i -> [u])
-> (forall u.
    Int -> (forall d. Data d => d -> u) -> NumberSegment i -> u)
-> (forall (m :: * -> *).
    Monad m =>
    (forall d. Data d => d -> m d)
    -> NumberSegment i -> m (NumberSegment i))
-> (forall (m :: * -> *).
    MonadPlus m =>
    (forall d. Data d => d -> m d)
    -> NumberSegment i -> m (NumberSegment i))
-> (forall (m :: * -> *).
    MonadPlus m =>
    (forall d. Data d => d -> m d)
    -> NumberSegment i -> m (NumberSegment i))
-> Data (NumberSegment i)
NumberSegment i -> DataType
NumberSegment i -> Constr
(forall d. Data d => c (t d)) -> Maybe (c (NumberSegment i))
(forall b. Data b => b -> b) -> NumberSegment i -> NumberSegment i
(forall d b. Data d => c (d -> b) -> d -> c b)
-> (forall g. g -> c g) -> NumberSegment i -> c (NumberSegment i)
(forall b r. Data b => c (b -> r) -> c r)
-> (forall r. r -> c r) -> Constr -> c (NumberSegment i)
forall i. Data i => Typeable (NumberSegment i)
forall i. Data i => NumberSegment i -> DataType
forall i. Data i => NumberSegment i -> Constr
forall i.
Data i =>
(forall b. Data b => b -> b) -> NumberSegment i -> NumberSegment i
forall i u.
Data i =>
Int -> (forall d. Data d => d -> u) -> NumberSegment i -> u
forall i u.
Data i =>
(forall d. Data d => d -> u) -> NumberSegment i -> [u]
forall i r r'.
Data i =>
(r -> r' -> r)
-> r -> (forall d. Data d => d -> r') -> NumberSegment i -> r
forall i r r'.
Data i =>
(r' -> r -> r)
-> r -> (forall d. Data d => d -> r') -> NumberSegment i -> r
forall i (m :: * -> *).
(Data i, Monad m) =>
(forall d. Data d => d -> m d)
-> NumberSegment i -> m (NumberSegment i)
forall i (m :: * -> *).
(Data i, MonadPlus m) =>
(forall d. Data d => d -> m d)
-> NumberSegment i -> m (NumberSegment i)
forall i (c :: * -> *).
Data i =>
(forall b r. Data b => c (b -> r) -> c r)
-> (forall r. r -> c r) -> Constr -> c (NumberSegment i)
forall i (c :: * -> *).
Data i =>
(forall d b. Data d => c (d -> b) -> d -> c b)
-> (forall g. g -> c g) -> NumberSegment i -> c (NumberSegment i)
forall i (t :: * -> *) (c :: * -> *).
(Data i, Typeable t) =>
(forall d. Data d => c (t d)) -> Maybe (c (NumberSegment i))
forall i (t :: * -> * -> *) (c :: * -> *).
(Data i, Typeable t) =>
(forall d e. (Data d, Data e) => c (t d e))
-> Maybe (c (NumberSegment i))
forall a.
Typeable a
-> (forall (c :: * -> *).
    (forall d b. Data d => c (d -> b) -> d -> c b)
    -> (forall g. g -> c g) -> a -> c a)
-> (forall (c :: * -> *).
    (forall b r. Data b => c (b -> r) -> c r)
    -> (forall r. r -> c r) -> Constr -> c a)
-> (a -> Constr)
-> (a -> DataType)
-> (forall (t :: * -> *) (c :: * -> *).
    Typeable t =>
    (forall d. Data d => c (t d)) -> Maybe (c a))
-> (forall (t :: * -> * -> *) (c :: * -> *).
    Typeable t =>
    (forall d e. (Data d, Data e) => c (t d e)) -> Maybe (c a))
-> ((forall b. Data b => b -> b) -> a -> a)
-> (forall r r'.
    (r -> r' -> r) -> r -> (forall d. Data d => d -> r') -> a -> r)
-> (forall r r'.
    (r' -> r -> r) -> r -> (forall d. Data d => d -> r') -> a -> r)
-> (forall u. (forall d. Data d => d -> u) -> a -> [u])
-> (forall u. Int -> (forall d. Data d => d -> u) -> a -> u)
-> (forall (m :: * -> *).
    Monad m =>
    (forall d. Data d => d -> m d) -> a -> m a)
-> (forall (m :: * -> *).
    MonadPlus m =>
    (forall d. Data d => d -> m d) -> a -> m a)
-> (forall (m :: * -> *).
    MonadPlus m =>
    (forall d. Data d => d -> m d) -> a -> m a)
-> Data a
forall u.
Int -> (forall d. Data d => d -> u) -> NumberSegment i -> u
forall u. (forall d. Data d => d -> u) -> NumberSegment i -> [u]
forall r r'.
(r -> r' -> r)
-> r -> (forall d. Data d => d -> r') -> NumberSegment i -> r
forall r r'.
(r' -> r -> r)
-> r -> (forall d. Data d => d -> r') -> NumberSegment i -> r
forall (m :: * -> *).
Monad m =>
(forall d. Data d => d -> m d)
-> NumberSegment i -> m (NumberSegment i)
forall (m :: * -> *).
MonadPlus m =>
(forall d. Data d => d -> m d)
-> NumberSegment i -> m (NumberSegment i)
forall (c :: * -> *).
(forall b r. Data b => c (b -> r) -> c r)
-> (forall r. r -> c r) -> Constr -> c (NumberSegment i)
forall (c :: * -> *).
(forall d b. Data d => c (d -> b) -> d -> c b)
-> (forall g. g -> c g) -> NumberSegment i -> c (NumberSegment i)
forall (t :: * -> *) (c :: * -> *).
Typeable t =>
(forall d. Data d => c (t d)) -> Maybe (c (NumberSegment i))
forall (t :: * -> * -> *) (c :: * -> *).
Typeable t =>
(forall d e. (Data d, Data e) => c (t d e))
-> Maybe (c (NumberSegment i))
$cNumberSegment :: Constr
$tNumberSegment :: DataType
gmapMo :: (forall d. Data d => d -> m d)
-> NumberSegment i -> m (NumberSegment i)
$cgmapMo :: forall i (m :: * -> *).
(Data i, MonadPlus m) =>
(forall d. Data d => d -> m d)
-> NumberSegment i -> m (NumberSegment i)
gmapMp :: (forall d. Data d => d -> m d)
-> NumberSegment i -> m (NumberSegment i)
$cgmapMp :: forall i (m :: * -> *).
(Data i, MonadPlus m) =>
(forall d. Data d => d -> m d)
-> NumberSegment i -> m (NumberSegment i)
gmapM :: (forall d. Data d => d -> m d)
-> NumberSegment i -> m (NumberSegment i)
$cgmapM :: forall i (m :: * -> *).
(Data i, Monad m) =>
(forall d. Data d => d -> m d)
-> NumberSegment i -> m (NumberSegment i)
gmapQi :: Int -> (forall d. Data d => d -> u) -> NumberSegment i -> u
$cgmapQi :: forall i u.
Data i =>
Int -> (forall d. Data d => d -> u) -> NumberSegment i -> u
gmapQ :: (forall d. Data d => d -> u) -> NumberSegment i -> [u]
$cgmapQ :: forall i u.
Data i =>
(forall d. Data d => d -> u) -> NumberSegment i -> [u]
gmapQr :: (r' -> r -> r)
-> r -> (forall d. Data d => d -> r') -> NumberSegment i -> r
$cgmapQr :: forall i r r'.
Data i =>
(r' -> r -> r)
-> r -> (forall d. Data d => d -> r') -> NumberSegment i -> r
gmapQl :: (r -> r' -> r)
-> r -> (forall d. Data d => d -> r') -> NumberSegment i -> r
$cgmapQl :: forall i r r'.
Data i =>
(r -> r' -> r)
-> r -> (forall d. Data d => d -> r') -> NumberSegment i -> r
gmapT :: (forall b. Data b => b -> b) -> NumberSegment i -> NumberSegment i
$cgmapT :: forall i.
Data i =>
(forall b. Data b => b -> b) -> NumberSegment i -> NumberSegment i
dataCast2 :: (forall d e. (Data d, Data e) => c (t d e))
-> Maybe (c (NumberSegment i))
$cdataCast2 :: forall i (t :: * -> * -> *) (c :: * -> *).
(Data i, Typeable t) =>
(forall d e. (Data d, Data e) => c (t d e))
-> Maybe (c (NumberSegment i))
dataCast1 :: (forall d. Data d => c (t d)) -> Maybe (c (NumberSegment i))
$cdataCast1 :: forall i (t :: * -> *) (c :: * -> *).
(Data i, Typeable t) =>
(forall d. Data d => c (t d)) -> Maybe (c (NumberSegment i))
dataTypeOf :: NumberSegment i -> DataType
$cdataTypeOf :: forall i. Data i => NumberSegment i -> DataType
toConstr :: NumberSegment i -> Constr
$ctoConstr :: forall i. Data i => NumberSegment i -> Constr
gunfold :: (forall b r. Data b => c (b -> r) -> c r)
-> (forall r. r -> c r) -> Constr -> c (NumberSegment i)
$cgunfold :: forall i (c :: * -> *).
Data i =>
(forall b r. Data b => c (b -> r) -> c r)
-> (forall r. r -> c r) -> Constr -> c (NumberSegment i)
gfoldl :: (forall d b. Data d => c (d -> b) -> d -> c b)
-> (forall g. g -> c g) -> NumberSegment i -> c (NumberSegment i)
$cgfoldl :: forall i (c :: * -> *).
Data i =>
(forall d b. Data d => c (d -> b) -> d -> c b)
-> (forall g. g -> c g) -> NumberSegment i -> c (NumberSegment i)
$cp1Data :: forall i. Data i => Typeable (NumberSegment i)
Data, NumberSegment i -> NumberSegment i -> Bool
(NumberSegment i -> NumberSegment i -> Bool)
-> (NumberSegment i -> NumberSegment i -> Bool)
-> Eq (NumberSegment i)
forall i. Eq i => NumberSegment i -> NumberSegment i -> Bool
forall a. (a -> a -> Bool) -> (a -> a -> Bool) -> Eq a
/= :: NumberSegment i -> NumberSegment i -> Bool
$c/= :: forall i. Eq i => NumberSegment i -> NumberSegment i -> Bool
== :: NumberSegment i -> NumberSegment i -> Bool
$c== :: forall i. Eq i => NumberSegment i -> NumberSegment i -> Bool
Eq, NumberSegment a -> Bool
(a -> m) -> NumberSegment a -> m
(a -> b -> b) -> b -> NumberSegment a -> b
(forall m. Monoid m => NumberSegment m -> m)
-> (forall m a. Monoid m => (a -> m) -> NumberSegment a -> m)
-> (forall m a. Monoid m => (a -> m) -> NumberSegment a -> m)
-> (forall a b. (a -> b -> b) -> b -> NumberSegment a -> b)
-> (forall a b. (a -> b -> b) -> b -> NumberSegment a -> b)
-> (forall b a. (b -> a -> b) -> b -> NumberSegment a -> b)
-> (forall b a. (b -> a -> b) -> b -> NumberSegment a -> b)
-> (forall a. (a -> a -> a) -> NumberSegment a -> a)
-> (forall a. (a -> a -> a) -> NumberSegment a -> a)
-> (forall a. NumberSegment a -> [a])
-> (forall a. NumberSegment a -> Bool)
-> (forall a. NumberSegment a -> Int)
-> (forall a. Eq a => a -> NumberSegment a -> Bool)
-> (forall a. Ord a => NumberSegment a -> a)
-> (forall a. Ord a => NumberSegment a -> a)
-> (forall a. Num a => NumberSegment a -> a)
-> (forall a. Num a => NumberSegment a -> a)
-> Foldable NumberSegment
forall a. Eq a => a -> NumberSegment a -> Bool
forall a. Num a => NumberSegment a -> a
forall a. Ord a => NumberSegment a -> a
forall m. Monoid m => NumberSegment m -> m
forall a. NumberSegment a -> Bool
forall a. NumberSegment a -> Int
forall a. NumberSegment a -> [a]
forall a. (a -> a -> a) -> NumberSegment a -> a
forall m a. Monoid m => (a -> m) -> NumberSegment a -> m
forall b a. (b -> a -> b) -> b -> NumberSegment a -> b
forall a b. (a -> b -> b) -> b -> NumberSegment a -> b
forall (t :: * -> *).
(forall m. Monoid m => t m -> m)
-> (forall m a. Monoid m => (a -> m) -> t a -> m)
-> (forall m a. Monoid m => (a -> m) -> t a -> m)
-> (forall a b. (a -> b -> b) -> b -> t a -> b)
-> (forall a b. (a -> b -> b) -> b -> t a -> b)
-> (forall b a. (b -> a -> b) -> b -> t a -> b)
-> (forall b a. (b -> a -> b) -> b -> t a -> b)
-> (forall a. (a -> a -> a) -> t a -> a)
-> (forall a. (a -> a -> a) -> t a -> a)
-> (forall a. t a -> [a])
-> (forall a. t a -> Bool)
-> (forall a. t a -> Int)
-> (forall a. Eq a => a -> t a -> Bool)
-> (forall a. Ord a => t a -> a)
-> (forall a. Ord a => t a -> a)
-> (forall a. Num a => t a -> a)
-> (forall a. Num a => t a -> a)
-> Foldable t
product :: NumberSegment a -> a
$cproduct :: forall a. Num a => NumberSegment a -> a
sum :: NumberSegment a -> a
$csum :: forall a. Num a => NumberSegment a -> a
minimum :: NumberSegment a -> a
$cminimum :: forall a. Ord a => NumberSegment a -> a
maximum :: NumberSegment a -> a
$cmaximum :: forall a. Ord a => NumberSegment a -> a
elem :: a -> NumberSegment a -> Bool
$celem :: forall a. Eq a => a -> NumberSegment a -> Bool
length :: NumberSegment a -> Int
$clength :: forall a. NumberSegment a -> Int
null :: NumberSegment a -> Bool
$cnull :: forall a. NumberSegment a -> Bool
toList :: NumberSegment a -> [a]
$ctoList :: forall a. NumberSegment a -> [a]
foldl1 :: (a -> a -> a) -> NumberSegment a -> a
$cfoldl1 :: forall a. (a -> a -> a) -> NumberSegment a -> a
foldr1 :: (a -> a -> a) -> NumberSegment a -> a
$cfoldr1 :: forall a. (a -> a -> a) -> NumberSegment a -> a
foldl' :: (b -> a -> b) -> b -> NumberSegment a -> b
$cfoldl' :: forall b a. (b -> a -> b) -> b -> NumberSegment a -> b
foldl :: (b -> a -> b) -> b -> NumberSegment a -> b
$cfoldl :: forall b a. (b -> a -> b) -> b -> NumberSegment a -> b
foldr' :: (a -> b -> b) -> b -> NumberSegment a -> b
$cfoldr' :: forall a b. (a -> b -> b) -> b -> NumberSegment a -> b
foldr :: (a -> b -> b) -> b -> NumberSegment a -> b
$cfoldr :: forall a b. (a -> b -> b) -> b -> NumberSegment a -> b
foldMap' :: (a -> m) -> NumberSegment a -> m
$cfoldMap' :: forall m a. Monoid m => (a -> m) -> NumberSegment a -> m
foldMap :: (a -> m) -> NumberSegment a -> m
$cfoldMap :: forall m a. Monoid m => (a -> m) -> NumberSegment a -> m
fold :: NumberSegment m -> m
$cfold :: forall m. Monoid m => NumberSegment m -> m
Foldable, a -> NumberSegment b -> NumberSegment a
(a -> b) -> NumberSegment a -> NumberSegment b
(forall a b. (a -> b) -> NumberSegment a -> NumberSegment b)
-> (forall a b. a -> NumberSegment b -> NumberSegment a)
-> Functor NumberSegment
forall a b. a -> NumberSegment b -> NumberSegment a
forall a b. (a -> b) -> NumberSegment a -> NumberSegment b
forall (f :: * -> *).
(forall a b. (a -> b) -> f a -> f b)
-> (forall a b. a -> f b -> f a) -> Functor f
<$ :: a -> NumberSegment b -> NumberSegment a
$c<$ :: forall a b. a -> NumberSegment b -> NumberSegment a
fmap :: (a -> b) -> NumberSegment a -> NumberSegment b
$cfmap :: forall a b. (a -> b) -> NumberSegment a -> NumberSegment b
Functor, (forall x. NumberSegment i -> Rep (NumberSegment i) x)
-> (forall x. Rep (NumberSegment i) x -> NumberSegment i)
-> Generic (NumberSegment i)
forall x. Rep (NumberSegment i) x -> NumberSegment i
forall x. NumberSegment i -> Rep (NumberSegment i) x
forall a.
(forall x. a -> Rep a x) -> (forall x. Rep a x -> a) -> Generic a
forall i x. Rep (NumberSegment i) x -> NumberSegment i
forall i x. NumberSegment i -> Rep (NumberSegment i) x
$cto :: forall i x. Rep (NumberSegment i) x -> NumberSegment i
$cfrom :: forall i x. NumberSegment i -> Rep (NumberSegment i) x
Generic, (forall a. NumberSegment a -> Rep1 NumberSegment a)
-> (forall a. Rep1 NumberSegment a -> NumberSegment a)
-> Generic1 NumberSegment
forall a. Rep1 NumberSegment a -> NumberSegment a
forall a. NumberSegment a -> Rep1 NumberSegment a
forall k (f :: k -> *).
(forall (a :: k). f a -> Rep1 f a)
-> (forall (a :: k). Rep1 f a -> f a) -> Generic1 f
$cto1 :: forall a. Rep1 NumberSegment a -> NumberSegment a
$cfrom1 :: forall a. NumberSegment a -> Rep1 NumberSegment a
Generic1, Eq (NumberSegment i)
Eq (NumberSegment i)
-> (NumberSegment i -> NumberSegment i -> Ordering)
-> (NumberSegment i -> NumberSegment i -> Bool)
-> (NumberSegment i -> NumberSegment i -> Bool)
-> (NumberSegment i -> NumberSegment i -> Bool)
-> (NumberSegment i -> NumberSegment i -> Bool)
-> (NumberSegment i -> NumberSegment i -> NumberSegment i)
-> (NumberSegment i -> NumberSegment i -> NumberSegment i)
-> Ord (NumberSegment i)
NumberSegment i -> NumberSegment i -> Bool
NumberSegment i -> NumberSegment i -> Ordering
NumberSegment i -> NumberSegment i -> NumberSegment i
forall a.
Eq a
-> (a -> a -> Ordering)
-> (a -> a -> Bool)
-> (a -> a -> Bool)
-> (a -> a -> Bool)
-> (a -> a -> Bool)
-> (a -> a -> a)
-> (a -> a -> a)
-> Ord a
forall i. Ord i => Eq (NumberSegment i)
forall i. Ord i => NumberSegment i -> NumberSegment i -> Bool
forall i. Ord i => NumberSegment i -> NumberSegment i -> Ordering
forall i.
Ord i =>
NumberSegment i -> NumberSegment i -> NumberSegment i
min :: NumberSegment i -> NumberSegment i -> NumberSegment i
$cmin :: forall i.
Ord i =>
NumberSegment i -> NumberSegment i -> NumberSegment i
max :: NumberSegment i -> NumberSegment i -> NumberSegment i
$cmax :: forall i.
Ord i =>
NumberSegment i -> NumberSegment i -> NumberSegment i
>= :: NumberSegment i -> NumberSegment i -> Bool
$c>= :: forall i. Ord i => NumberSegment i -> NumberSegment i -> Bool
> :: NumberSegment i -> NumberSegment i -> Bool
$c> :: forall i. Ord i => NumberSegment i -> NumberSegment i -> Bool
<= :: NumberSegment i -> NumberSegment i -> Bool
$c<= :: forall i. Ord i => NumberSegment i -> NumberSegment i -> Bool
< :: NumberSegment i -> NumberSegment i -> Bool
$c< :: forall i. Ord i => NumberSegment i -> NumberSegment i -> Bool
compare :: NumberSegment i -> NumberSegment i -> Ordering
$ccompare :: forall i. Ord i => NumberSegment i -> NumberSegment i -> Ordering
$cp1Ord :: forall i. Ord i => Eq (NumberSegment i)
Ord, ReadPrec [NumberSegment i]
ReadPrec (NumberSegment i)
Int -> ReadS (NumberSegment i)
ReadS [NumberSegment i]
(Int -> ReadS (NumberSegment i))
-> ReadS [NumberSegment i]
-> ReadPrec (NumberSegment i)
-> ReadPrec [NumberSegment i]
-> Read (NumberSegment i)
forall i. Read i => ReadPrec [NumberSegment i]
forall i. Read i => ReadPrec (NumberSegment i)
forall i. Read i => Int -> ReadS (NumberSegment i)
forall i. Read i => ReadS [NumberSegment i]
forall a.
(Int -> ReadS a)
-> ReadS [a] -> ReadPrec a -> ReadPrec [a] -> Read a
readListPrec :: ReadPrec [NumberSegment i]
$creadListPrec :: forall i. Read i => ReadPrec [NumberSegment i]
readPrec :: ReadPrec (NumberSegment i)
$creadPrec :: forall i. Read i => ReadPrec (NumberSegment i)
readList :: ReadS [NumberSegment i]
$creadList :: forall i. Read i => ReadS [NumberSegment i]
readsPrec :: Int -> ReadS (NumberSegment i)
$creadsPrec :: forall i. Read i => Int -> ReadS (NumberSegment i)
Read, Int -> NumberSegment i -> ShowS
[NumberSegment i] -> ShowS
NumberSegment i -> String
(Int -> NumberSegment i -> ShowS)
-> (NumberSegment i -> String)
-> ([NumberSegment i] -> ShowS)
-> Show (NumberSegment i)
forall i. Show i => Int -> NumberSegment i -> ShowS
forall i. Show i => [NumberSegment i] -> ShowS
forall i. Show i => NumberSegment i -> String
forall a.
(Int -> a -> ShowS) -> (a -> String) -> ([a] -> ShowS) -> Show a
showList :: [NumberSegment i] -> ShowS
$cshowList :: forall i. Show i => [NumberSegment i] -> ShowS
show :: NumberSegment i -> String
$cshow :: forall i. Show i => NumberSegment i -> String
showsPrec :: Int -> NumberSegment i -> ShowS
$cshowsPrec :: forall i. Show i => Int -> NumberSegment i -> ShowS
Show)

instance NFData a => NFData (NumberSegment a)

instance NFData1 NumberSegment

instance Arbitrary1 NumberSegment where
  liftArbitrary :: Gen a -> Gen (NumberSegment a)
liftArbitrary Gen a
gen = Gen (NumberSegment a)
go
      where go :: Gen (NumberSegment a)
go = MNumberSegment a
-> a -> Text -> MNumberSegment a -> NumberSegment a
forall i.
MNumberSegment i
-> i -> Text -> MNumberSegment i -> NumberSegment i
NumberSegment (MNumberSegment a
 -> a -> Text -> MNumberSegment a -> NumberSegment a)
-> Gen (MNumberSegment a)
-> Gen (a -> Text -> MNumberSegment a -> NumberSegment a)
forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
<$> Gen (NumberSegment a) -> Gen (MNumberSegment a)
forall (f :: * -> *) a. Arbitrary1 f => Gen a -> Gen (f a)
liftArbitrary Gen (NumberSegment a)
go Gen (a -> Text -> MNumberSegment a -> NumberSegment a)
-> Gen a -> Gen (Text -> MNumberSegment a -> NumberSegment a)
forall (f :: * -> *) a b. Applicative f => f (a -> b) -> f a -> f b
<*> Gen a
gen Gen (Text -> MNumberSegment a -> NumberSegment a)
-> Gen Text -> Gen (MNumberSegment a -> NumberSegment a)
forall (f :: * -> *) a b. Applicative f => f (a -> b) -> f a -> f b
<*> Gen Text
_genText Gen (MNumberSegment a -> NumberSegment a)
-> Gen (MNumberSegment a) -> Gen (NumberSegment a)
forall (f :: * -> *) a b. Applicative f => f (a -> b) -> f a -> f b
<*> Gen (NumberSegment a) -> Gen (MNumberSegment a)
forall (f :: * -> *) a. Arbitrary1 f => Gen a -> Gen (f a)
liftArbitrary Gen (NumberSegment a)
go

instance Arbitrary i => Arbitrary (NumberSegment i) where
  arbitrary :: Gen (NumberSegment i)
arbitrary = Gen (NumberSegment i)
forall (f :: * -> *) a. (Arbitrary1 f, Arbitrary a) => Gen (f a)
arbitrary1
  shrink :: NumberSegment i -> [NumberSegment i]
shrink (NumberSegment MNumberSegment i
dv i
val Text
txt MNumberSegment i
rm) =
    ((\MNumberSegment i
x -> MNumberSegment i
-> i -> Text -> MNumberSegment i -> NumberSegment i
forall i.
MNumberSegment i
-> i -> Text -> MNumberSegment i -> NumberSegment i
NumberSegment MNumberSegment i
x i
val Text
txt MNumberSegment i
rm) (MNumberSegment i -> NumberSegment i)
-> [MNumberSegment i] -> [NumberSegment i]
forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
<$> MNumberSegment i -> [MNumberSegment i]
forall a. Arbitrary a => a -> [a]
shrink MNumberSegment i
dv) [NumberSegment i] -> [NumberSegment i] -> [NumberSegment i]
forall a. Semigroup a => a -> a -> a
<>
    ((\i
x -> MNumberSegment i
-> i -> Text -> MNumberSegment i -> NumberSegment i
forall i.
MNumberSegment i
-> i -> Text -> MNumberSegment i -> NumberSegment i
NumberSegment MNumberSegment i
dv i
x Text
txt MNumberSegment i
rm) (i -> NumberSegment i) -> [i] -> [NumberSegment i]
forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
<$> i -> [i]
forall a. Arbitrary a => a -> [a]
shrink i
val) [NumberSegment i] -> [NumberSegment i] -> [NumberSegment i]
forall a. Semigroup a => a -> a -> a
<>
    ((\Text
x -> MNumberSegment i
-> i -> Text -> MNumberSegment i -> NumberSegment i
forall i.
MNumberSegment i
-> i -> Text -> MNumberSegment i -> NumberSegment i
NumberSegment MNumberSegment i
dv i
val Text
x MNumberSegment i
rm) (Text -> NumberSegment i) -> [Text] -> [NumberSegment i]
forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
<$> Text -> [Text]
_shrinkText Text
txt) [NumberSegment i] -> [NumberSegment i] -> [NumberSegment i]
forall a. Semigroup a => a -> a -> a
<>
    (MNumberSegment i
-> i -> Text -> MNumberSegment i -> NumberSegment i
forall i.
MNumberSegment i
-> i -> Text -> MNumberSegment i -> NumberSegment i
NumberSegment MNumberSegment i
dv i
val Text
txt (MNumberSegment i -> NumberSegment i)
-> [MNumberSegment i] -> [NumberSegment i]
forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
<$> MNumberSegment i -> [MNumberSegment i]
forall a. Arbitrary a => a -> [a]
shrink MNumberSegment i
rm)


-- | A 'Maybe' variant of the 'NumberSegment' data type. This is used since the
-- division part can be one, or the remainder part can be zero.
type MNumberSegment i = Maybe (NumberSegment i)

-- | A data type that specifies the different types of numbers. These can be
-- used to specify the "target format". The 'Default' number type is 'Cardinal'.
data NumberType
  = Cardinal  -- ^ /Cardinal/ numbers like one, two, three, etc.
  | Ordinal  -- ^ /Ordinal/ numbers like first, second, third, etc.
  | ShortOrdinal -- ^ /Short ordinal/ numbers like 1st, 2nd, 3rd, etc.
  deriving (NumberType
NumberType -> NumberType -> Bounded NumberType
forall a. a -> a -> Bounded a
maxBound :: NumberType
$cmaxBound :: NumberType
minBound :: NumberType
$cminBound :: NumberType
Bounded, Typeable NumberType
DataType
Constr
Typeable NumberType
-> (forall (c :: * -> *).
    (forall d b. Data d => c (d -> b) -> d -> c b)
    -> (forall g. g -> c g) -> NumberType -> c NumberType)
-> (forall (c :: * -> *).
    (forall b r. Data b => c (b -> r) -> c r)
    -> (forall r. r -> c r) -> Constr -> c NumberType)
-> (NumberType -> Constr)
-> (NumberType -> DataType)
-> (forall (t :: * -> *) (c :: * -> *).
    Typeable t =>
    (forall d. Data d => c (t d)) -> Maybe (c NumberType))
-> (forall (t :: * -> * -> *) (c :: * -> *).
    Typeable t =>
    (forall d e. (Data d, Data e) => c (t d e))
    -> Maybe (c NumberType))
-> ((forall b. Data b => b -> b) -> NumberType -> NumberType)
-> (forall r r'.
    (r -> r' -> r)
    -> r -> (forall d. Data d => d -> r') -> NumberType -> r)
-> (forall r r'.
    (r' -> r -> r)
    -> r -> (forall d. Data d => d -> r') -> NumberType -> r)
-> (forall u. (forall d. Data d => d -> u) -> NumberType -> [u])
-> (forall u.
    Int -> (forall d. Data d => d -> u) -> NumberType -> u)
-> (forall (m :: * -> *).
    Monad m =>
    (forall d. Data d => d -> m d) -> NumberType -> m NumberType)
-> (forall (m :: * -> *).
    MonadPlus m =>
    (forall d. Data d => d -> m d) -> NumberType -> m NumberType)
-> (forall (m :: * -> *).
    MonadPlus m =>
    (forall d. Data d => d -> m d) -> NumberType -> m NumberType)
-> Data NumberType
NumberType -> DataType
NumberType -> Constr
(forall b. Data b => b -> b) -> NumberType -> NumberType
(forall d b. Data d => c (d -> b) -> d -> c b)
-> (forall g. g -> c g) -> NumberType -> c NumberType
(forall b r. Data b => c (b -> r) -> c r)
-> (forall r. r -> c r) -> Constr -> c NumberType
forall a.
Typeable a
-> (forall (c :: * -> *).
    (forall d b. Data d => c (d -> b) -> d -> c b)
    -> (forall g. g -> c g) -> a -> c a)
-> (forall (c :: * -> *).
    (forall b r. Data b => c (b -> r) -> c r)
    -> (forall r. r -> c r) -> Constr -> c a)
-> (a -> Constr)
-> (a -> DataType)
-> (forall (t :: * -> *) (c :: * -> *).
    Typeable t =>
    (forall d. Data d => c (t d)) -> Maybe (c a))
-> (forall (t :: * -> * -> *) (c :: * -> *).
    Typeable t =>
    (forall d e. (Data d, Data e) => c (t d e)) -> Maybe (c a))
-> ((forall b. Data b => b -> b) -> a -> a)
-> (forall r r'.
    (r -> r' -> r) -> r -> (forall d. Data d => d -> r') -> a -> r)
-> (forall r r'.
    (r' -> r -> r) -> r -> (forall d. Data d => d -> r') -> a -> r)
-> (forall u. (forall d. Data d => d -> u) -> a -> [u])
-> (forall u. Int -> (forall d. Data d => d -> u) -> a -> u)
-> (forall (m :: * -> *).
    Monad m =>
    (forall d. Data d => d -> m d) -> a -> m a)
-> (forall (m :: * -> *).
    MonadPlus m =>
    (forall d. Data d => d -> m d) -> a -> m a)
-> (forall (m :: * -> *).
    MonadPlus m =>
    (forall d. Data d => d -> m d) -> a -> m a)
-> Data a
forall u. Int -> (forall d. Data d => d -> u) -> NumberType -> u
forall u. (forall d. Data d => d -> u) -> NumberType -> [u]
forall r r'.
(r -> r' -> r)
-> r -> (forall d. Data d => d -> r') -> NumberType -> r
forall r r'.
(r' -> r -> r)
-> r -> (forall d. Data d => d -> r') -> NumberType -> r
forall (m :: * -> *).
Monad m =>
(forall d. Data d => d -> m d) -> NumberType -> m NumberType
forall (m :: * -> *).
MonadPlus m =>
(forall d. Data d => d -> m d) -> NumberType -> m NumberType
forall (c :: * -> *).
(forall b r. Data b => c (b -> r) -> c r)
-> (forall r. r -> c r) -> Constr -> c NumberType
forall (c :: * -> *).
(forall d b. Data d => c (d -> b) -> d -> c b)
-> (forall g. g -> c g) -> NumberType -> c NumberType
forall (t :: * -> *) (c :: * -> *).
Typeable t =>
(forall d. Data d => c (t d)) -> Maybe (c NumberType)
forall (t :: * -> * -> *) (c :: * -> *).
Typeable t =>
(forall d e. (Data d, Data e) => c (t d e)) -> Maybe (c NumberType)
$cShortOrdinal :: Constr
$cOrdinal :: Constr
$cCardinal :: Constr
$tNumberType :: DataType
gmapMo :: (forall d. Data d => d -> m d) -> NumberType -> m NumberType
$cgmapMo :: forall (m :: * -> *).
MonadPlus m =>
(forall d. Data d => d -> m d) -> NumberType -> m NumberType
gmapMp :: (forall d. Data d => d -> m d) -> NumberType -> m NumberType
$cgmapMp :: forall (m :: * -> *).
MonadPlus m =>
(forall d. Data d => d -> m d) -> NumberType -> m NumberType
gmapM :: (forall d. Data d => d -> m d) -> NumberType -> m NumberType
$cgmapM :: forall (m :: * -> *).
Monad m =>
(forall d. Data d => d -> m d) -> NumberType -> m NumberType
gmapQi :: Int -> (forall d. Data d => d -> u) -> NumberType -> u
$cgmapQi :: forall u. Int -> (forall d. Data d => d -> u) -> NumberType -> u
gmapQ :: (forall d. Data d => d -> u) -> NumberType -> [u]
$cgmapQ :: forall u. (forall d. Data d => d -> u) -> NumberType -> [u]
gmapQr :: (r' -> r -> r)
-> r -> (forall d. Data d => d -> r') -> NumberType -> r
$cgmapQr :: forall r r'.
(r' -> r -> r)
-> r -> (forall d. Data d => d -> r') -> NumberType -> r
gmapQl :: (r -> r' -> r)
-> r -> (forall d. Data d => d -> r') -> NumberType -> r
$cgmapQl :: forall r r'.
(r -> r' -> r)
-> r -> (forall d. Data d => d -> r') -> NumberType -> r
gmapT :: (forall b. Data b => b -> b) -> NumberType -> NumberType
$cgmapT :: (forall b. Data b => b -> b) -> NumberType -> NumberType
dataCast2 :: (forall d e. (Data d, Data e) => c (t d e)) -> Maybe (c NumberType)
$cdataCast2 :: forall (t :: * -> * -> *) (c :: * -> *).
Typeable t =>
(forall d e. (Data d, Data e) => c (t d e)) -> Maybe (c NumberType)
dataCast1 :: (forall d. Data d => c (t d)) -> Maybe (c NumberType)
$cdataCast1 :: forall (t :: * -> *) (c :: * -> *).
Typeable t =>
(forall d. Data d => c (t d)) -> Maybe (c NumberType)
dataTypeOf :: NumberType -> DataType
$cdataTypeOf :: NumberType -> DataType
toConstr :: NumberType -> Constr
$ctoConstr :: NumberType -> Constr
gunfold :: (forall b r. Data b => c (b -> r) -> c r)
-> (forall r. r -> c r) -> Constr -> c NumberType
$cgunfold :: forall (c :: * -> *).
(forall b r. Data b => c (b -> r) -> c r)
-> (forall r. r -> c r) -> Constr -> c NumberType
gfoldl :: (forall d b. Data d => c (d -> b) -> d -> c b)
-> (forall g. g -> c g) -> NumberType -> c NumberType
$cgfoldl :: forall (c :: * -> *).
(forall d b. Data d => c (d -> b) -> d -> c b)
-> (forall g. g -> c g) -> NumberType -> c NumberType
$cp1Data :: Typeable NumberType
Data, Int -> NumberType
NumberType -> Int
NumberType -> [NumberType]
NumberType -> NumberType
NumberType -> NumberType -> [NumberType]
NumberType -> NumberType -> NumberType -> [NumberType]
(NumberType -> NumberType)
-> (NumberType -> NumberType)
-> (Int -> NumberType)
-> (NumberType -> Int)
-> (NumberType -> [NumberType])
-> (NumberType -> NumberType -> [NumberType])
-> (NumberType -> NumberType -> [NumberType])
-> (NumberType -> NumberType -> NumberType -> [NumberType])
-> Enum NumberType
forall a.
(a -> a)
-> (a -> a)
-> (Int -> a)
-> (a -> Int)
-> (a -> [a])
-> (a -> a -> [a])
-> (a -> a -> [a])
-> (a -> a -> a -> [a])
-> Enum a
enumFromThenTo :: NumberType -> NumberType -> NumberType -> [NumberType]
$cenumFromThenTo :: NumberType -> NumberType -> NumberType -> [NumberType]
enumFromTo :: NumberType -> NumberType -> [NumberType]
$cenumFromTo :: NumberType -> NumberType -> [NumberType]
enumFromThen :: NumberType -> NumberType -> [NumberType]
$cenumFromThen :: NumberType -> NumberType -> [NumberType]
enumFrom :: NumberType -> [NumberType]
$cenumFrom :: NumberType -> [NumberType]
fromEnum :: NumberType -> Int
$cfromEnum :: NumberType -> Int
toEnum :: Int -> NumberType
$ctoEnum :: Int -> NumberType
pred :: NumberType -> NumberType
$cpred :: NumberType -> NumberType
succ :: NumberType -> NumberType
$csucc :: NumberType -> NumberType
Enum, NumberType -> NumberType -> Bool
(NumberType -> NumberType -> Bool)
-> (NumberType -> NumberType -> Bool) -> Eq NumberType
forall a. (a -> a -> Bool) -> (a -> a -> Bool) -> Eq a
/= :: NumberType -> NumberType -> Bool
$c/= :: NumberType -> NumberType -> Bool
== :: NumberType -> NumberType -> Bool
$c== :: NumberType -> NumberType -> Bool
Eq, (forall x. NumberType -> Rep NumberType x)
-> (forall x. Rep NumberType x -> NumberType) -> Generic NumberType
forall x. Rep NumberType x -> NumberType
forall x. NumberType -> Rep NumberType x
forall a.
(forall x. a -> Rep a x) -> (forall x. Rep a x -> a) -> Generic a
$cto :: forall x. Rep NumberType x -> NumberType
$cfrom :: forall x. NumberType -> Rep NumberType x
Generic, Eq NumberType
Eq NumberType
-> (NumberType -> NumberType -> Ordering)
-> (NumberType -> NumberType -> Bool)
-> (NumberType -> NumberType -> Bool)
-> (NumberType -> NumberType -> Bool)
-> (NumberType -> NumberType -> Bool)
-> (NumberType -> NumberType -> NumberType)
-> (NumberType -> NumberType -> NumberType)
-> Ord NumberType
NumberType -> NumberType -> Bool
NumberType -> NumberType -> Ordering
NumberType -> NumberType -> NumberType
forall a.
Eq a
-> (a -> a -> Ordering)
-> (a -> a -> Bool)
-> (a -> a -> Bool)
-> (a -> a -> Bool)
-> (a -> a -> Bool)
-> (a -> a -> a)
-> (a -> a -> a)
-> Ord a
min :: NumberType -> NumberType -> NumberType
$cmin :: NumberType -> NumberType -> NumberType
max :: NumberType -> NumberType -> NumberType
$cmax :: NumberType -> NumberType -> NumberType
>= :: NumberType -> NumberType -> Bool
$c>= :: NumberType -> NumberType -> Bool
> :: NumberType -> NumberType -> Bool
$c> :: NumberType -> NumberType -> Bool
<= :: NumberType -> NumberType -> Bool
$c<= :: NumberType -> NumberType -> Bool
< :: NumberType -> NumberType -> Bool
$c< :: NumberType -> NumberType -> Bool
compare :: NumberType -> NumberType -> Ordering
$ccompare :: NumberType -> NumberType -> Ordering
$cp1Ord :: Eq NumberType
Ord, ReadPrec [NumberType]
ReadPrec NumberType
Int -> ReadS NumberType
ReadS [NumberType]
(Int -> ReadS NumberType)
-> ReadS [NumberType]
-> ReadPrec NumberType
-> ReadPrec [NumberType]
-> Read NumberType
forall a.
(Int -> ReadS a)
-> ReadS [a] -> ReadPrec a -> ReadPrec [a] -> Read a
readListPrec :: ReadPrec [NumberType]
$creadListPrec :: ReadPrec [NumberType]
readPrec :: ReadPrec NumberType
$creadPrec :: ReadPrec NumberType
readList :: ReadS [NumberType]
$creadList :: ReadS [NumberType]
readsPrec :: Int -> ReadS NumberType
$creadsPrec :: Int -> ReadS NumberType
Read, Int -> NumberType -> ShowS
[NumberType] -> ShowS
NumberType -> String
(Int -> NumberType -> ShowS)
-> (NumberType -> String)
-> ([NumberType] -> ShowS)
-> Show NumberType
forall a.
(Int -> a -> ShowS) -> (a -> String) -> ([a] -> ShowS) -> Show a
showList :: [NumberType] -> ShowS
$cshowList :: [NumberType] -> ShowS
show :: NumberType -> String
$cshow :: NumberType -> String
showsPrec :: Int -> NumberType -> ShowS
$cshowsPrec :: Int -> NumberType -> ShowS
Show)

instance Arbitrary NumberType where
  arbitrary :: Gen NumberType
arbitrary = Gen NumberType
forall a. (Bounded a, Enum a) => Gen a
arbitraryBoundedEnum

instance NFData NumberType

-- | The type of a function that converts time to its description. The first
-- two parameters are used to make conversion more convenient.
type ClockText
  =  ClockSegment  -- ^ The 'ClockSegment' that describes the state of minutes within an hour.
  -> DaySegment  -- ^ The 'DaySegment' that describes the state of hours within a day.
  -> Int  -- ^ The number of hours.
  -> Int  -- ^ The number of minutes.
  -> Text  -- ^ A 'Text' object that describes the given time.

-- | A data type that describes the state of the minutes within an hour.
data ClockSegment
  = OClock  -- ^ The number of minutes is zero.
  | Past Int  -- ^ The parameter is the number of minutes past the hour, this is between @1@ and @14@.
  | QuarterPast  -- ^ It is a quarter past the hour.
  | ToHalf Int  -- ^ The parameter is the number of minutes until half, this is between @1@ and @14@.
  | Half  -- ^ It is half past an hour.
  | PastHalf Int  -- ^ The parameter is the number of minutes past half, this is between @1@ and @14@.
  | QuarterTo  -- ^ It is a quarter to an hour.
  | To Int  -- ^ The parameter is the number of minutes to the next hour, this is between @1@ and @14@.
  deriving (Typeable ClockSegment
DataType
Constr
Typeable ClockSegment
-> (forall (c :: * -> *).
    (forall d b. Data d => c (d -> b) -> d -> c b)
    -> (forall g. g -> c g) -> ClockSegment -> c ClockSegment)
-> (forall (c :: * -> *).
    (forall b r. Data b => c (b -> r) -> c r)
    -> (forall r. r -> c r) -> Constr -> c ClockSegment)
-> (ClockSegment -> Constr)
-> (ClockSegment -> DataType)
-> (forall (t :: * -> *) (c :: * -> *).
    Typeable t =>
    (forall d. Data d => c (t d)) -> Maybe (c ClockSegment))
-> (forall (t :: * -> * -> *) (c :: * -> *).
    Typeable t =>
    (forall d e. (Data d, Data e) => c (t d e))
    -> Maybe (c ClockSegment))
-> ((forall b. Data b => b -> b) -> ClockSegment -> ClockSegment)
-> (forall r r'.
    (r -> r' -> r)
    -> r -> (forall d. Data d => d -> r') -> ClockSegment -> r)
-> (forall r r'.
    (r' -> r -> r)
    -> r -> (forall d. Data d => d -> r') -> ClockSegment -> r)
-> (forall u. (forall d. Data d => d -> u) -> ClockSegment -> [u])
-> (forall u.
    Int -> (forall d. Data d => d -> u) -> ClockSegment -> u)
-> (forall (m :: * -> *).
    Monad m =>
    (forall d. Data d => d -> m d) -> ClockSegment -> m ClockSegment)
-> (forall (m :: * -> *).
    MonadPlus m =>
    (forall d. Data d => d -> m d) -> ClockSegment -> m ClockSegment)
-> (forall (m :: * -> *).
    MonadPlus m =>
    (forall d. Data d => d -> m d) -> ClockSegment -> m ClockSegment)
-> Data ClockSegment
ClockSegment -> DataType
ClockSegment -> Constr
(forall b. Data b => b -> b) -> ClockSegment -> ClockSegment
(forall d b. Data d => c (d -> b) -> d -> c b)
-> (forall g. g -> c g) -> ClockSegment -> c ClockSegment
(forall b r. Data b => c (b -> r) -> c r)
-> (forall r. r -> c r) -> Constr -> c ClockSegment
forall a.
Typeable a
-> (forall (c :: * -> *).
    (forall d b. Data d => c (d -> b) -> d -> c b)
    -> (forall g. g -> c g) -> a -> c a)
-> (forall (c :: * -> *).
    (forall b r. Data b => c (b -> r) -> c r)
    -> (forall r. r -> c r) -> Constr -> c a)
-> (a -> Constr)
-> (a -> DataType)
-> (forall (t :: * -> *) (c :: * -> *).
    Typeable t =>
    (forall d. Data d => c (t d)) -> Maybe (c a))
-> (forall (t :: * -> * -> *) (c :: * -> *).
    Typeable t =>
    (forall d e. (Data d, Data e) => c (t d e)) -> Maybe (c a))
-> ((forall b. Data b => b -> b) -> a -> a)
-> (forall r r'.
    (r -> r' -> r) -> r -> (forall d. Data d => d -> r') -> a -> r)
-> (forall r r'.
    (r' -> r -> r) -> r -> (forall d. Data d => d -> r') -> a -> r)
-> (forall u. (forall d. Data d => d -> u) -> a -> [u])
-> (forall u. Int -> (forall d. Data d => d -> u) -> a -> u)
-> (forall (m :: * -> *).
    Monad m =>
    (forall d. Data d => d -> m d) -> a -> m a)
-> (forall (m :: * -> *).
    MonadPlus m =>
    (forall d. Data d => d -> m d) -> a -> m a)
-> (forall (m :: * -> *).
    MonadPlus m =>
    (forall d. Data d => d -> m d) -> a -> m a)
-> Data a
forall u. Int -> (forall d. Data d => d -> u) -> ClockSegment -> u
forall u. (forall d. Data d => d -> u) -> ClockSegment -> [u]
forall r r'.
(r -> r' -> r)
-> r -> (forall d. Data d => d -> r') -> ClockSegment -> r
forall r r'.
(r' -> r -> r)
-> r -> (forall d. Data d => d -> r') -> ClockSegment -> r
forall (m :: * -> *).
Monad m =>
(forall d. Data d => d -> m d) -> ClockSegment -> m ClockSegment
forall (m :: * -> *).
MonadPlus m =>
(forall d. Data d => d -> m d) -> ClockSegment -> m ClockSegment
forall (c :: * -> *).
(forall b r. Data b => c (b -> r) -> c r)
-> (forall r. r -> c r) -> Constr -> c ClockSegment
forall (c :: * -> *).
(forall d b. Data d => c (d -> b) -> d -> c b)
-> (forall g. g -> c g) -> ClockSegment -> c ClockSegment
forall (t :: * -> *) (c :: * -> *).
Typeable t =>
(forall d. Data d => c (t d)) -> Maybe (c ClockSegment)
forall (t :: * -> * -> *) (c :: * -> *).
Typeable t =>
(forall d e. (Data d, Data e) => c (t d e))
-> Maybe (c ClockSegment)
$cTo :: Constr
$cQuarterTo :: Constr
$cPastHalf :: Constr
$cHalf :: Constr
$cToHalf :: Constr
$cQuarterPast :: Constr
$cPast :: Constr
$cOClock :: Constr
$tClockSegment :: DataType
gmapMo :: (forall d. Data d => d -> m d) -> ClockSegment -> m ClockSegment
$cgmapMo :: forall (m :: * -> *).
MonadPlus m =>
(forall d. Data d => d -> m d) -> ClockSegment -> m ClockSegment
gmapMp :: (forall d. Data d => d -> m d) -> ClockSegment -> m ClockSegment
$cgmapMp :: forall (m :: * -> *).
MonadPlus m =>
(forall d. Data d => d -> m d) -> ClockSegment -> m ClockSegment
gmapM :: (forall d. Data d => d -> m d) -> ClockSegment -> m ClockSegment
$cgmapM :: forall (m :: * -> *).
Monad m =>
(forall d. Data d => d -> m d) -> ClockSegment -> m ClockSegment
gmapQi :: Int -> (forall d. Data d => d -> u) -> ClockSegment -> u
$cgmapQi :: forall u. Int -> (forall d. Data d => d -> u) -> ClockSegment -> u
gmapQ :: (forall d. Data d => d -> u) -> ClockSegment -> [u]
$cgmapQ :: forall u. (forall d. Data d => d -> u) -> ClockSegment -> [u]
gmapQr :: (r' -> r -> r)
-> r -> (forall d. Data d => d -> r') -> ClockSegment -> r
$cgmapQr :: forall r r'.
(r' -> r -> r)
-> r -> (forall d. Data d => d -> r') -> ClockSegment -> r
gmapQl :: (r -> r' -> r)
-> r -> (forall d. Data d => d -> r') -> ClockSegment -> r
$cgmapQl :: forall r r'.
(r -> r' -> r)
-> r -> (forall d. Data d => d -> r') -> ClockSegment -> r
gmapT :: (forall b. Data b => b -> b) -> ClockSegment -> ClockSegment
$cgmapT :: (forall b. Data b => b -> b) -> ClockSegment -> ClockSegment
dataCast2 :: (forall d e. (Data d, Data e) => c (t d e))
-> Maybe (c ClockSegment)
$cdataCast2 :: forall (t :: * -> * -> *) (c :: * -> *).
Typeable t =>
(forall d e. (Data d, Data e) => c (t d e))
-> Maybe (c ClockSegment)
dataCast1 :: (forall d. Data d => c (t d)) -> Maybe (c ClockSegment)
$cdataCast1 :: forall (t :: * -> *) (c :: * -> *).
Typeable t =>
(forall d. Data d => c (t d)) -> Maybe (c ClockSegment)
dataTypeOf :: ClockSegment -> DataType
$cdataTypeOf :: ClockSegment -> DataType
toConstr :: ClockSegment -> Constr
$ctoConstr :: ClockSegment -> Constr
gunfold :: (forall b r. Data b => c (b -> r) -> c r)
-> (forall r. r -> c r) -> Constr -> c ClockSegment
$cgunfold :: forall (c :: * -> *).
(forall b r. Data b => c (b -> r) -> c r)
-> (forall r. r -> c r) -> Constr -> c ClockSegment
gfoldl :: (forall d b. Data d => c (d -> b) -> d -> c b)
-> (forall g. g -> c g) -> ClockSegment -> c ClockSegment
$cgfoldl :: forall (c :: * -> *).
(forall d b. Data d => c (d -> b) -> d -> c b)
-> (forall g. g -> c g) -> ClockSegment -> c ClockSegment
$cp1Data :: Typeable ClockSegment
Data, ClockSegment -> ClockSegment -> Bool
(ClockSegment -> ClockSegment -> Bool)
-> (ClockSegment -> ClockSegment -> Bool) -> Eq ClockSegment
forall a. (a -> a -> Bool) -> (a -> a -> Bool) -> Eq a
/= :: ClockSegment -> ClockSegment -> Bool
$c/= :: ClockSegment -> ClockSegment -> Bool
== :: ClockSegment -> ClockSegment -> Bool
$c== :: ClockSegment -> ClockSegment -> Bool
Eq, (forall x. ClockSegment -> Rep ClockSegment x)
-> (forall x. Rep ClockSegment x -> ClockSegment)
-> Generic ClockSegment
forall x. Rep ClockSegment x -> ClockSegment
forall x. ClockSegment -> Rep ClockSegment x
forall a.
(forall x. a -> Rep a x) -> (forall x. Rep a x -> a) -> Generic a
$cto :: forall x. Rep ClockSegment x -> ClockSegment
$cfrom :: forall x. ClockSegment -> Rep ClockSegment x
Generic, Eq ClockSegment
Eq ClockSegment
-> (ClockSegment -> ClockSegment -> Ordering)
-> (ClockSegment -> ClockSegment -> Bool)
-> (ClockSegment -> ClockSegment -> Bool)
-> (ClockSegment -> ClockSegment -> Bool)
-> (ClockSegment -> ClockSegment -> Bool)
-> (ClockSegment -> ClockSegment -> ClockSegment)
-> (ClockSegment -> ClockSegment -> ClockSegment)
-> Ord ClockSegment
ClockSegment -> ClockSegment -> Bool
ClockSegment -> ClockSegment -> Ordering
ClockSegment -> ClockSegment -> ClockSegment
forall a.
Eq a
-> (a -> a -> Ordering)
-> (a -> a -> Bool)
-> (a -> a -> Bool)
-> (a -> a -> Bool)
-> (a -> a -> Bool)
-> (a -> a -> a)
-> (a -> a -> a)
-> Ord a
min :: ClockSegment -> ClockSegment -> ClockSegment
$cmin :: ClockSegment -> ClockSegment -> ClockSegment
max :: ClockSegment -> ClockSegment -> ClockSegment
$cmax :: ClockSegment -> ClockSegment -> ClockSegment
>= :: ClockSegment -> ClockSegment -> Bool
$c>= :: ClockSegment -> ClockSegment -> Bool
> :: ClockSegment -> ClockSegment -> Bool
$c> :: ClockSegment -> ClockSegment -> Bool
<= :: ClockSegment -> ClockSegment -> Bool
$c<= :: ClockSegment -> ClockSegment -> Bool
< :: ClockSegment -> ClockSegment -> Bool
$c< :: ClockSegment -> ClockSegment -> Bool
compare :: ClockSegment -> ClockSegment -> Ordering
$ccompare :: ClockSegment -> ClockSegment -> Ordering
$cp1Ord :: Eq ClockSegment
Ord, ReadPrec [ClockSegment]
ReadPrec ClockSegment
Int -> ReadS ClockSegment
ReadS [ClockSegment]
(Int -> ReadS ClockSegment)
-> ReadS [ClockSegment]
-> ReadPrec ClockSegment
-> ReadPrec [ClockSegment]
-> Read ClockSegment
forall a.
(Int -> ReadS a)
-> ReadS [a] -> ReadPrec a -> ReadPrec [a] -> Read a
readListPrec :: ReadPrec [ClockSegment]
$creadListPrec :: ReadPrec [ClockSegment]
readPrec :: ReadPrec ClockSegment
$creadPrec :: ReadPrec ClockSegment
readList :: ReadS [ClockSegment]
$creadList :: ReadS [ClockSegment]
readsPrec :: Int -> ReadS ClockSegment
$creadsPrec :: Int -> ReadS ClockSegment
Read, Int -> ClockSegment -> ShowS
[ClockSegment] -> ShowS
ClockSegment -> String
(Int -> ClockSegment -> ShowS)
-> (ClockSegment -> String)
-> ([ClockSegment] -> ShowS)
-> Show ClockSegment
forall a.
(Int -> a -> ShowS) -> (a -> String) -> ([a] -> ShowS) -> Show a
showList :: [ClockSegment] -> ShowS
$cshowList :: [ClockSegment] -> ShowS
show :: ClockSegment -> String
$cshow :: ClockSegment -> String
showsPrec :: Int -> ClockSegment -> ShowS
$cshowsPrec :: Int -> ClockSegment -> ShowS
Show)

instance NFData ClockSegment

instance Arbitrary ClockSegment where
  arbitrary :: Gen ClockSegment
arbitrary = Int -> ClockSegment
toClockSegment (Int -> ClockSegment) -> Gen Int -> Gen ClockSegment
forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
<$> (Int, Int) -> Gen Int
forall a. Random a => (a, a) -> Gen a
choose (Int
0, Int
59)

-- | A data type that describes the state of the hours within a day.
data DayPart
  = Night  -- ^ It is night, this means that it is between @0:00@ and @5:59@.
  | Morning  -- ^ It is morning, this means that it is between @6:00@ and @11:59@.
  | Afternoon  -- ^ It is afternoon, this means it is between @12:00@ and @17:59@.
  | Evening  -- ^ It is evening, this means it is between @18:00@ and @23:59@.
  deriving (DayPart
DayPart -> DayPart -> Bounded DayPart
forall a. a -> a -> Bounded a
maxBound :: DayPart
$cmaxBound :: DayPart
minBound :: DayPart
$cminBound :: DayPart
Bounded, Typeable DayPart
DataType
Constr
Typeable DayPart
-> (forall (c :: * -> *).
    (forall d b. Data d => c (d -> b) -> d -> c b)
    -> (forall g. g -> c g) -> DayPart -> c DayPart)
-> (forall (c :: * -> *).
    (forall b r. Data b => c (b -> r) -> c r)
    -> (forall r. r -> c r) -> Constr -> c DayPart)
-> (DayPart -> Constr)
-> (DayPart -> DataType)
-> (forall (t :: * -> *) (c :: * -> *).
    Typeable t =>
    (forall d. Data d => c (t d)) -> Maybe (c DayPart))
-> (forall (t :: * -> * -> *) (c :: * -> *).
    Typeable t =>
    (forall d e. (Data d, Data e) => c (t d e)) -> Maybe (c DayPart))
-> ((forall b. Data b => b -> b) -> DayPart -> DayPart)
-> (forall r r'.
    (r -> r' -> r)
    -> r -> (forall d. Data d => d -> r') -> DayPart -> r)
-> (forall r r'.
    (r' -> r -> r)
    -> r -> (forall d. Data d => d -> r') -> DayPart -> r)
-> (forall u. (forall d. Data d => d -> u) -> DayPart -> [u])
-> (forall u. Int -> (forall d. Data d => d -> u) -> DayPart -> u)
-> (forall (m :: * -> *).
    Monad m =>
    (forall d. Data d => d -> m d) -> DayPart -> m DayPart)
-> (forall (m :: * -> *).
    MonadPlus m =>
    (forall d. Data d => d -> m d) -> DayPart -> m DayPart)
-> (forall (m :: * -> *).
    MonadPlus m =>
    (forall d. Data d => d -> m d) -> DayPart -> m DayPart)
-> Data DayPart
DayPart -> DataType
DayPart -> Constr
(forall b. Data b => b -> b) -> DayPart -> DayPart
(forall d b. Data d => c (d -> b) -> d -> c b)
-> (forall g. g -> c g) -> DayPart -> c DayPart
(forall b r. Data b => c (b -> r) -> c r)
-> (forall r. r -> c r) -> Constr -> c DayPart
forall a.
Typeable a
-> (forall (c :: * -> *).
    (forall d b. Data d => c (d -> b) -> d -> c b)
    -> (forall g. g -> c g) -> a -> c a)
-> (forall (c :: * -> *).
    (forall b r. Data b => c (b -> r) -> c r)
    -> (forall r. r -> c r) -> Constr -> c a)
-> (a -> Constr)
-> (a -> DataType)
-> (forall (t :: * -> *) (c :: * -> *).
    Typeable t =>
    (forall d. Data d => c (t d)) -> Maybe (c a))
-> (forall (t :: * -> * -> *) (c :: * -> *).
    Typeable t =>
    (forall d e. (Data d, Data e) => c (t d e)) -> Maybe (c a))
-> ((forall b. Data b => b -> b) -> a -> a)
-> (forall r r'.
    (r -> r' -> r) -> r -> (forall d. Data d => d -> r') -> a -> r)
-> (forall r r'.
    (r' -> r -> r) -> r -> (forall d. Data d => d -> r') -> a -> r)
-> (forall u. (forall d. Data d => d -> u) -> a -> [u])
-> (forall u. Int -> (forall d. Data d => d -> u) -> a -> u)
-> (forall (m :: * -> *).
    Monad m =>
    (forall d. Data d => d -> m d) -> a -> m a)
-> (forall (m :: * -> *).
    MonadPlus m =>
    (forall d. Data d => d -> m d) -> a -> m a)
-> (forall (m :: * -> *).
    MonadPlus m =>
    (forall d. Data d => d -> m d) -> a -> m a)
-> Data a
forall u. Int -> (forall d. Data d => d -> u) -> DayPart -> u
forall u. (forall d. Data d => d -> u) -> DayPart -> [u]
forall r r'.
(r -> r' -> r)
-> r -> (forall d. Data d => d -> r') -> DayPart -> r
forall r r'.
(r' -> r -> r)
-> r -> (forall d. Data d => d -> r') -> DayPart -> r
forall (m :: * -> *).
Monad m =>
(forall d. Data d => d -> m d) -> DayPart -> m DayPart
forall (m :: * -> *).
MonadPlus m =>
(forall d. Data d => d -> m d) -> DayPart -> m DayPart
forall (c :: * -> *).
(forall b r. Data b => c (b -> r) -> c r)
-> (forall r. r -> c r) -> Constr -> c DayPart
forall (c :: * -> *).
(forall d b. Data d => c (d -> b) -> d -> c b)
-> (forall g. g -> c g) -> DayPart -> c DayPart
forall (t :: * -> *) (c :: * -> *).
Typeable t =>
(forall d. Data d => c (t d)) -> Maybe (c DayPart)
forall (t :: * -> * -> *) (c :: * -> *).
Typeable t =>
(forall d e. (Data d, Data e) => c (t d e)) -> Maybe (c DayPart)
$cEvening :: Constr
$cAfternoon :: Constr
$cMorning :: Constr
$cNight :: Constr
$tDayPart :: DataType
gmapMo :: (forall d. Data d => d -> m d) -> DayPart -> m DayPart
$cgmapMo :: forall (m :: * -> *).
MonadPlus m =>
(forall d. Data d => d -> m d) -> DayPart -> m DayPart
gmapMp :: (forall d. Data d => d -> m d) -> DayPart -> m DayPart
$cgmapMp :: forall (m :: * -> *).
MonadPlus m =>
(forall d. Data d => d -> m d) -> DayPart -> m DayPart
gmapM :: (forall d. Data d => d -> m d) -> DayPart -> m DayPart
$cgmapM :: forall (m :: * -> *).
Monad m =>
(forall d. Data d => d -> m d) -> DayPart -> m DayPart
gmapQi :: Int -> (forall d. Data d => d -> u) -> DayPart -> u
$cgmapQi :: forall u. Int -> (forall d. Data d => d -> u) -> DayPart -> u
gmapQ :: (forall d. Data d => d -> u) -> DayPart -> [u]
$cgmapQ :: forall u. (forall d. Data d => d -> u) -> DayPart -> [u]
gmapQr :: (r' -> r -> r)
-> r -> (forall d. Data d => d -> r') -> DayPart -> r
$cgmapQr :: forall r r'.
(r' -> r -> r)
-> r -> (forall d. Data d => d -> r') -> DayPart -> r
gmapQl :: (r -> r' -> r)
-> r -> (forall d. Data d => d -> r') -> DayPart -> r
$cgmapQl :: forall r r'.
(r -> r' -> r)
-> r -> (forall d. Data d => d -> r') -> DayPart -> r
gmapT :: (forall b. Data b => b -> b) -> DayPart -> DayPart
$cgmapT :: (forall b. Data b => b -> b) -> DayPart -> DayPart
dataCast2 :: (forall d e. (Data d, Data e) => c (t d e)) -> Maybe (c DayPart)
$cdataCast2 :: forall (t :: * -> * -> *) (c :: * -> *).
Typeable t =>
(forall d e. (Data d, Data e) => c (t d e)) -> Maybe (c DayPart)
dataCast1 :: (forall d. Data d => c (t d)) -> Maybe (c DayPart)
$cdataCast1 :: forall (t :: * -> *) (c :: * -> *).
Typeable t =>
(forall d. Data d => c (t d)) -> Maybe (c DayPart)
dataTypeOf :: DayPart -> DataType
$cdataTypeOf :: DayPart -> DataType
toConstr :: DayPart -> Constr
$ctoConstr :: DayPart -> Constr
gunfold :: (forall b r. Data b => c (b -> r) -> c r)
-> (forall r. r -> c r) -> Constr -> c DayPart
$cgunfold :: forall (c :: * -> *).
(forall b r. Data b => c (b -> r) -> c r)
-> (forall r. r -> c r) -> Constr -> c DayPart
gfoldl :: (forall d b. Data d => c (d -> b) -> d -> c b)
-> (forall g. g -> c g) -> DayPart -> c DayPart
$cgfoldl :: forall (c :: * -> *).
(forall d b. Data d => c (d -> b) -> d -> c b)
-> (forall g. g -> c g) -> DayPart -> c DayPart
$cp1Data :: Typeable DayPart
Data, Int -> DayPart
DayPart -> Int
DayPart -> [DayPart]
DayPart -> DayPart
DayPart -> DayPart -> [DayPart]
DayPart -> DayPart -> DayPart -> [DayPart]
(DayPart -> DayPart)
-> (DayPart -> DayPart)
-> (Int -> DayPart)
-> (DayPart -> Int)
-> (DayPart -> [DayPart])
-> (DayPart -> DayPart -> [DayPart])
-> (DayPart -> DayPart -> [DayPart])
-> (DayPart -> DayPart -> DayPart -> [DayPart])
-> Enum DayPart
forall a.
(a -> a)
-> (a -> a)
-> (Int -> a)
-> (a -> Int)
-> (a -> [a])
-> (a -> a -> [a])
-> (a -> a -> [a])
-> (a -> a -> a -> [a])
-> Enum a
enumFromThenTo :: DayPart -> DayPart -> DayPart -> [DayPart]
$cenumFromThenTo :: DayPart -> DayPart -> DayPart -> [DayPart]
enumFromTo :: DayPart -> DayPart -> [DayPart]
$cenumFromTo :: DayPart -> DayPart -> [DayPart]
enumFromThen :: DayPart -> DayPart -> [DayPart]
$cenumFromThen :: DayPart -> DayPart -> [DayPart]
enumFrom :: DayPart -> [DayPart]
$cenumFrom :: DayPart -> [DayPart]
fromEnum :: DayPart -> Int
$cfromEnum :: DayPart -> Int
toEnum :: Int -> DayPart
$ctoEnum :: Int -> DayPart
pred :: DayPart -> DayPart
$cpred :: DayPart -> DayPart
succ :: DayPart -> DayPart
$csucc :: DayPart -> DayPart
Enum, DayPart -> DayPart -> Bool
(DayPart -> DayPart -> Bool)
-> (DayPart -> DayPart -> Bool) -> Eq DayPart
forall a. (a -> a -> Bool) -> (a -> a -> Bool) -> Eq a
/= :: DayPart -> DayPart -> Bool
$c/= :: DayPart -> DayPart -> Bool
== :: DayPart -> DayPart -> Bool
$c== :: DayPart -> DayPart -> Bool
Eq, (forall x. DayPart -> Rep DayPart x)
-> (forall x. Rep DayPart x -> DayPart) -> Generic DayPart
forall x. Rep DayPart x -> DayPart
forall x. DayPart -> Rep DayPart x
forall a.
(forall x. a -> Rep a x) -> (forall x. Rep a x -> a) -> Generic a
$cto :: forall x. Rep DayPart x -> DayPart
$cfrom :: forall x. DayPart -> Rep DayPart x
Generic, Eq DayPart
Eq DayPart
-> (DayPart -> DayPart -> Ordering)
-> (DayPart -> DayPart -> Bool)
-> (DayPart -> DayPart -> Bool)
-> (DayPart -> DayPart -> Bool)
-> (DayPart -> DayPart -> Bool)
-> (DayPart -> DayPart -> DayPart)
-> (DayPart -> DayPart -> DayPart)
-> Ord DayPart
DayPart -> DayPart -> Bool
DayPart -> DayPart -> Ordering
DayPart -> DayPart -> DayPart
forall a.
Eq a
-> (a -> a -> Ordering)
-> (a -> a -> Bool)
-> (a -> a -> Bool)
-> (a -> a -> Bool)
-> (a -> a -> Bool)
-> (a -> a -> a)
-> (a -> a -> a)
-> Ord a
min :: DayPart -> DayPart -> DayPart
$cmin :: DayPart -> DayPart -> DayPart
max :: DayPart -> DayPart -> DayPart
$cmax :: DayPart -> DayPart -> DayPart
>= :: DayPart -> DayPart -> Bool
$c>= :: DayPart -> DayPart -> Bool
> :: DayPart -> DayPart -> Bool
$c> :: DayPart -> DayPart -> Bool
<= :: DayPart -> DayPart -> Bool
$c<= :: DayPart -> DayPart -> Bool
< :: DayPart -> DayPart -> Bool
$c< :: DayPart -> DayPart -> Bool
compare :: DayPart -> DayPart -> Ordering
$ccompare :: DayPart -> DayPart -> Ordering
$cp1Ord :: Eq DayPart
Ord, ReadPrec [DayPart]
ReadPrec DayPart
Int -> ReadS DayPart
ReadS [DayPart]
(Int -> ReadS DayPart)
-> ReadS [DayPart]
-> ReadPrec DayPart
-> ReadPrec [DayPart]
-> Read DayPart
forall a.
(Int -> ReadS a)
-> ReadS [a] -> ReadPrec a -> ReadPrec [a] -> Read a
readListPrec :: ReadPrec [DayPart]
$creadListPrec :: ReadPrec [DayPart]
readPrec :: ReadPrec DayPart
$creadPrec :: ReadPrec DayPart
readList :: ReadS [DayPart]
$creadList :: ReadS [DayPart]
readsPrec :: Int -> ReadS DayPart
$creadsPrec :: Int -> ReadS DayPart
Read, Int -> DayPart -> ShowS
[DayPart] -> ShowS
DayPart -> String
(Int -> DayPart -> ShowS)
-> (DayPart -> String) -> ([DayPart] -> ShowS) -> Show DayPart
forall a.
(Int -> a -> ShowS) -> (a -> String) -> ([a] -> ShowS) -> Show a
showList :: [DayPart] -> ShowS
$cshowList :: [DayPart] -> ShowS
show :: DayPart -> String
$cshow :: DayPart -> String
showsPrec :: Int -> DayPart -> ShowS
$cshowsPrec :: Int -> DayPart -> ShowS
Show)

instance Arbitrary DayPart where
  arbitrary :: Gen DayPart
arbitrary = Gen DayPart
forall a. (Bounded a, Enum a) => Gen a
arbitraryBoundedEnum

instance NFData DayPart

-- | A data type that describes the part of the day, and the number of hours on
-- a 12-hour clock.
data DaySegment
  = DaySegment {
        DaySegment -> DayPart
dayPart :: DayPart  -- ^ The part of the day.
      , DaySegment -> Int
dayHour :: Int  -- ^ The number of hours, between @1@ and @12@ (both inclusive).
      }
  deriving (Typeable DaySegment
DataType
Constr
Typeable DaySegment
-> (forall (c :: * -> *).
    (forall d b. Data d => c (d -> b) -> d -> c b)
    -> (forall g. g -> c g) -> DaySegment -> c DaySegment)
-> (forall (c :: * -> *).
    (forall b r. Data b => c (b -> r) -> c r)
    -> (forall r. r -> c r) -> Constr -> c DaySegment)
-> (DaySegment -> Constr)
-> (DaySegment -> DataType)
-> (forall (t :: * -> *) (c :: * -> *).
    Typeable t =>
    (forall d. Data d => c (t d)) -> Maybe (c DaySegment))
-> (forall (t :: * -> * -> *) (c :: * -> *).
    Typeable t =>
    (forall d e. (Data d, Data e) => c (t d e))
    -> Maybe (c DaySegment))
-> ((forall b. Data b => b -> b) -> DaySegment -> DaySegment)
-> (forall r r'.
    (r -> r' -> r)
    -> r -> (forall d. Data d => d -> r') -> DaySegment -> r)
-> (forall r r'.
    (r' -> r -> r)
    -> r -> (forall d. Data d => d -> r') -> DaySegment -> r)
-> (forall u. (forall d. Data d => d -> u) -> DaySegment -> [u])
-> (forall u.
    Int -> (forall d. Data d => d -> u) -> DaySegment -> u)
-> (forall (m :: * -> *).
    Monad m =>
    (forall d. Data d => d -> m d) -> DaySegment -> m DaySegment)
-> (forall (m :: * -> *).
    MonadPlus m =>
    (forall d. Data d => d -> m d) -> DaySegment -> m DaySegment)
-> (forall (m :: * -> *).
    MonadPlus m =>
    (forall d. Data d => d -> m d) -> DaySegment -> m DaySegment)
-> Data DaySegment
DaySegment -> DataType
DaySegment -> Constr
(forall b. Data b => b -> b) -> DaySegment -> DaySegment
(forall d b. Data d => c (d -> b) -> d -> c b)
-> (forall g. g -> c g) -> DaySegment -> c DaySegment
(forall b r. Data b => c (b -> r) -> c r)
-> (forall r. r -> c r) -> Constr -> c DaySegment
forall a.
Typeable a
-> (forall (c :: * -> *).
    (forall d b. Data d => c (d -> b) -> d -> c b)
    -> (forall g. g -> c g) -> a -> c a)
-> (forall (c :: * -> *).
    (forall b r. Data b => c (b -> r) -> c r)
    -> (forall r. r -> c r) -> Constr -> c a)
-> (a -> Constr)
-> (a -> DataType)
-> (forall (t :: * -> *) (c :: * -> *).
    Typeable t =>
    (forall d. Data d => c (t d)) -> Maybe (c a))
-> (forall (t :: * -> * -> *) (c :: * -> *).
    Typeable t =>
    (forall d e. (Data d, Data e) => c (t d e)) -> Maybe (c a))
-> ((forall b. Data b => b -> b) -> a -> a)
-> (forall r r'.
    (r -> r' -> r) -> r -> (forall d. Data d => d -> r') -> a -> r)
-> (forall r r'.
    (r' -> r -> r) -> r -> (forall d. Data d => d -> r') -> a -> r)
-> (forall u. (forall d. Data d => d -> u) -> a -> [u])
-> (forall u. Int -> (forall d. Data d => d -> u) -> a -> u)
-> (forall (m :: * -> *).
    Monad m =>
    (forall d. Data d => d -> m d) -> a -> m a)
-> (forall (m :: * -> *).
    MonadPlus m =>
    (forall d. Data d => d -> m d) -> a -> m a)
-> (forall (m :: * -> *).
    MonadPlus m =>
    (forall d. Data d => d -> m d) -> a -> m a)
-> Data a
forall u. Int -> (forall d. Data d => d -> u) -> DaySegment -> u
forall u. (forall d. Data d => d -> u) -> DaySegment -> [u]
forall r r'.
(r -> r' -> r)
-> r -> (forall d. Data d => d -> r') -> DaySegment -> r
forall r r'.
(r' -> r -> r)
-> r -> (forall d. Data d => d -> r') -> DaySegment -> r
forall (m :: * -> *).
Monad m =>
(forall d. Data d => d -> m d) -> DaySegment -> m DaySegment
forall (m :: * -> *).
MonadPlus m =>
(forall d. Data d => d -> m d) -> DaySegment -> m DaySegment
forall (c :: * -> *).
(forall b r. Data b => c (b -> r) -> c r)
-> (forall r. r -> c r) -> Constr -> c DaySegment
forall (c :: * -> *).
(forall d b. Data d => c (d -> b) -> d -> c b)
-> (forall g. g -> c g) -> DaySegment -> c DaySegment
forall (t :: * -> *) (c :: * -> *).
Typeable t =>
(forall d. Data d => c (t d)) -> Maybe (c DaySegment)
forall (t :: * -> * -> *) (c :: * -> *).
Typeable t =>
(forall d e. (Data d, Data e) => c (t d e)) -> Maybe (c DaySegment)
$cDaySegment :: Constr
$tDaySegment :: DataType
gmapMo :: (forall d. Data d => d -> m d) -> DaySegment -> m DaySegment
$cgmapMo :: forall (m :: * -> *).
MonadPlus m =>
(forall d. Data d => d -> m d) -> DaySegment -> m DaySegment
gmapMp :: (forall d. Data d => d -> m d) -> DaySegment -> m DaySegment
$cgmapMp :: forall (m :: * -> *).
MonadPlus m =>
(forall d. Data d => d -> m d) -> DaySegment -> m DaySegment
gmapM :: (forall d. Data d => d -> m d) -> DaySegment -> m DaySegment
$cgmapM :: forall (m :: * -> *).
Monad m =>
(forall d. Data d => d -> m d) -> DaySegment -> m DaySegment
gmapQi :: Int -> (forall d. Data d => d -> u) -> DaySegment -> u
$cgmapQi :: forall u. Int -> (forall d. Data d => d -> u) -> DaySegment -> u
gmapQ :: (forall d. Data d => d -> u) -> DaySegment -> [u]
$cgmapQ :: forall u. (forall d. Data d => d -> u) -> DaySegment -> [u]
gmapQr :: (r' -> r -> r)
-> r -> (forall d. Data d => d -> r') -> DaySegment -> r
$cgmapQr :: forall r r'.
(r' -> r -> r)
-> r -> (forall d. Data d => d -> r') -> DaySegment -> r
gmapQl :: (r -> r' -> r)
-> r -> (forall d. Data d => d -> r') -> DaySegment -> r
$cgmapQl :: forall r r'.
(r -> r' -> r)
-> r -> (forall d. Data d => d -> r') -> DaySegment -> r
gmapT :: (forall b. Data b => b -> b) -> DaySegment -> DaySegment
$cgmapT :: (forall b. Data b => b -> b) -> DaySegment -> DaySegment
dataCast2 :: (forall d e. (Data d, Data e) => c (t d e)) -> Maybe (c DaySegment)
$cdataCast2 :: forall (t :: * -> * -> *) (c :: * -> *).
Typeable t =>
(forall d e. (Data d, Data e) => c (t d e)) -> Maybe (c DaySegment)
dataCast1 :: (forall d. Data d => c (t d)) -> Maybe (c DaySegment)
$cdataCast1 :: forall (t :: * -> *) (c :: * -> *).
Typeable t =>
(forall d. Data d => c (t d)) -> Maybe (c DaySegment)
dataTypeOf :: DaySegment -> DataType
$cdataTypeOf :: DaySegment -> DataType
toConstr :: DaySegment -> Constr
$ctoConstr :: DaySegment -> Constr
gunfold :: (forall b r. Data b => c (b -> r) -> c r)
-> (forall r. r -> c r) -> Constr -> c DaySegment
$cgunfold :: forall (c :: * -> *).
(forall b r. Data b => c (b -> r) -> c r)
-> (forall r. r -> c r) -> Constr -> c DaySegment
gfoldl :: (forall d b. Data d => c (d -> b) -> d -> c b)
-> (forall g. g -> c g) -> DaySegment -> c DaySegment
$cgfoldl :: forall (c :: * -> *).
(forall d b. Data d => c (d -> b) -> d -> c b)
-> (forall g. g -> c g) -> DaySegment -> c DaySegment
$cp1Data :: Typeable DaySegment
Data, DaySegment -> DaySegment -> Bool
(DaySegment -> DaySegment -> Bool)
-> (DaySegment -> DaySegment -> Bool) -> Eq DaySegment
forall a. (a -> a -> Bool) -> (a -> a -> Bool) -> Eq a
/= :: DaySegment -> DaySegment -> Bool
$c/= :: DaySegment -> DaySegment -> Bool
== :: DaySegment -> DaySegment -> Bool
$c== :: DaySegment -> DaySegment -> Bool
Eq, (forall x. DaySegment -> Rep DaySegment x)
-> (forall x. Rep DaySegment x -> DaySegment) -> Generic DaySegment
forall x. Rep DaySegment x -> DaySegment
forall x. DaySegment -> Rep DaySegment x
forall a.
(forall x. a -> Rep a x) -> (forall x. Rep a x -> a) -> Generic a
$cto :: forall x. Rep DaySegment x -> DaySegment
$cfrom :: forall x. DaySegment -> Rep DaySegment x
Generic, Eq DaySegment
Eq DaySegment
-> (DaySegment -> DaySegment -> Ordering)
-> (DaySegment -> DaySegment -> Bool)
-> (DaySegment -> DaySegment -> Bool)
-> (DaySegment -> DaySegment -> Bool)
-> (DaySegment -> DaySegment -> Bool)
-> (DaySegment -> DaySegment -> DaySegment)
-> (DaySegment -> DaySegment -> DaySegment)
-> Ord DaySegment
DaySegment -> DaySegment -> Bool
DaySegment -> DaySegment -> Ordering
DaySegment -> DaySegment -> DaySegment
forall a.
Eq a
-> (a -> a -> Ordering)
-> (a -> a -> Bool)
-> (a -> a -> Bool)
-> (a -> a -> Bool)
-> (a -> a -> Bool)
-> (a -> a -> a)
-> (a -> a -> a)
-> Ord a
min :: DaySegment -> DaySegment -> DaySegment
$cmin :: DaySegment -> DaySegment -> DaySegment
max :: DaySegment -> DaySegment -> DaySegment
$cmax :: DaySegment -> DaySegment -> DaySegment
>= :: DaySegment -> DaySegment -> Bool
$c>= :: DaySegment -> DaySegment -> Bool
> :: DaySegment -> DaySegment -> Bool
$c> :: DaySegment -> DaySegment -> Bool
<= :: DaySegment -> DaySegment -> Bool
$c<= :: DaySegment -> DaySegment -> Bool
< :: DaySegment -> DaySegment -> Bool
$c< :: DaySegment -> DaySegment -> Bool
compare :: DaySegment -> DaySegment -> Ordering
$ccompare :: DaySegment -> DaySegment -> Ordering
$cp1Ord :: Eq DaySegment
Ord, ReadPrec [DaySegment]
ReadPrec DaySegment
Int -> ReadS DaySegment
ReadS [DaySegment]
(Int -> ReadS DaySegment)
-> ReadS [DaySegment]
-> ReadPrec DaySegment
-> ReadPrec [DaySegment]
-> Read DaySegment
forall a.
(Int -> ReadS a)
-> ReadS [a] -> ReadPrec a -> ReadPrec [a] -> Read a
readListPrec :: ReadPrec [DaySegment]
$creadListPrec :: ReadPrec [DaySegment]
readPrec :: ReadPrec DaySegment
$creadPrec :: ReadPrec DaySegment
readList :: ReadS [DaySegment]
$creadList :: ReadS [DaySegment]
readsPrec :: Int -> ReadS DaySegment
$creadsPrec :: Int -> ReadS DaySegment
Read, Int -> DaySegment -> ShowS
[DaySegment] -> ShowS
DaySegment -> String
(Int -> DaySegment -> ShowS)
-> (DaySegment -> String)
-> ([DaySegment] -> ShowS)
-> Show DaySegment
forall a.
(Int -> a -> ShowS) -> (a -> String) -> ([a] -> ShowS) -> Show a
showList :: [DaySegment] -> ShowS
$cshowList :: [DaySegment] -> ShowS
show :: DaySegment -> String
$cshow :: DaySegment -> String
showsPrec :: Int -> DaySegment -> ShowS
$cshowsPrec :: Int -> DaySegment -> ShowS
Show)

instance Arbitrary DaySegment where
  arbitrary :: Gen DaySegment
arbitrary = Int -> DaySegment
toDaySegment (Int -> DaySegment) -> Gen Int -> Gen DaySegment
forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
<$> (Int, Int) -> Gen Int
forall a. Random a => (a, a) -> Gen a
choose (Int
0, Int
23)

instance NFData DaySegment

-- | Convert the given number of minutes to the corresponding 'ClockSegment'.
toClockSegment
  :: Int  -- ^ The number of minutes.
  -> ClockSegment  -- ^ The corresponding 'ClockSegment'.
toClockSegment :: Int -> ClockSegment
toClockSegment Int
0 = ClockSegment
OClock
toClockSegment Int
15 = ClockSegment
QuarterPast
toClockSegment Int
30 = ClockSegment
Half
toClockSegment Int
45 = ClockSegment
QuarterTo
toClockSegment Int
n
    | Int
n Int -> Int -> Bool
forall a. Ord a => a -> a -> Bool
<= Int
15 = Int -> ClockSegment
Past Int
n
    | Int
n Int -> Int -> Bool
forall a. Ord a => a -> a -> Bool
<= Int
30 = Int -> ClockSegment
ToHalf (Int
30Int -> Int -> Int
forall a. Num a => a -> a -> a
-Int
n)
    | Int
n Int -> Int -> Bool
forall a. Ord a => a -> a -> Bool
<= Int
45 = Int -> ClockSegment
PastHalf (Int
nInt -> Int -> Int
forall a. Num a => a -> a -> a
-Int
30)
    | Bool
otherwise = Int -> ClockSegment
To (Int
60Int -> Int -> Int
forall a. Num a => a -> a -> a
-Int
n)

-- | Convert the given number of hours to the corresponding 'DayPart'.
toDayPart
  :: Int  -- ^ The given number of hours.
  -> DayPart  -- ^ The corresponding 'DayPart'.
toDayPart :: Int -> DayPart
toDayPart Int
n
    | Int
n Int -> Int -> Bool
forall a. Ord a => a -> a -> Bool
<= Int
5 = DayPart
Night
    | Int
n Int -> Int -> Bool
forall a. Ord a => a -> a -> Bool
<= Int
11 = DayPart
Morning
    | Int
n Int -> Int -> Bool
forall a. Ord a => a -> a -> Bool
<= Int
17 = DayPart
Afternoon
    | Bool
otherwise = DayPart
Evening

-- | Convert the given number of hours to the corresponding 'DaySegment'.
toDaySegment
  :: Int  -- ^ The given number of hours.
  -> DaySegment  -- ^ The corresponding 'DaySegment'.
toDaySegment :: Int -> DaySegment
toDaySegment Int
n = DayPart -> Int -> DaySegment
DaySegment (Int -> DayPart
toDayPart Int
n) (Int -> Int
hourCorrection Int
n)

-- | Correct the hour to a 12 number segment.
-- The input can be any Int number, whereas the
-- result will be in the @1 .. 12@ range.
hourCorrection
  :: Int  -- ^ The value for the number of hours.
  -> Int  -- ^ The hours in the @1 .. 12@ range.
hourCorrection :: Int -> Int
hourCorrection Int
h = ((Int
h Int -> Int -> Int
forall a. Num a => a -> a -> a
- Int
1) Int -> Int -> Int
forall a. Integral a => a -> a -> a
`mod` Int
12) Int -> Int -> Int
forall a. Num a => a -> a -> a
+ Int
1

instance Default NumberType where
    def :: NumberType
def = NumberType
Cardinal

-- | A type class used for num to word algorithms. It maps an 'Integral' type
-- @i@ to 'Text'.
class NumToWord a where
    -- | Convert the given number to a 'Text' object that is the given number in
    -- words in /cardinal/ form.
    toCardinal :: Integral i
      => a  -- ^ The conversion algorithm that transforms the number into words.
      -> i  -- ^ The number to transform into a /cardinal/ form.
      -> Text  -- ^ The number in words in a /cardinal/ form.
    toCardinal = NumberType -> a -> i -> Text
forall a i.
(NumToWord a, Integral i) =>
NumberType -> a -> i -> Text
toWords NumberType
Cardinal

    -- | Convert the given number to a 'Text' object that is the given number in
    -- words in /cardinal/ form.
    toOrdinal :: Integral i
      => a  -- ^ The conversion algorithm that transforms the number into words.
      -> i  -- ^ The number to transform into a /ordinal/ form.
      -> Text  -- ^ The number in words in a /ordinal/ form.
    toOrdinal = NumberType -> a -> i -> Text
forall a i.
(NumToWord a, Integral i) =>
NumberType -> a -> i -> Text
toWords NumberType
Ordinal

    -- | Convert the given number to a 'Text' object that is the given number
    -- in words in /short cardinal/ form.
    toShortOrdinal :: Integral i
      => a  -- ^ The conversion algorithm that transforms the number into words.
      -> i  -- ^ The number to transform into a /ordinal/ form.
      -> Text  -- ^ The number in words in a /ordinal/ form.
    toShortOrdinal = NumberType -> a -> i -> Text
forall a i.
(NumToWord a, Integral i) =>
NumberType -> a -> i -> Text
toWords NumberType
Ordinal

    -- | Convert the given number to a 'Text' object that is the given number in
    -- words in the given 'NumberType'.
    toWords :: Integral i
      => NumberType  -- ^ The given format to convert the number to.
      -> a  -- ^ The conversion algorithm that transforms the number into words.
      -> i  -- ^ The number to transform into the given form.
      -> Text  -- ^ The number in words in the given form.
    toWords NumberType
Cardinal = a -> i -> Text
forall a i. (NumToWord a, Integral i) => a -> i -> Text
toCardinal
    toWords NumberType
Ordinal = a -> i -> Text
forall a i. (NumToWord a, Integral i) => a -> i -> Text
toOrdinal
    toWords NumberType
ShortOrdinal = a -> i -> Text
forall a i. (NumToWord a, Integral i) => a -> i -> Text
toShortOrdinal

    -- | Convert the given time of the day to text describing that time.
    toTimeText
      :: a  -- ^ The conversion algorithm to transform numbers into words.
      -> TimeOfDay  -- ^ The time of the day to convert to words.
      -> Text  -- ^ The time as /text/.
    toTimeText a
gen (TimeOfDay Int
h Int
m Pico
_) = a -> Int -> Int -> Text
forall a. NumToWord a => a -> Int -> Int -> Text
toTimeText' a
gen Int
h Int
m

    -- | Convert the given hours and minutes to text that describes the time.
    toTimeText'
      :: a  -- ^ The conversion algorithm to transform numbers into words.
      -> Int  -- ^ The number of hours, between 0 and 23 (both inclusive)
      -> Int  -- ^ The number of minutes, beween 0 and 59 (both inclusive)
      -> Text  -- ^ The time as /text/.
    toTimeText' a
gen Int
h Int
m = a -> TimeOfDay -> Text
forall a. NumToWord a => a -> TimeOfDay -> Text
toTimeText a
gen (Int -> Int -> Pico -> TimeOfDay
TimeOfDay Int
h Int
m Pico
0)
    {-# MINIMAL ((toCardinal, toOrdinal, toShortOrdinal) | toWords), (toTimeText | toTimeText') #-}

-- | Convert the current time in the given 'TimeZone' to the time in words with the given 'NumToWord'
-- algorithm.
currentTimeText :: NumToWord a
  => TimeZone -- ^ The given 'TimeZone'.
  -> a  -- ^ The 'NumToWord' algorithm that converts time to words.
  -> IO Text  -- ^ An 'IO' that will generate a 'Text' object that describes the current time in words.
currentTimeText :: TimeZone -> a -> IO Text
currentTimeText TimeZone
tz a
alg = a -> TimeOfDay -> Text
forall a. NumToWord a => a -> TimeOfDay -> Text
toTimeText a
alg (TimeOfDay -> Text) -> (UTCTime -> TimeOfDay) -> UTCTime -> Text
forall b c a. (b -> c) -> (a -> b) -> a -> c
. (Integer, TimeOfDay) -> TimeOfDay
forall a b. (a, b) -> b
snd ((Integer, TimeOfDay) -> TimeOfDay)
-> (UTCTime -> (Integer, TimeOfDay)) -> UTCTime -> TimeOfDay
forall b c a. (b -> c) -> (a -> b) -> a -> c
. TimeZone -> TimeOfDay -> (Integer, TimeOfDay)
utcToLocalTimeOfDay TimeZone
tz (TimeOfDay -> (Integer, TimeOfDay))
-> (UTCTime -> TimeOfDay) -> UTCTime -> (Integer, TimeOfDay)
forall b c a. (b -> c) -> (a -> b) -> a -> c
. DiffTime -> TimeOfDay
timeToTimeOfDay (DiffTime -> TimeOfDay)
-> (UTCTime -> DiffTime) -> UTCTime -> TimeOfDay
forall b c a. (b -> c) -> (a -> b) -> a -> c
. UTCTime -> DiffTime
utctDayTime (UTCTime -> Text) -> IO UTCTime -> IO Text
forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
<$> IO UTCTime
getCurrentTime

-- | Convert the current time to the time in words with the given 'NumToWord'
-- algorithm as UTC time.
currentTimeText' :: NumToWord a
  => a  -- ^ The 'NumToWord' algorithm that converts time to words.
  -> IO Text  -- ^ An 'IO' that will generate a 'Text' object that describes the current time in words.
currentTimeText' :: a -> IO Text
currentTimeText' a
alg = a -> TimeOfDay -> Text
forall a. NumToWord a => a -> TimeOfDay -> Text
toTimeText a
alg (TimeOfDay -> Text) -> (UTCTime -> TimeOfDay) -> UTCTime -> Text
forall b c a. (b -> c) -> (a -> b) -> a -> c
. DiffTime -> TimeOfDay
timeToTimeOfDay (DiffTime -> TimeOfDay)
-> (UTCTime -> DiffTime) -> UTCTime -> TimeOfDay
forall b c a. (b -> c) -> (a -> b) -> a -> c
. UTCTime -> DiffTime
utctDayTime (UTCTime -> Text) -> IO UTCTime -> IO Text
forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
<$> IO UTCTime
getCurrentTime

-- | A type class used to split a value, based on the name of a number in a
-- specific language. The value that is used to split, is often, depending on
-- the language, the largest value smaller than the given number.
class ValueSplit a where
    -- | A function that takes an 'Integral' value, and based on the object
    -- splits it with a value and the name of the number in a specific language.
    valueSplit :: a -> FreeValueSplitter