{-# options_haddock prune #-}
module Polysemy.Time.At where
import Control.Concurrent.STM (newTVarIO)
import Torsor (Torsor (add), difference)
import Polysemy.Time.Calendar (HasDate, date, dateToTime)
import Polysemy.Time.Data.TimeUnit (MilliSeconds (MilliSeconds), TimeUnit, addTimeUnit, convert)
import qualified Polysemy.Time.Effect.Time as Time
import Polysemy.Time.Effect.Time (Time)
dateCurrentRelative ::
∀ diff t d r .
Torsor t diff =>
Members [Time t d, AtomicState (t, t)] r =>
Sem r t
dateCurrentRelative :: forall diff t d (r :: EffectRow).
(Torsor t diff, Members '[Time t d, AtomicState (t, t)] r) =>
Sem r t
dateCurrentRelative = do
(t
startAt, t
startActual) <- forall s (r :: EffectRow). Member (AtomicState s) r => Sem r s
atomicGet @(t, t)
(forall p v. Torsor p v => v -> p -> p
`add` t
startAt) forall b c a. (b -> c) -> (a -> b) -> a -> c
. (forall p v. Torsor p v => p -> p -> v
`difference` t
startActual) forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
<$> forall t d (r :: EffectRow). Member (Time t d) r => Sem r t
Time.now @t @d
interceptTimeAtWithStart ::
∀ diff t d r a .
Torsor t diff =>
TimeUnit diff =>
HasDate t d =>
Members [Time t d, AtomicState (t, t)] r =>
Sem r a ->
Sem r a
interceptTimeAtWithStart :: forall diff t d (r :: EffectRow) a.
(Torsor t diff, TimeUnit diff, HasDate t d,
Members '[Time t d, AtomicState (t, t)] r) =>
Sem r a -> Sem r a
interceptTimeAtWithStart =
forall (e :: (* -> *) -> * -> *) (r :: EffectRow) a.
(Member e r, FirstOrder e "intercept") =>
(forall x (rInitial :: EffectRow). e (Sem rInitial) x -> Sem r x)
-> Sem r a -> Sem r a
intercept @(Time t d) \case
Time t d (Sem rInitial) x
Time.Now ->
forall diff t d (r :: EffectRow).
(Torsor t diff, Members '[Time t d, AtomicState (t, t)] r) =>
Sem r t
dateCurrentRelative @diff @t @d
Time t d (Sem rInitial) x
Time.Today ->
forall t d. HasDate t d => t -> d
date forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
<$> forall diff t d (r :: EffectRow).
(Torsor t diff, Members '[Time t d, AtomicState (t, t)] r) =>
Sem r t
dateCurrentRelative @diff @t @d
Time.Sleep u
t ->
forall t d u (r :: EffectRow).
(TimeUnit u, Member (Time t d) r) =>
u -> Sem r ()
Time.sleep @t @d u
t
Time.SetTime t
startAt -> do
t
startActual <- forall t d (r :: EffectRow). Member (Time t d) r => Sem r t
Time.now @t @d
forall s (r :: EffectRow).
Member (AtomicState s) r =>
s -> Sem r ()
atomicPut @(t, t) (t
startAt, t
startActual)
Time.Adjust u1
diff -> do
forall s (r :: EffectRow).
Member (AtomicState s) r =>
(s -> s) -> Sem r ()
atomicModify' @(t, t) (forall (p :: * -> * -> *) a b c.
Bifunctor p =>
(a -> b) -> p a c -> p b c
first (forall t u1 u2. AddTimeUnit t u1 u2 => u1 -> t -> t
addTimeUnit u1
diff))
Time.SetDate d
startAt -> do
t
startActual <- forall t d (r :: EffectRow). Member (Time t d) r => Sem r t
Time.now @t @d
forall s (r :: EffectRow).
Member (AtomicState s) r =>
s -> Sem r ()
atomicPut @(t, t) (forall t d. HasDate t d => d -> t
dateToTime d
startAt, t
startActual)
{-# inline interceptTimeAtWithStart #-}
interceptTimeAt ::
∀ (diff :: Type) t d r a .
TimeUnit diff =>
Torsor t diff =>
HasDate t d =>
Members [Time t d, Embed IO] r =>
t ->
Sem r a ->
Sem r a
interceptTimeAt :: forall diff t d (r :: EffectRow) a.
(TimeUnit diff, Torsor t diff, HasDate t d,
Members '[Time t d, Embed IO] r) =>
t -> Sem r a -> Sem r a
interceptTimeAt t
startAt Sem r a
sem = do
t
startActual <- forall t d (r :: EffectRow). Member (Time t d) r => Sem r t
Time.now @t @d
TVar (t, t)
tv <- forall (m :: * -> *) (r :: EffectRow) a.
Member (Embed m) r =>
m a -> Sem r a
embed (forall a. a -> IO (TVar a)
newTVarIO (t
startAt, t
startActual))
forall (r :: EffectRow) s a.
Member (Embed IO) r =>
TVar s -> Sem (AtomicState s : r) a -> Sem r a
runAtomicStateTVar TVar (t, t)
tv forall b c a. (b -> c) -> (a -> b) -> a -> c
. forall diff t d (r :: EffectRow) a.
(Torsor t diff, TimeUnit diff, HasDate t d,
Members '[Time t d, AtomicState (t, t)] r) =>
Sem r a -> Sem r a
interceptTimeAtWithStart @diff @t @d forall b c a. (b -> c) -> (a -> b) -> a -> c
. forall (e :: (* -> *) -> * -> *) (r :: EffectRow) a.
Sem r a -> Sem (e : r) a
raise forall a b. (a -> b) -> a -> b
$ Sem r a
sem
{-# inline interceptTimeAt #-}
sleepPoll ::
∀ t d diff u r .
Ord diff =>
TimeUnit u =>
TimeUnit diff =>
Torsor t diff =>
Members [Time t d, AtomicState t] r =>
u ->
t ->
Sem r ()
sleepPoll :: forall t d diff u (r :: EffectRow).
(Ord diff, TimeUnit u, TimeUnit diff, Torsor t diff,
Members '[Time t d, AtomicState t] r) =>
u -> t -> Sem r ()
sleepPoll u
duration t
start =
Sem r ()
spin
where
spin :: Sem r ()
spin = do
forall t d u (r :: EffectRow).
(TimeUnit u, Member (Time t d) r) =>
u -> Sem r ()
Time.sleep @t @d (Int64 -> MilliSeconds
MilliSeconds Int64
10)
forall (m :: * -> *). Monad m => m Bool -> m () -> m ()
unlessM (t -> Bool
later forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
<$> forall s (r :: EffectRow). Member (AtomicState s) r => Sem r s
atomicGet @t) Sem r ()
spin
later :: t -> Bool
later t
now =
forall p v. Torsor p v => p -> p -> v
difference t
now t
start forall a. Ord a => a -> a -> Bool
>= diff
diff
diff :: diff
diff =
forall a b. (TimeUnit a, TimeUnit b) => a -> b
convert @u @diff u
duration
interceptTimeConstantState ::
∀ t d diff r a .
Ord diff =>
HasDate t d =>
TimeUnit diff =>
Torsor t diff =>
Members [Time t d, AtomicState t] r =>
Sem r a ->
Sem r a
interceptTimeConstantState :: forall t d diff (r :: EffectRow) a.
(Ord diff, HasDate t d, TimeUnit diff, Torsor t diff,
Members '[Time t d, AtomicState t] r) =>
Sem r a -> Sem r a
interceptTimeConstantState =
forall (e :: (* -> *) -> * -> *) (r :: EffectRow) a.
(Member e r, FirstOrder e "intercept") =>
(forall x (rInitial :: EffectRow). e (Sem rInitial) x -> Sem r x)
-> Sem r a -> Sem r a
intercept @(Time t d) \case
Time t d (Sem rInitial) x
Time.Now ->
forall s (r :: EffectRow). Member (AtomicState s) r => Sem r s
atomicGet
Time t d (Sem rInitial) x
Time.Today ->
forall s s' (r :: EffectRow).
Member (AtomicState s) r =>
(s -> s') -> Sem r s'
atomicGets @t forall t d. HasDate t d => t -> d
date
Time.Sleep u
t ->
forall t d diff u (r :: EffectRow).
(Ord diff, TimeUnit u, TimeUnit diff, Torsor t diff,
Members '[Time t d, AtomicState t] r) =>
u -> t -> Sem r ()
sleepPoll @t @d u
t forall (m :: * -> *) a b. Monad m => (a -> m b) -> m a -> m b
=<< forall s (r :: EffectRow). Member (AtomicState s) r => Sem r s
atomicGet
Time.SetTime t
now ->
forall s (r :: EffectRow).
Member (AtomicState s) r =>
s -> Sem r ()
atomicPut t
now
Time.Adjust u1
diff ->
forall s (r :: EffectRow).
Member (AtomicState s) r =>
(s -> s) -> Sem r ()
atomicModify' @t (forall t u1 u2. AddTimeUnit t u1 u2 => u1 -> t -> t
addTimeUnit u1
diff)
Time.SetDate d
startAt ->
forall s (r :: EffectRow).
Member (AtomicState s) r =>
s -> Sem r ()
atomicPut @t (forall t d. HasDate t d => d -> t
dateToTime d
startAt)
{-# inline interceptTimeConstantState #-}
interceptTimeConstant ::
∀ t d diff r a .
Ord diff =>
HasDate t d =>
TimeUnit diff =>
Torsor t diff =>
Members [Time t d, Embed IO] r =>
t ->
Sem r a ->
Sem r a
interceptTimeConstant :: forall t d diff (r :: EffectRow) a.
(Ord diff, HasDate t d, TimeUnit diff, Torsor t diff,
Members '[Time t d, Embed IO] r) =>
t -> Sem r a -> Sem r a
interceptTimeConstant t
startAt Sem r a
sem = do
TVar t
tv <- forall (m :: * -> *) (r :: EffectRow) a.
Member (Embed m) r =>
m a -> Sem r a
embed (forall a. a -> IO (TVar a)
newTVarIO t
startAt)
forall (r :: EffectRow) s a.
Member (Embed IO) r =>
TVar s -> Sem (AtomicState s : r) a -> Sem r a
runAtomicStateTVar TVar t
tv forall b c a. (b -> c) -> (a -> b) -> a -> c
. forall t d diff (r :: EffectRow) a.
(Ord diff, HasDate t d, TimeUnit diff, Torsor t diff,
Members '[Time t d, AtomicState t] r) =>
Sem r a -> Sem r a
interceptTimeConstantState @t forall b c a. (b -> c) -> (a -> b) -> a -> c
. forall (e :: (* -> *) -> * -> *) (r :: EffectRow) a.
Sem r a -> Sem (e : r) a
raise forall a b. (a -> b) -> a -> b
$ Sem r a
sem
{-# inline interceptTimeConstant #-}
interceptTimeConstantNow ::
∀ t d diff r a .
Ord diff =>
HasDate t d =>
TimeUnit diff =>
Torsor t diff =>
Members [Time t d, Embed IO] r =>
Sem r a ->
Sem r a
interceptTimeConstantNow :: forall t d diff (r :: EffectRow) a.
(Ord diff, HasDate t d, TimeUnit diff, Torsor t diff,
Members '[Time t d, Embed IO] r) =>
Sem r a -> Sem r a
interceptTimeConstantNow Sem r a
sem = do
t
now <- forall t d (r :: EffectRow). Member (Time t d) r => Sem r t
Time.now @t @d
TVar t
tv <- forall (m :: * -> *) (r :: EffectRow) a.
Member (Embed m) r =>
m a -> Sem r a
embed (forall a. a -> IO (TVar a)
newTVarIO t
now)
forall (r :: EffectRow) s a.
Member (Embed IO) r =>
TVar s -> Sem (AtomicState s : r) a -> Sem r a
runAtomicStateTVar TVar t
tv forall b c a. (b -> c) -> (a -> b) -> a -> c
. forall t d diff (r :: EffectRow) a.
(Ord diff, HasDate t d, TimeUnit diff, Torsor t diff,
Members '[Time t d, AtomicState t] r) =>
Sem r a -> Sem r a
interceptTimeConstantState @t forall b c a. (b -> c) -> (a -> b) -> a -> c
. forall (e :: (* -> *) -> * -> *) (r :: EffectRow) a.
Sem r a -> Sem (e : r) a
raise forall a b. (a -> b) -> a -> b
$ Sem r a
sem
{-# inline interceptTimeConstantNow #-}