time-out-0.2: src/Control/Monad/Trans/Timer.hs
{- This file is part of time-out.
-
- Written in 2016 by fr33domlover <fr33domlover@riseup.net>.
-
- ♡ Copying is an act of love. Please copy, reuse and share.
-
- The author(s) have dedicated all copyright and related and neighboring
- rights to this software to the public domain worldwide. This software is
- distributed without any warranty.
-
- You should have received a copy of the CC0 Public Domain Dedication along
- with this software. If not, see
- <http://creativecommons.org/publicdomain/zero/1.0/>.
-}
{-# LANGUAGE GeneralizedNewtypeDeriving #-}
-- | Monad transformer for managing a timer.
module Control.Monad.Trans.Timer
( -- * Transformer
TimerT ()
, runTimerT
-- * Starting a timer
, startTimer
, startTimer'
, startTimerWith
-- * Stopping a timer
, stopTimer
-- * Restarting a timer
, restartTimer
, restartTimer'
, restartTimerWith
)
where
import Control.Monad.Catch
import Control.Monad.Fix (MonadFix)
import Control.Monad.IO.Class
import Control.Monad.Trans.Class (MonadTrans)
import Control.Monad.Trans.Reader
import Data.Time.Units (TimeUnit)
import qualified Control.Timer as T
newtype TimerT n m a = TimerT
{ unTT :: ReaderT (T.Timer n) m a
}
deriving
( -- Basics
Functor
, Applicative
, Monad
-- Extra monads from base
, MonadFix
-- Thread operations are IO
, MonadIO
-- This is a transformer after all
, MonadTrans
-- Exceptions
, MonadCatch
, MonadThrow
, MonadMask
)
askTimer :: Monad m => TimerT n m (T.Timer n)
askTimer = TimerT ask
runTimerT
:: (MonadIO m, MonadMask m, MonadIO n, MonadCatch n)
=> TimerT n m a
-> T.TimerSettings n
-> m a
runTimerT act sets = T.withTimer sets $ runReaderT $ unTT act
startTimer :: MonadIO m => TimerT n m ()
startTimer = askTimer >>= T.startTimer
startTimer' :: (MonadIO m, TimeUnit t) => t -> TimerT n m ()
startTimer' t = askTimer >>= flip T.startTimer' t
startTimerWith
:: (TimeUnit t, MonadIO m)
=> Maybe t
-> Maybe (n ())
-> TimerT n m ()
startTimerWith mtime maction =
askTimer >>= \ timer -> T.startTimerWith timer mtime maction
stopTimer :: MonadIO m => TimerT n m ()
stopTimer = askTimer >>= T.stopTimer
restartTimer :: MonadIO m => TimerT n m ()
restartTimer = askTimer >>= T.restartTimer
restartTimer' :: (TimeUnit t, MonadIO m) => t -> TimerT n m ()
restartTimer' t = askTimer >>= flip T.restartTimer' t
restartTimerWith
:: (TimeUnit t, MonadIO m)
=> Maybe t
-> Maybe (n ())
-> TimerT n m ()
restartTimerWith mtime maction =
askTimer >>= \ timer -> T.restartTimerWith timer mtime maction