spectacle-1.0.0: src/Control/Applicative/Queue.hs
{-# LANGUAGE TupleSections #-}
-- | Effect queues.
--
-- @since 1.0.0
module Control.Applicative.Queue
( Queue,
runQueue,
liftQueue,
wrapQueue,
joinQueue,
now,
later,
)
where
import Control.Applicative (Applicative (liftA2))
import Control.Applicative.Day (Day (Day), getDay)
import Control.Applicative.Phases (Phases (Here, There), liftPhases, lowerPhases, wrapPhases)
-- ---------------------------------------------------------------------------------------------------------------------
type Queue f = Day (Phases f)
runQueue :: Applicative f => Queue f a -> f a
runQueue = fmap fst . lowerPhases . flip getDay (Here ())
liftQueue :: Monad f => Queue f (f a) -> Queue f a
liftQueue (Day f) = Day \x ->
let fx = fmap fst (f x)
fy = fmap snd (f (fmap snd (f x)))
in liftA2 (,) (liftPhases fx) fy
wrapQueue :: Monad f => f (Queue f a) -> Queue f a
wrapQueue f = Day \x -> wrapPhases (fmap (($ x) . getDay) f)
joinQueue :: Monad f => Queue f (Queue f a) -> Queue f a
joinQueue (Day f) = Day \x ->
let x' = lowerPhases (fmap fst (f x))
in getDay (wrapQueue x') x
now :: Applicative f => f a -> Queue f a
now xs = Day \case
Here x -> There (,) xs (Here x)
There f y ys -> There (\(a, b) c -> (a, f b c)) (liftA2 (,) xs y) ys
later :: Applicative f => Queue f a -> Queue f a
later q = Day (go q)
where
go :: Applicative f => Queue f a -> Phases f b -> Phases f (a, b)
go (Day f) (Here y) = There (const id) (pure ()) (f (Here y))
go (Day f) (There g y ys) = There (fmap . g) y (f ys)