{-# language Safe #-}

module LazyAsync.Actions.Start where

import LazyAsync.Types (Complex (..), LazyAsync (..), StartPoll (..))

import LazyAsync.Prelude (Applicative ((*>)), IO, MonadBase (..), MonadIO (..),
                          STM, atomically, return)

-- | 🚀 Starts an asynchronous action, if it has not already been started
start :: (MonadBase base m, MonadIO base) => LazyAsync a -> m ()
start :: forall (base :: * -> *) (m :: * -> *) a.
(MonadBase base m, MonadIO base) =>
LazyAsync a -> m ()
start Pure{}               = forall (m :: * -> *) a. Monad m => a -> m a
return ()
start Empty{}              = forall (m :: * -> *) a. Monad m => a -> m a
return ()
start (A1 (StartPoll STM ()
s STM (Status a)
_)) = forall (b :: * -> *) (m :: * -> *) α. MonadBase b m => b α -> m α
liftBase (forall (m :: * -> *) a. MonadIO m => IO a -> m a
liftIO (forall a. STM a -> IO a
atomically STM ()
s))
start (A2 (Complex Status x -> Status y -> Status a
_ LazyAsync x
x LazyAsync y
y)) = forall (base :: * -> *) (m :: * -> *) a.
(MonadBase base m, MonadIO base) =>
LazyAsync a -> m ()
start LazyAsync x
x forall (f :: * -> *) a b. Applicative f => f a -> f b -> f b
*> forall (base :: * -> *) (m :: * -> *) a.
(MonadBase base m, MonadIO base) =>
LazyAsync a -> m ()
start LazyAsync y
y

-- | Akin to 'start'
startIO :: LazyAsync a -> IO ()
startIO :: forall a. LazyAsync a -> IO ()
startIO = forall (base :: * -> *) (m :: * -> *) a.
(MonadBase base m, MonadIO base) =>
LazyAsync a -> m ()
start

-- | Akin to 'start'
startSTM :: LazyAsync a -> STM ()
startSTM :: forall a. LazyAsync a -> STM ()
startSTM Pure{}               = forall (m :: * -> *) a. Monad m => a -> m a
return ()
startSTM Empty{}              = forall (m :: * -> *) a. Monad m => a -> m a
return ()
startSTM (A1 (StartPoll STM ()
s STM (Status a)
_)) = STM ()
s
startSTM (A2 (Complex Status x -> Status y -> Status a
_ LazyAsync x
x LazyAsync y
y)) = forall a. LazyAsync a -> STM ()
startSTM LazyAsync x
x forall (f :: * -> *) a b. Applicative f => f a -> f b -> f b
*> forall a. LazyAsync a -> STM ()
startSTM LazyAsync y
y