{-# LANGUAGE UndecidableInstances #-}

module Blucontrol.Gamma.Linear (
  GammaLinearT
, runGammaLinearT
, Time (..)
, Hour
, Minute
, (==>)
, N.NonEmpty (..) -- TODO: keep here?
, calculateRGB -- TODO: export for testing
, weightedAverageTrichromaticity -- TODO: export for testing
) where

import Control.DeepSeq
import Control.Monad.Base
import Control.Monad.Except
import Control.Monad.Reader
import Control.Monad.Trans.Control
import qualified Data.Finite as F
import qualified Data.List.NonEmpty as N
import qualified Data.Map as M
import Data.Maybe (fromJust)
import Data.Time
import GHC.Generics

import Blucontrol.Gamma
import Blucontrol.RGB
import Blucontrol.RGB.Temperature

newtype GammaLinearT c m a = GammaLinearT { GammaLinearT c m a -> ReaderT (Map TimeOfDay c) m a
unGammaLinearT :: ReaderT (M.Map TimeOfDay c) m a }
  deriving (Functor (GammaLinearT c m)
a -> GammaLinearT c m a
Functor (GammaLinearT c m)
-> (forall a. a -> GammaLinearT c m a)
-> (forall a b.
    GammaLinearT c m (a -> b)
    -> GammaLinearT c m a -> GammaLinearT c m b)
-> (forall a b c.
    (a -> b -> c)
    -> GammaLinearT c m a -> GammaLinearT c m b -> GammaLinearT c m c)
-> (forall a b.
    GammaLinearT c m a -> GammaLinearT c m b -> GammaLinearT c m b)
-> (forall a b.
    GammaLinearT c m a -> GammaLinearT c m b -> GammaLinearT c m a)
-> Applicative (GammaLinearT c m)
GammaLinearT c m a -> GammaLinearT c m b -> GammaLinearT c m b
GammaLinearT c m a -> GammaLinearT c m b -> GammaLinearT c m a
GammaLinearT c m (a -> b)
-> GammaLinearT c m a -> GammaLinearT c m b
(a -> b -> c)
-> GammaLinearT c m a -> GammaLinearT c m b -> GammaLinearT c m c
forall a. a -> GammaLinearT c m a
forall a b.
GammaLinearT c m a -> GammaLinearT c m b -> GammaLinearT c m a
forall a b.
GammaLinearT c m a -> GammaLinearT c m b -> GammaLinearT c m b
forall a b.
GammaLinearT c m (a -> b)
-> GammaLinearT c m a -> GammaLinearT c m b
forall a b c.
(a -> b -> c)
-> GammaLinearT c m a -> GammaLinearT c m b -> GammaLinearT c m c
forall c (m :: * -> *). Applicative m => Functor (GammaLinearT c m)
forall c (m :: * -> *) a. Applicative m => a -> GammaLinearT c m a
forall c (m :: * -> *) a b.
Applicative m =>
GammaLinearT c m a -> GammaLinearT c m b -> GammaLinearT c m a
forall c (m :: * -> *) a b.
Applicative m =>
GammaLinearT c m a -> GammaLinearT c m b -> GammaLinearT c m b
forall c (m :: * -> *) a b.
Applicative m =>
GammaLinearT c m (a -> b)
-> GammaLinearT c m a -> GammaLinearT c m b
forall c (m :: * -> *) a b c.
Applicative m =>
(a -> b -> c)
-> GammaLinearT c m a -> GammaLinearT c m b -> GammaLinearT c m c
forall (f :: * -> *).
Functor f
-> (forall a. a -> f a)
-> (forall a b. f (a -> b) -> f a -> f b)
-> (forall a b c. (a -> b -> c) -> f a -> f b -> f c)
-> (forall a b. f a -> f b -> f b)
-> (forall a b. f a -> f b -> f a)
-> Applicative f
<* :: GammaLinearT c m a -> GammaLinearT c m b -> GammaLinearT c m a
$c<* :: forall c (m :: * -> *) a b.
Applicative m =>
GammaLinearT c m a -> GammaLinearT c m b -> GammaLinearT c m a
*> :: GammaLinearT c m a -> GammaLinearT c m b -> GammaLinearT c m b
$c*> :: forall c (m :: * -> *) a b.
Applicative m =>
GammaLinearT c m a -> GammaLinearT c m b -> GammaLinearT c m b
liftA2 :: (a -> b -> c)
-> GammaLinearT c m a -> GammaLinearT c m b -> GammaLinearT c m c
$cliftA2 :: forall c (m :: * -> *) a b c.
Applicative m =>
(a -> b -> c)
-> GammaLinearT c m a -> GammaLinearT c m b -> GammaLinearT c m c
<*> :: GammaLinearT c m (a -> b)
-> GammaLinearT c m a -> GammaLinearT c m b
$c<*> :: forall c (m :: * -> *) a b.
Applicative m =>
GammaLinearT c m (a -> b)
-> GammaLinearT c m a -> GammaLinearT c m b
pure :: a -> GammaLinearT c m a
$cpure :: forall c (m :: * -> *) a. Applicative m => a -> GammaLinearT c m a
$cp1Applicative :: forall c (m :: * -> *). Applicative m => Functor (GammaLinearT c m)
Applicative, a -> GammaLinearT c m b -> GammaLinearT c m a
(a -> b) -> GammaLinearT c m a -> GammaLinearT c m b
(forall a b. (a -> b) -> GammaLinearT c m a -> GammaLinearT c m b)
-> (forall a b. a -> GammaLinearT c m b -> GammaLinearT c m a)
-> Functor (GammaLinearT c m)
forall a b. a -> GammaLinearT c m b -> GammaLinearT c m a
forall a b. (a -> b) -> GammaLinearT c m a -> GammaLinearT c m b
forall c (m :: * -> *) a b.
Functor m =>
a -> GammaLinearT c m b -> GammaLinearT c m a
forall c (m :: * -> *) a b.
Functor m =>
(a -> b) -> GammaLinearT c m a -> GammaLinearT c m b
forall (f :: * -> *).
(forall a b. (a -> b) -> f a -> f b)
-> (forall a b. a -> f b -> f a) -> Functor f
<$ :: a -> GammaLinearT c m b -> GammaLinearT c m a
$c<$ :: forall c (m :: * -> *) a b.
Functor m =>
a -> GammaLinearT c m b -> GammaLinearT c m a
fmap :: (a -> b) -> GammaLinearT c m a -> GammaLinearT c m b
$cfmap :: forall c (m :: * -> *) a b.
Functor m =>
(a -> b) -> GammaLinearT c m a -> GammaLinearT c m b
Functor, Applicative (GammaLinearT c m)
a -> GammaLinearT c m a
Applicative (GammaLinearT c m)
-> (forall a b.
    GammaLinearT c m a
    -> (a -> GammaLinearT c m b) -> GammaLinearT c m b)
-> (forall a b.
    GammaLinearT c m a -> GammaLinearT c m b -> GammaLinearT c m b)
-> (forall a. a -> GammaLinearT c m a)
-> Monad (GammaLinearT c m)
GammaLinearT c m a
-> (a -> GammaLinearT c m b) -> GammaLinearT c m b
GammaLinearT c m a -> GammaLinearT c m b -> GammaLinearT c m b
forall a. a -> GammaLinearT c m a
forall a b.
GammaLinearT c m a -> GammaLinearT c m b -> GammaLinearT c m b
forall a b.
GammaLinearT c m a
-> (a -> GammaLinearT c m b) -> GammaLinearT c m b
forall c (m :: * -> *). Monad m => Applicative (GammaLinearT c m)
forall c (m :: * -> *) a. Monad m => a -> GammaLinearT c m a
forall c (m :: * -> *) a b.
Monad m =>
GammaLinearT c m a -> GammaLinearT c m b -> GammaLinearT c m b
forall c (m :: * -> *) a b.
Monad m =>
GammaLinearT c m a
-> (a -> GammaLinearT c m b) -> GammaLinearT c m b
forall (m :: * -> *).
Applicative m
-> (forall a b. m a -> (a -> m b) -> m b)
-> (forall a b. m a -> m b -> m b)
-> (forall a. a -> m a)
-> Monad m
return :: a -> GammaLinearT c m a
$creturn :: forall c (m :: * -> *) a. Monad m => a -> GammaLinearT c m a
>> :: GammaLinearT c m a -> GammaLinearT c m b -> GammaLinearT c m b
$c>> :: forall c (m :: * -> *) a b.
Monad m =>
GammaLinearT c m a -> GammaLinearT c m b -> GammaLinearT c m b
>>= :: GammaLinearT c m a
-> (a -> GammaLinearT c m b) -> GammaLinearT c m b
$c>>= :: forall c (m :: * -> *) a b.
Monad m =>
GammaLinearT c m a
-> (a -> GammaLinearT c m b) -> GammaLinearT c m b
$cp1Monad :: forall c (m :: * -> *). Monad m => Applicative (GammaLinearT c m)
Monad, MonadBase b, MonadBaseControl b, m a -> GammaLinearT c m a
(forall (m :: * -> *) a. Monad m => m a -> GammaLinearT c m a)
-> MonadTrans (GammaLinearT c)
forall c (m :: * -> *) a. Monad m => m a -> GammaLinearT c m a
forall (m :: * -> *) a. Monad m => m a -> GammaLinearT c m a
forall (t :: (* -> *) -> * -> *).
(forall (m :: * -> *) a. Monad m => m a -> t m a) -> MonadTrans t
lift :: m a -> GammaLinearT c m a
$clift :: forall c (m :: * -> *) a. Monad m => m a -> GammaLinearT c m a
MonadTrans, MonadTrans (GammaLinearT c)
m (StT (GammaLinearT c) a) -> GammaLinearT c m a
MonadTrans (GammaLinearT c)
-> (forall (m :: * -> *) a.
    Monad m =>
    (Run (GammaLinearT c) -> m a) -> GammaLinearT c m a)
-> (forall (m :: * -> *) a.
    Monad m =>
    m (StT (GammaLinearT c) a) -> GammaLinearT c m a)
-> MonadTransControl (GammaLinearT c)
(Run (GammaLinearT c) -> m a) -> GammaLinearT c m a
forall c. MonadTrans (GammaLinearT c)
forall c (m :: * -> *) a.
Monad m =>
m (StT (GammaLinearT c) a) -> GammaLinearT c m a
forall c (m :: * -> *) a.
Monad m =>
(Run (GammaLinearT c) -> m a) -> GammaLinearT c m a
forall (m :: * -> *) a.
Monad m =>
m (StT (GammaLinearT c) a) -> GammaLinearT c m a
forall (m :: * -> *) a.
Monad m =>
(Run (GammaLinearT c) -> m a) -> GammaLinearT c m a
forall (t :: (* -> *) -> * -> *).
MonadTrans t
-> (forall (m :: * -> *) a. Monad m => (Run t -> m a) -> t m a)
-> (forall (m :: * -> *) a. Monad m => m (StT t a) -> t m a)
-> MonadTransControl t
restoreT :: m (StT (GammaLinearT c) a) -> GammaLinearT c m a
$crestoreT :: forall c (m :: * -> *) a.
Monad m =>
m (StT (GammaLinearT c) a) -> GammaLinearT c m a
liftWith :: (Run (GammaLinearT c) -> m a) -> GammaLinearT c m a
$cliftWith :: forall c (m :: * -> *) a.
Monad m =>
(Run (GammaLinearT c) -> m a) -> GammaLinearT c m a
$cp1MonadTransControl :: forall c. MonadTrans (GammaLinearT c)
MonadTransControl)

instance MonadReader r m => MonadReader r (GammaLinearT c m) where
  ask :: GammaLinearT c m r
ask = m r -> GammaLinearT c m r
forall (t :: (* -> *) -> * -> *) (m :: * -> *) a.
(MonadTrans t, Monad m) =>
m a -> t m a
lift m r
forall r (m :: * -> *). MonadReader r m => m r
ask
  local :: (r -> r) -> GammaLinearT c m a -> GammaLinearT c m a
local r -> r
f GammaLinearT c m a
tma = (Run (GammaLinearT c) -> m a) -> GammaLinearT c m a
forall (t :: (* -> *) -> * -> *) (m :: * -> *) a.
(MonadTransControl t, Monad m) =>
(Run t -> m a) -> t m a
liftWith ((Run (GammaLinearT c) -> m a) -> GammaLinearT c m a)
-> (Run (GammaLinearT c) -> m a) -> GammaLinearT c m a
forall a b. (a -> b) -> a -> b
$ \ Run (GammaLinearT c)
run ->
    (r -> r) -> m a -> m a
forall r (m :: * -> *) a. MonadReader r m => (r -> r) -> m a -> m a
local r -> r
f (m a -> m a) -> m a -> m a
forall a b. (a -> b) -> a -> b
$ GammaLinearT c m a -> m (StT (GammaLinearT c) a)
Run (GammaLinearT c)
run GammaLinearT c m a
tma

instance MonadBase IO m => MonadGamma (GammaLinearT Trichromaticity m) where
  gamma :: GammaLinearT Trichromaticity m Trichromaticity
gamma = (Rational -> Trichromaticity -> Trichromaticity -> Trichromaticity)
-> LocalTime -> GammaLinearT Trichromaticity m Trichromaticity
forall (m :: * -> *) c.
Monad m =>
(Rational -> c -> c -> c) -> LocalTime -> GammaLinearT c m c
calculateRGB Rational -> Trichromaticity -> Trichromaticity -> Trichromaticity
weightedAverageTrichromaticity (LocalTime -> GammaLinearT Trichromaticity m Trichromaticity)
-> (ZonedTime -> LocalTime)
-> ZonedTime
-> GammaLinearT Trichromaticity m Trichromaticity
forall b c a. (b -> c) -> (a -> b) -> a -> c
. ZonedTime -> LocalTime
zonedTimeToLocalTime (ZonedTime -> GammaLinearT Trichromaticity m Trichromaticity)
-> GammaLinearT Trichromaticity m ZonedTime
-> GammaLinearT Trichromaticity m Trichromaticity
forall (m :: * -> *) a b. Monad m => (a -> m b) -> m a -> m b
=<< IO ZonedTime -> GammaLinearT Trichromaticity m ZonedTime
forall (b :: * -> *) (m :: * -> *) α. MonadBase b m => b α -> m α
liftBase IO ZonedTime
getZonedTime

instance MonadBase IO m => MonadGamma (GammaLinearT Temperature m) where
  gamma :: GammaLinearT Temperature m Trichromaticity
gamma = (Temperature -> Trichromaticity)
-> GammaLinearT Temperature m Temperature
-> GammaLinearT Temperature m Trichromaticity
forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
fmap Temperature -> Trichromaticity
forall c. RGB c => c -> Trichromaticity
toRGB (GammaLinearT Temperature m Temperature
 -> GammaLinearT Temperature m Trichromaticity)
-> GammaLinearT Temperature m Temperature
-> GammaLinearT Temperature m Trichromaticity
forall a b. (a -> b) -> a -> b
$ (Rational -> Temperature -> Temperature -> Temperature)
-> LocalTime -> GammaLinearT Temperature m Temperature
forall (m :: * -> *) c.
Monad m =>
(Rational -> c -> c -> c) -> LocalTime -> GammaLinearT c m c
calculateRGB Rational -> Temperature -> Temperature -> Temperature
weightedAverageTemperature (LocalTime -> GammaLinearT Temperature m Temperature)
-> (ZonedTime -> LocalTime)
-> ZonedTime
-> GammaLinearT Temperature m Temperature
forall b c a. (b -> c) -> (a -> b) -> a -> c
. ZonedTime -> LocalTime
zonedTimeToLocalTime (ZonedTime -> GammaLinearT Temperature m Temperature)
-> GammaLinearT Temperature m ZonedTime
-> GammaLinearT Temperature m Temperature
forall (m :: * -> *) a b. Monad m => (a -> m b) -> m a -> m b
=<< IO ZonedTime -> GammaLinearT Temperature m ZonedTime
forall (b :: * -> *) (m :: * -> *) α. MonadBase b m => b α -> m α
liftBase IO ZonedTime
getZonedTime

nextTimeRGB :: M.Map TimeOfDay c -> LocalTime -> Maybe (LocalTime,c)
nextTimeRGB :: Map TimeOfDay c -> LocalTime -> Maybe (LocalTime, c)
nextTimeRGB Map TimeOfDay c
m LocalTime
time = Maybe (LocalTime, c)
-> (() -> Maybe (LocalTime, c)) -> Maybe (LocalTime, c)
forall e (m :: * -> *) a.
MonadError e m =>
m a -> (e -> m a) -> m a
catchError ((TimeOfDay, c) -> (LocalTime, c)
toLocalTimeToday ((TimeOfDay, c) -> (LocalTime, c))
-> Maybe (TimeOfDay, c) -> Maybe (LocalTime, c)
forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
<$> TimeOfDay -> Map TimeOfDay c -> Maybe (TimeOfDay, c)
forall k v. Ord k => k -> Map k v -> Maybe (k, v)
M.lookupGT (LocalTime -> TimeOfDay
localTimeOfDay LocalTime
time) Map TimeOfDay c
m) ((() -> Maybe (LocalTime, c)) -> Maybe (LocalTime, c))
-> (() -> Maybe (LocalTime, c)) -> Maybe (LocalTime, c)
forall a b. (a -> b) -> a -> b
$
                     Maybe (LocalTime, c) -> () -> Maybe (LocalTime, c)
forall a b. a -> b -> a
const ((TimeOfDay, c) -> (LocalTime, c)
toLocalTimeTomorrow ((TimeOfDay, c) -> (LocalTime, c))
-> Maybe (TimeOfDay, c) -> Maybe (LocalTime, c)
forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
<$> Map TimeOfDay c -> Maybe (TimeOfDay, c)
forall k a. Map k a -> Maybe (k, a)
M.lookupMin Map TimeOfDay c
m)
  where toLocalTimeToday :: (TimeOfDay, c) -> (LocalTime, c)
toLocalTimeToday (TimeOfDay
tod,c
tc) = let t :: LocalTime
t = LocalTime :: Day -> TimeOfDay -> LocalTime
LocalTime { localDay :: Day
localDay = LocalTime -> Day
localDay LocalTime
time
                                                      , localTimeOfDay :: TimeOfDay
localTimeOfDay = TimeOfDay
tod
                                                      }
                                     in (LocalTime
t,c
tc)
        toLocalTimeTomorrow :: (TimeOfDay, c) -> (LocalTime, c)
toLocalTimeTomorrow (TimeOfDay, c)
x = let (LocalTime
t,c
tc) = (TimeOfDay, c) -> (LocalTime, c)
toLocalTimeToday (TimeOfDay, c)
x
                                    t' :: LocalTime
t' = LocalTime
t { localDay :: Day
localDay = Day -> Day
forall a. Enum a => a -> a
succ (Day -> Day) -> Day -> Day
forall a b. (a -> b) -> a -> b
$ LocalTime -> Day
localDay LocalTime
t }
                                 in (LocalTime
t',c
tc)

prevTimeRGB :: M.Map TimeOfDay c -> LocalTime -> Maybe (LocalTime,c)
prevTimeRGB :: Map TimeOfDay c -> LocalTime -> Maybe (LocalTime, c)
prevTimeRGB Map TimeOfDay c
m LocalTime
time = Maybe (LocalTime, c)
-> (() -> Maybe (LocalTime, c)) -> Maybe (LocalTime, c)
forall e (m :: * -> *) a.
MonadError e m =>
m a -> (e -> m a) -> m a
catchError ((TimeOfDay, c) -> (LocalTime, c)
toLocalTimeToday ((TimeOfDay, c) -> (LocalTime, c))
-> Maybe (TimeOfDay, c) -> Maybe (LocalTime, c)
forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
<$> TimeOfDay -> Map TimeOfDay c -> Maybe (TimeOfDay, c)
forall k v. Ord k => k -> Map k v -> Maybe (k, v)
M.lookupLE (LocalTime -> TimeOfDay
localTimeOfDay LocalTime
time) Map TimeOfDay c
m) ((() -> Maybe (LocalTime, c)) -> Maybe (LocalTime, c))
-> (() -> Maybe (LocalTime, c)) -> Maybe (LocalTime, c)
forall a b. (a -> b) -> a -> b
$
                     Maybe (LocalTime, c) -> () -> Maybe (LocalTime, c)
forall a b. a -> b -> a
const ((TimeOfDay, c) -> (LocalTime, c)
toLocalTimeYesterday ((TimeOfDay, c) -> (LocalTime, c))
-> Maybe (TimeOfDay, c) -> Maybe (LocalTime, c)
forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
<$> Map TimeOfDay c -> Maybe (TimeOfDay, c)
forall k a. Map k a -> Maybe (k, a)
M.lookupMax Map TimeOfDay c
m)
  where toLocalTimeToday :: (TimeOfDay, c) -> (LocalTime, c)
toLocalTimeToday (TimeOfDay
tod,c
tc) = let t :: LocalTime
t = LocalTime :: Day -> TimeOfDay -> LocalTime
LocalTime { localDay :: Day
localDay = LocalTime -> Day
localDay LocalTime
time
                                                      , localTimeOfDay :: TimeOfDay
localTimeOfDay = TimeOfDay
tod
                                                      }
                                     in (LocalTime
t,c
tc)
        toLocalTimeYesterday :: (TimeOfDay, c) -> (LocalTime, c)
toLocalTimeYesterday (TimeOfDay, c)
x = let (LocalTime
t,c
tc) = (TimeOfDay, c) -> (LocalTime, c)
toLocalTimeToday (TimeOfDay, c)
x
                                     t' :: LocalTime
t' = LocalTime
t { localDay :: Day
localDay = Day -> Day
forall a. Enum a => a -> a
pred (Day -> Day) -> Day -> Day
forall a b. (a -> b) -> a -> b
$ LocalTime -> Day
localDay LocalTime
t }
                                  in (LocalTime
t',c
tc)

calculateRGB :: Monad m
             => (Rational -> c -> c -> c)
             -> LocalTime -> GammaLinearT c m c
calculateRGB :: (Rational -> c -> c -> c) -> LocalTime -> GammaLinearT c m c
calculateRGB Rational -> c -> c -> c
weightedAverage LocalTime
time = do
  Map TimeOfDay c
m <- ReaderT (Map TimeOfDay c) m (Map TimeOfDay c)
-> GammaLinearT c m (Map TimeOfDay c)
forall c (m :: * -> *) a.
ReaderT (Map TimeOfDay c) m a -> GammaLinearT c m a
GammaLinearT ReaderT (Map TimeOfDay c) m (Map TimeOfDay c)
forall r (m :: * -> *). MonadReader r m => m r
ask
  c -> GammaLinearT c m c
forall (m :: * -> *) a. Monad m => a -> m a
return (c -> GammaLinearT c m c)
-> (Maybe c -> c) -> Maybe c -> GammaLinearT c m c
forall b c a. (b -> c) -> (a -> b) -> a -> c
. Maybe c -> c
forall a. HasCallStack => Maybe a -> a
fromJust (Maybe c -> GammaLinearT c m c) -> Maybe c -> GammaLinearT c m c
forall a b. (a -> b) -> a -> b
$ do
    (LocalTime
nextTime , c
nextRGB) <- Map TimeOfDay c -> LocalTime -> Maybe (LocalTime, c)
forall c. Map TimeOfDay c -> LocalTime -> Maybe (LocalTime, c)
nextTimeRGB Map TimeOfDay c
m LocalTime
time
    (LocalTime
prevTime , c
prevRGB) <- Map TimeOfDay c -> LocalTime -> Maybe (LocalTime, c)
forall c. Map TimeOfDay c -> LocalTime -> Maybe (LocalTime, c)
prevTimeRGB Map TimeOfDay c
m LocalTime
time
    let diffSeconds :: LocalTime -> LocalTime -> Pico
diffSeconds LocalTime
t1 LocalTime
t2 = NominalDiffTime -> Pico
nominalDiffTimeToSeconds (NominalDiffTime -> Pico) -> NominalDiffTime -> Pico
forall a b. (a -> b) -> a -> b
$ LocalTime
t1 LocalTime -> LocalTime -> NominalDiffTime
`diffLocalTime` LocalTime
t2
        timeFraction :: Rational
timeFraction = Pico -> Rational
forall a. Real a => a -> Rational
toRational (Pico -> Rational) -> Pico -> Rational
forall a b. (a -> b) -> a -> b
$ (LocalTime
time LocalTime -> LocalTime -> Pico
`diffSeconds` LocalTime
prevTime) Pico -> Pico -> Pico
forall a. Fractional a => a -> a -> a
/ (LocalTime
nextTime LocalTime -> LocalTime -> Pico
`diffSeconds` LocalTime
prevTime)
    c -> Maybe c
forall (m :: * -> *) a. Monad m => a -> m a
return (c -> Maybe c) -> c -> Maybe c
forall a b. (a -> b) -> a -> b
$ Rational -> c -> c -> c
weightedAverage Rational
timeFraction c
prevRGB c
nextRGB

weightedAverageTrichromaticity :: Rational -> Trichromaticity -> Trichromaticity -> Trichromaticity
weightedAverageTrichromaticity :: Rational -> Trichromaticity -> Trichromaticity -> Trichromaticity
weightedAverageTrichromaticity Rational
w Trichromaticity
tc1 Trichromaticity
tc2 = Trichromaticity :: Chromaticity -> Chromaticity -> Chromaticity -> Trichromaticity
Trichromaticity { red :: Chromaticity
red = Chromaticity -> Chromaticity -> Chromaticity
f (Trichromaticity -> Chromaticity
red Trichromaticity
tc1) (Trichromaticity -> Chromaticity
red Trichromaticity
tc2)
                                                           , green :: Chromaticity
green = Chromaticity -> Chromaticity -> Chromaticity
f (Trichromaticity -> Chromaticity
green Trichromaticity
tc1) (Trichromaticity -> Chromaticity
green Trichromaticity
tc2)
                                                           , blue :: Chromaticity
blue = Chromaticity -> Chromaticity -> Chromaticity
f (Trichromaticity -> Chromaticity
blue Trichromaticity
tc1) (Trichromaticity -> Chromaticity
blue Trichromaticity
tc2)
                                                           }
  where f :: Chromaticity -> Chromaticity -> Chromaticity
f Chromaticity
c1 Chromaticity
c2 = Rational -> Chromaticity
forall a b. (RealFrac a, Integral b) => a -> b
round (Rational -> Chromaticity) -> Rational -> Chromaticity
forall a b. (a -> b) -> a -> b
$ Chromaticity -> Rational
forall a b. (Integral a, Num b) => a -> b
fromIntegral Chromaticity
c1 Rational -> Rational -> Rational
forall a. Num a => a -> a -> a
+ Rational
w Rational -> Rational -> Rational
forall a. Num a => a -> a -> a
* (Chromaticity -> Rational
forall a b. (Integral a, Num b) => a -> b
fromIntegral Chromaticity
c2 Rational -> Rational -> Rational
forall a. Num a => a -> a -> a
- Chromaticity -> Rational
forall a b. (Integral a, Num b) => a -> b
fromIntegral Chromaticity
c1)

weightedAverageTemperature :: Rational -> Temperature -> Temperature -> Temperature
weightedAverageTemperature :: Rational -> Temperature -> Temperature -> Temperature
weightedAverageTemperature Rational
w Temperature
t1 Temperature
t2 = Rational -> Temperature
forall a. Fractional a => Rational -> a
fromRational (Rational -> Temperature) -> Rational -> Temperature
forall a b. (a -> b) -> a -> b
$ Temperature -> Rational
forall a. Real a => a -> Rational
toRational Temperature
t1 Rational -> Rational -> Rational
forall a. Num a => a -> a -> a
+ Rational
w Rational -> Rational -> Rational
forall a. Num a => a -> a -> a
* (Temperature -> Rational
forall a. Real a => a -> Rational
toRational Temperature
t2 Rational -> Rational -> Rational
forall a. Num a => a -> a -> a
- Temperature -> Rational
forall a. Real a => a -> Rational
toRational Temperature
t1)

-- TODO: maybe remove RGB constraint
runGammaLinearT' :: RGB c => M.Map TimeOfDay c -> GammaLinearT c m a -> m a
runGammaLinearT' :: Map TimeOfDay c -> GammaLinearT c m a -> m a
runGammaLinearT' Map TimeOfDay c
rgbs GammaLinearT c m a
tma = ReaderT (Map TimeOfDay c) m a -> Map TimeOfDay c -> m a
forall r (m :: * -> *) a. ReaderT r m a -> r -> m a
runReaderT (GammaLinearT c m a -> ReaderT (Map TimeOfDay c) m a
forall c (m :: * -> *) a.
GammaLinearT c m a -> ReaderT (Map TimeOfDay c) m a
unGammaLinearT GammaLinearT c m a
tma) Map TimeOfDay c
rgbs

-- TODO: maybe remove RGB constraint
runGammaLinearT :: RGB c => N.NonEmpty (TimeOfDay,c) -> GammaLinearT c m a -> m a
runGammaLinearT :: NonEmpty (TimeOfDay, c) -> GammaLinearT c m a -> m a
runGammaLinearT NonEmpty (TimeOfDay, c)
rgbs = Map TimeOfDay c -> GammaLinearT c m a -> m a
forall c (m :: * -> *) a.
RGB c =>
Map TimeOfDay c -> GammaLinearT c m a -> m a
runGammaLinearT' (Map TimeOfDay c -> GammaLinearT c m a -> m a)
-> Map TimeOfDay c -> GammaLinearT c m a -> m a
forall a b. (a -> b) -> a -> b
$ [(TimeOfDay, c)] -> Map TimeOfDay c
forall k a. Ord k => [(k, a)] -> Map k a
M.fromList ([(TimeOfDay, c)] -> Map TimeOfDay c)
-> (NonEmpty (TimeOfDay, c) -> [(TimeOfDay, c)])
-> NonEmpty (TimeOfDay, c)
-> Map TimeOfDay c
forall b c a. (b -> c) -> (a -> b) -> a -> c
. NonEmpty (TimeOfDay, c) -> [(TimeOfDay, c)]
forall a. NonEmpty a -> [a]
N.toList (NonEmpty (TimeOfDay, c) -> Map TimeOfDay c)
-> NonEmpty (TimeOfDay, c) -> Map TimeOfDay c
forall a b. (a -> b) -> a -> b
$ NonEmpty (TimeOfDay, c)
rgbs

newtype Hour = Hour { Hour -> Finite 24
unHour :: F.Finite 24 }
  deriving (Hour
Hour -> Hour -> Bounded Hour
forall a. a -> a -> Bounded a
maxBound :: Hour
$cmaxBound :: Hour
minBound :: Hour
$cminBound :: Hour
Bounded, Int -> Hour
Hour -> Int
Hour -> [Hour]
Hour -> Hour
Hour -> Hour -> [Hour]
Hour -> Hour -> Hour -> [Hour]
(Hour -> Hour)
-> (Hour -> Hour)
-> (Int -> Hour)
-> (Hour -> Int)
-> (Hour -> [Hour])
-> (Hour -> Hour -> [Hour])
-> (Hour -> Hour -> [Hour])
-> (Hour -> Hour -> Hour -> [Hour])
-> Enum Hour
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 :: Hour -> Hour -> Hour -> [Hour]
$cenumFromThenTo :: Hour -> Hour -> Hour -> [Hour]
enumFromTo :: Hour -> Hour -> [Hour]
$cenumFromTo :: Hour -> Hour -> [Hour]
enumFromThen :: Hour -> Hour -> [Hour]
$cenumFromThen :: Hour -> Hour -> [Hour]
enumFrom :: Hour -> [Hour]
$cenumFrom :: Hour -> [Hour]
fromEnum :: Hour -> Int
$cfromEnum :: Hour -> Int
toEnum :: Int -> Hour
$ctoEnum :: Int -> Hour
pred :: Hour -> Hour
$cpred :: Hour -> Hour
succ :: Hour -> Hour
$csucc :: Hour -> Hour
Enum, Hour -> Hour -> Bool
(Hour -> Hour -> Bool) -> (Hour -> Hour -> Bool) -> Eq Hour
forall a. (a -> a -> Bool) -> (a -> a -> Bool) -> Eq a
/= :: Hour -> Hour -> Bool
$c/= :: Hour -> Hour -> Bool
== :: Hour -> Hour -> Bool
$c== :: Hour -> Hour -> Bool
Eq, (forall x. Hour -> Rep Hour x)
-> (forall x. Rep Hour x -> Hour) -> Generic Hour
forall x. Rep Hour x -> Hour
forall x. Hour -> Rep Hour x
forall a.
(forall x. a -> Rep a x) -> (forall x. Rep a x -> a) -> Generic a
$cto :: forall x. Rep Hour x -> Hour
$cfrom :: forall x. Hour -> Rep Hour x
Generic, Enum Hour
Real Hour
Real Hour
-> Enum Hour
-> (Hour -> Hour -> Hour)
-> (Hour -> Hour -> Hour)
-> (Hour -> Hour -> Hour)
-> (Hour -> Hour -> Hour)
-> (Hour -> Hour -> (Hour, Hour))
-> (Hour -> Hour -> (Hour, Hour))
-> (Hour -> Integer)
-> Integral Hour
Hour -> Integer
Hour -> Hour -> (Hour, Hour)
Hour -> Hour -> Hour
forall a.
Real a
-> Enum a
-> (a -> a -> a)
-> (a -> a -> a)
-> (a -> a -> a)
-> (a -> a -> a)
-> (a -> a -> (a, a))
-> (a -> a -> (a, a))
-> (a -> Integer)
-> Integral a
toInteger :: Hour -> Integer
$ctoInteger :: Hour -> Integer
divMod :: Hour -> Hour -> (Hour, Hour)
$cdivMod :: Hour -> Hour -> (Hour, Hour)
quotRem :: Hour -> Hour -> (Hour, Hour)
$cquotRem :: Hour -> Hour -> (Hour, Hour)
mod :: Hour -> Hour -> Hour
$cmod :: Hour -> Hour -> Hour
div :: Hour -> Hour -> Hour
$cdiv :: Hour -> Hour -> Hour
rem :: Hour -> Hour -> Hour
$crem :: Hour -> Hour -> Hour
quot :: Hour -> Hour -> Hour
$cquot :: Hour -> Hour -> Hour
$cp2Integral :: Enum Hour
$cp1Integral :: Real Hour
Integral, Integer -> Hour
Hour -> Hour
Hour -> Hour -> Hour
(Hour -> Hour -> Hour)
-> (Hour -> Hour -> Hour)
-> (Hour -> Hour -> Hour)
-> (Hour -> Hour)
-> (Hour -> Hour)
-> (Hour -> Hour)
-> (Integer -> Hour)
-> Num Hour
forall a.
(a -> a -> a)
-> (a -> a -> a)
-> (a -> a -> a)
-> (a -> a)
-> (a -> a)
-> (a -> a)
-> (Integer -> a)
-> Num a
fromInteger :: Integer -> Hour
$cfromInteger :: Integer -> Hour
signum :: Hour -> Hour
$csignum :: Hour -> Hour
abs :: Hour -> Hour
$cabs :: Hour -> Hour
negate :: Hour -> Hour
$cnegate :: Hour -> Hour
* :: Hour -> Hour -> Hour
$c* :: Hour -> Hour -> Hour
- :: Hour -> Hour -> Hour
$c- :: Hour -> Hour -> Hour
+ :: Hour -> Hour -> Hour
$c+ :: Hour -> Hour -> Hour
Num, Eq Hour
Eq Hour
-> (Hour -> Hour -> Ordering)
-> (Hour -> Hour -> Bool)
-> (Hour -> Hour -> Bool)
-> (Hour -> Hour -> Bool)
-> (Hour -> Hour -> Bool)
-> (Hour -> Hour -> Hour)
-> (Hour -> Hour -> Hour)
-> Ord Hour
Hour -> Hour -> Bool
Hour -> Hour -> Ordering
Hour -> Hour -> Hour
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 :: Hour -> Hour -> Hour
$cmin :: Hour -> Hour -> Hour
max :: Hour -> Hour -> Hour
$cmax :: Hour -> Hour -> Hour
>= :: Hour -> Hour -> Bool
$c>= :: Hour -> Hour -> Bool
> :: Hour -> Hour -> Bool
$c> :: Hour -> Hour -> Bool
<= :: Hour -> Hour -> Bool
$c<= :: Hour -> Hour -> Bool
< :: Hour -> Hour -> Bool
$c< :: Hour -> Hour -> Bool
compare :: Hour -> Hour -> Ordering
$ccompare :: Hour -> Hour -> Ordering
$cp1Ord :: Eq Hour
Ord, ReadPrec [Hour]
ReadPrec Hour
Int -> ReadS Hour
ReadS [Hour]
(Int -> ReadS Hour)
-> ReadS [Hour] -> ReadPrec Hour -> ReadPrec [Hour] -> Read Hour
forall a.
(Int -> ReadS a)
-> ReadS [a] -> ReadPrec a -> ReadPrec [a] -> Read a
readListPrec :: ReadPrec [Hour]
$creadListPrec :: ReadPrec [Hour]
readPrec :: ReadPrec Hour
$creadPrec :: ReadPrec Hour
readList :: ReadS [Hour]
$creadList :: ReadS [Hour]
readsPrec :: Int -> ReadS Hour
$creadsPrec :: Int -> ReadS Hour
Read, Num Hour
Ord Hour
Num Hour -> Ord Hour -> (Hour -> Rational) -> Real Hour
Hour -> Rational
forall a. Num a -> Ord a -> (a -> Rational) -> Real a
toRational :: Hour -> Rational
$ctoRational :: Hour -> Rational
$cp2Real :: Ord Hour
$cp1Real :: Num Hour
Real, Int -> Hour -> ShowS
[Hour] -> ShowS
Hour -> String
(Int -> Hour -> ShowS)
-> (Hour -> String) -> ([Hour] -> ShowS) -> Show Hour
forall a.
(Int -> a -> ShowS) -> (a -> String) -> ([a] -> ShowS) -> Show a
showList :: [Hour] -> ShowS
$cshowList :: [Hour] -> ShowS
show :: Hour -> String
$cshow :: Hour -> String
showsPrec :: Int -> Hour -> ShowS
$cshowsPrec :: Int -> Hour -> ShowS
Show)

instance NFData Hour

newtype Minute = Minute { Minute -> Finite 60
unMinute :: F.Finite 60 }
  deriving (Minute
Minute -> Minute -> Bounded Minute
forall a. a -> a -> Bounded a
maxBound :: Minute
$cmaxBound :: Minute
minBound :: Minute
$cminBound :: Minute
Bounded, Int -> Minute
Minute -> Int
Minute -> [Minute]
Minute -> Minute
Minute -> Minute -> [Minute]
Minute -> Minute -> Minute -> [Minute]
(Minute -> Minute)
-> (Minute -> Minute)
-> (Int -> Minute)
-> (Minute -> Int)
-> (Minute -> [Minute])
-> (Minute -> Minute -> [Minute])
-> (Minute -> Minute -> [Minute])
-> (Minute -> Minute -> Minute -> [Minute])
-> Enum Minute
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 :: Minute -> Minute -> Minute -> [Minute]
$cenumFromThenTo :: Minute -> Minute -> Minute -> [Minute]
enumFromTo :: Minute -> Minute -> [Minute]
$cenumFromTo :: Minute -> Minute -> [Minute]
enumFromThen :: Minute -> Minute -> [Minute]
$cenumFromThen :: Minute -> Minute -> [Minute]
enumFrom :: Minute -> [Minute]
$cenumFrom :: Minute -> [Minute]
fromEnum :: Minute -> Int
$cfromEnum :: Minute -> Int
toEnum :: Int -> Minute
$ctoEnum :: Int -> Minute
pred :: Minute -> Minute
$cpred :: Minute -> Minute
succ :: Minute -> Minute
$csucc :: Minute -> Minute
Enum, Minute -> Minute -> Bool
(Minute -> Minute -> Bool)
-> (Minute -> Minute -> Bool) -> Eq Minute
forall a. (a -> a -> Bool) -> (a -> a -> Bool) -> Eq a
/= :: Minute -> Minute -> Bool
$c/= :: Minute -> Minute -> Bool
== :: Minute -> Minute -> Bool
$c== :: Minute -> Minute -> Bool
Eq, (forall x. Minute -> Rep Minute x)
-> (forall x. Rep Minute x -> Minute) -> Generic Minute
forall x. Rep Minute x -> Minute
forall x. Minute -> Rep Minute x
forall a.
(forall x. a -> Rep a x) -> (forall x. Rep a x -> a) -> Generic a
$cto :: forall x. Rep Minute x -> Minute
$cfrom :: forall x. Minute -> Rep Minute x
Generic, Enum Minute
Real Minute
Real Minute
-> Enum Minute
-> (Minute -> Minute -> Minute)
-> (Minute -> Minute -> Minute)
-> (Minute -> Minute -> Minute)
-> (Minute -> Minute -> Minute)
-> (Minute -> Minute -> (Minute, Minute))
-> (Minute -> Minute -> (Minute, Minute))
-> (Minute -> Integer)
-> Integral Minute
Minute -> Integer
Minute -> Minute -> (Minute, Minute)
Minute -> Minute -> Minute
forall a.
Real a
-> Enum a
-> (a -> a -> a)
-> (a -> a -> a)
-> (a -> a -> a)
-> (a -> a -> a)
-> (a -> a -> (a, a))
-> (a -> a -> (a, a))
-> (a -> Integer)
-> Integral a
toInteger :: Minute -> Integer
$ctoInteger :: Minute -> Integer
divMod :: Minute -> Minute -> (Minute, Minute)
$cdivMod :: Minute -> Minute -> (Minute, Minute)
quotRem :: Minute -> Minute -> (Minute, Minute)
$cquotRem :: Minute -> Minute -> (Minute, Minute)
mod :: Minute -> Minute -> Minute
$cmod :: Minute -> Minute -> Minute
div :: Minute -> Minute -> Minute
$cdiv :: Minute -> Minute -> Minute
rem :: Minute -> Minute -> Minute
$crem :: Minute -> Minute -> Minute
quot :: Minute -> Minute -> Minute
$cquot :: Minute -> Minute -> Minute
$cp2Integral :: Enum Minute
$cp1Integral :: Real Minute
Integral, Integer -> Minute
Minute -> Minute
Minute -> Minute -> Minute
(Minute -> Minute -> Minute)
-> (Minute -> Minute -> Minute)
-> (Minute -> Minute -> Minute)
-> (Minute -> Minute)
-> (Minute -> Minute)
-> (Minute -> Minute)
-> (Integer -> Minute)
-> Num Minute
forall a.
(a -> a -> a)
-> (a -> a -> a)
-> (a -> a -> a)
-> (a -> a)
-> (a -> a)
-> (a -> a)
-> (Integer -> a)
-> Num a
fromInteger :: Integer -> Minute
$cfromInteger :: Integer -> Minute
signum :: Minute -> Minute
$csignum :: Minute -> Minute
abs :: Minute -> Minute
$cabs :: Minute -> Minute
negate :: Minute -> Minute
$cnegate :: Minute -> Minute
* :: Minute -> Minute -> Minute
$c* :: Minute -> Minute -> Minute
- :: Minute -> Minute -> Minute
$c- :: Minute -> Minute -> Minute
+ :: Minute -> Minute -> Minute
$c+ :: Minute -> Minute -> Minute
Num, Eq Minute
Eq Minute
-> (Minute -> Minute -> Ordering)
-> (Minute -> Minute -> Bool)
-> (Minute -> Minute -> Bool)
-> (Minute -> Minute -> Bool)
-> (Minute -> Minute -> Bool)
-> (Minute -> Minute -> Minute)
-> (Minute -> Minute -> Minute)
-> Ord Minute
Minute -> Minute -> Bool
Minute -> Minute -> Ordering
Minute -> Minute -> Minute
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 :: Minute -> Minute -> Minute
$cmin :: Minute -> Minute -> Minute
max :: Minute -> Minute -> Minute
$cmax :: Minute -> Minute -> Minute
>= :: Minute -> Minute -> Bool
$c>= :: Minute -> Minute -> Bool
> :: Minute -> Minute -> Bool
$c> :: Minute -> Minute -> Bool
<= :: Minute -> Minute -> Bool
$c<= :: Minute -> Minute -> Bool
< :: Minute -> Minute -> Bool
$c< :: Minute -> Minute -> Bool
compare :: Minute -> Minute -> Ordering
$ccompare :: Minute -> Minute -> Ordering
$cp1Ord :: Eq Minute
Ord, ReadPrec [Minute]
ReadPrec Minute
Int -> ReadS Minute
ReadS [Minute]
(Int -> ReadS Minute)
-> ReadS [Minute]
-> ReadPrec Minute
-> ReadPrec [Minute]
-> Read Minute
forall a.
(Int -> ReadS a)
-> ReadS [a] -> ReadPrec a -> ReadPrec [a] -> Read a
readListPrec :: ReadPrec [Minute]
$creadListPrec :: ReadPrec [Minute]
readPrec :: ReadPrec Minute
$creadPrec :: ReadPrec Minute
readList :: ReadS [Minute]
$creadList :: ReadS [Minute]
readsPrec :: Int -> ReadS Minute
$creadsPrec :: Int -> ReadS Minute
Read, Num Minute
Ord Minute
Num Minute -> Ord Minute -> (Minute -> Rational) -> Real Minute
Minute -> Rational
forall a. Num a -> Ord a -> (a -> Rational) -> Real a
toRational :: Minute -> Rational
$ctoRational :: Minute -> Rational
$cp2Real :: Ord Minute
$cp1Real :: Num Minute
Real, Int -> Minute -> ShowS
[Minute] -> ShowS
Minute -> String
(Int -> Minute -> ShowS)
-> (Minute -> String) -> ([Minute] -> ShowS) -> Show Minute
forall a.
(Int -> a -> ShowS) -> (a -> String) -> ([a] -> ShowS) -> Show a
showList :: [Minute] -> ShowS
$cshowList :: [Minute] -> ShowS
show :: Minute -> String
$cshow :: Minute -> String
showsPrec :: Int -> Minute -> ShowS
$cshowsPrec :: Int -> Minute -> ShowS
Show)

instance NFData Minute

infix 7 :.
data Time = Hour :. Minute
  deriving (Time
Time -> Time -> Bounded Time
forall a. a -> a -> Bounded a
maxBound :: Time
$cmaxBound :: Time
minBound :: Time
$cminBound :: Time
Bounded, Time -> Time -> Bool
(Time -> Time -> Bool) -> (Time -> Time -> Bool) -> Eq Time
forall a. (a -> a -> Bool) -> (a -> a -> Bool) -> Eq a
/= :: Time -> Time -> Bool
$c/= :: Time -> Time -> Bool
== :: Time -> Time -> Bool
$c== :: Time -> Time -> Bool
Eq, (forall x. Time -> Rep Time x)
-> (forall x. Rep Time x -> Time) -> Generic Time
forall x. Rep Time x -> Time
forall x. Time -> Rep Time x
forall a.
(forall x. a -> Rep a x) -> (forall x. Rep a x -> a) -> Generic a
$cto :: forall x. Rep Time x -> Time
$cfrom :: forall x. Time -> Rep Time x
Generic, Eq Time
Eq Time
-> (Time -> Time -> Ordering)
-> (Time -> Time -> Bool)
-> (Time -> Time -> Bool)
-> (Time -> Time -> Bool)
-> (Time -> Time -> Bool)
-> (Time -> Time -> Time)
-> (Time -> Time -> Time)
-> Ord Time
Time -> Time -> Bool
Time -> Time -> Ordering
Time -> Time -> Time
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 :: Time -> Time -> Time
$cmin :: Time -> Time -> Time
max :: Time -> Time -> Time
$cmax :: Time -> Time -> Time
>= :: Time -> Time -> Bool
$c>= :: Time -> Time -> Bool
> :: Time -> Time -> Bool
$c> :: Time -> Time -> Bool
<= :: Time -> Time -> Bool
$c<= :: Time -> Time -> Bool
< :: Time -> Time -> Bool
$c< :: Time -> Time -> Bool
compare :: Time -> Time -> Ordering
$ccompare :: Time -> Time -> Ordering
$cp1Ord :: Eq Time
Ord, ReadPrec [Time]
ReadPrec Time
Int -> ReadS Time
ReadS [Time]
(Int -> ReadS Time)
-> ReadS [Time] -> ReadPrec Time -> ReadPrec [Time] -> Read Time
forall a.
(Int -> ReadS a)
-> ReadS [a] -> ReadPrec a -> ReadPrec [a] -> Read a
readListPrec :: ReadPrec [Time]
$creadListPrec :: ReadPrec [Time]
readPrec :: ReadPrec Time
$creadPrec :: ReadPrec Time
readList :: ReadS [Time]
$creadList :: ReadS [Time]
readsPrec :: Int -> ReadS Time
$creadsPrec :: Int -> ReadS Time
Read, Int -> Time -> ShowS
[Time] -> ShowS
Time -> String
(Int -> Time -> ShowS)
-> (Time -> String) -> ([Time] -> ShowS) -> Show Time
forall a.
(Int -> a -> ShowS) -> (a -> String) -> ([a] -> ShowS) -> Show a
showList :: [Time] -> ShowS
$cshowList :: [Time] -> ShowS
show :: Time -> String
$cshow :: Time -> String
showsPrec :: Int -> Time -> ShowS
$cshowsPrec :: Int -> Time -> ShowS
Show)

instance NFData Time

instance Enum Time where
  fromEnum :: Time -> Int
fromEnum (Hour
h :. Minute
m) = Hour -> Int
forall a. Enum a => a -> Int
fromEnum Hour
h Int -> Int -> Int
forall a. Num a => a -> a -> a
* Int -> Int
forall a. Enum a => a -> a
succ (Minute -> Int
forall a. Enum a => a -> Int
fromEnum (Minute -> Int) -> Minute -> Int
forall a b. (a -> b) -> a -> b
$ Bounded Minute => Minute
forall a. Bounded a => a
maxBound @Minute) Int -> Int -> Int
forall a. Num a => a -> a -> a
+ Minute -> Int
forall a. Enum a => a -> Int
fromEnum Minute
m
  toEnum :: Int -> Time
toEnum Int
i = let (Int
h , Int
m) = Int
i Int -> Int -> (Int, Int)
forall a. Integral a => a -> a -> (a, a)
`divMod` Int -> Int
forall a. Enum a => a -> a
succ (Minute -> Int
forall a. Enum a => a -> Int
fromEnum (Minute -> Int) -> Minute -> Int
forall a b. (a -> b) -> a -> b
$ Bounded Minute => Minute
forall a. Bounded a => a
maxBound @Minute)
              in Int -> Hour
forall a. Enum a => Int -> a
toEnum Int
h Hour -> Minute -> Time
:. Int -> Minute
forall a. Enum a => Int -> a
toEnum Int
m

-- TODO: maybe remove RGB constraint
infix 6 ==>
(==>) :: RGB c => Time -> c -> (TimeOfDay,c)
==> :: Time -> c -> (TimeOfDay, c)
(==>) (Hour
h :. Minute
m) c
c = (TimeOfDay
time,c
c)
  where time :: TimeOfDay
time = TimeOfDay :: Int -> Int -> Pico -> TimeOfDay
TimeOfDay { todHour :: Int
todHour = Hour -> Int
forall a b. (Integral a, Num b) => a -> b
fromIntegral Hour
h
                         , todMin :: Int
todMin = Minute -> Int
forall a b. (Integral a, Num b) => a -> b
fromIntegral Minute
m
                         , todSec :: Pico
todSec = Pico
0
                         }