{-# LANGUAGE FlexibleInstances #-}

module Control.Monad.Now
  ( MonadNow
  , getCurrentTime
  , getPOSIXTime
  ) where

import Control.Monad.Except (ExceptT)
import Control.Monad.Logger (LoggingT)
import Control.Monad.Reader (ReaderT)
import Control.Monad.Trans.Class (lift)
import Data.Time (UTCTime)
import Data.Time qualified as Time
import Data.Time.Clock.POSIX (POSIXTime)
import Data.Time.Clock.POSIX qualified as Time

class Monad m =>
      MonadNow m
  where
  getCurrentTime :: m UTCTime
  getPOSIXTime :: m POSIXTime

instance MonadNow IO where
  getCurrentTime :: IO UTCTime
getCurrentTime = IO UTCTime
Time.getCurrentTime
  getPOSIXTime :: IO POSIXTime
getPOSIXTime = IO POSIXTime
Time.getPOSIXTime

instance MonadNow m => MonadNow (ExceptT e m) where
  getCurrentTime :: ExceptT e m UTCTime
getCurrentTime = m UTCTime -> ExceptT e m UTCTime
forall (t :: (* -> *) -> * -> *) (m :: * -> *) a.
(MonadTrans t, Monad m) =>
m a -> t m a
lift m UTCTime
forall (m :: * -> *). MonadNow m => m UTCTime
getCurrentTime
  getPOSIXTime :: ExceptT e m POSIXTime
getPOSIXTime = m POSIXTime -> ExceptT e m POSIXTime
forall (t :: (* -> *) -> * -> *) (m :: * -> *) a.
(MonadTrans t, Monad m) =>
m a -> t m a
lift m POSIXTime
forall (m :: * -> *). MonadNow m => m POSIXTime
getPOSIXTime

instance MonadNow m => MonadNow (LoggingT m) where
  getCurrentTime :: LoggingT m UTCTime
getCurrentTime = m UTCTime -> LoggingT m UTCTime
forall (t :: (* -> *) -> * -> *) (m :: * -> *) a.
(MonadTrans t, Monad m) =>
m a -> t m a
lift m UTCTime
forall (m :: * -> *). MonadNow m => m UTCTime
getCurrentTime
  getPOSIXTime :: LoggingT m POSIXTime
getPOSIXTime = m POSIXTime -> LoggingT m POSIXTime
forall (t :: (* -> *) -> * -> *) (m :: * -> *) a.
(MonadTrans t, Monad m) =>
m a -> t m a
lift m POSIXTime
forall (m :: * -> *). MonadNow m => m POSIXTime
getPOSIXTime

instance MonadNow m => MonadNow (ReaderT r m) where
  getCurrentTime :: ReaderT r m UTCTime
getCurrentTime = m UTCTime -> ReaderT r m UTCTime
forall (t :: (* -> *) -> * -> *) (m :: * -> *) a.
(MonadTrans t, Monad m) =>
m a -> t m a
lift m UTCTime
forall (m :: * -> *). MonadNow m => m UTCTime
getCurrentTime
  getPOSIXTime :: ReaderT r m POSIXTime
getPOSIXTime = m POSIXTime -> ReaderT r m POSIXTime
forall (t :: (* -> *) -> * -> *) (m :: * -> *) a.
(MonadTrans t, Monad m) =>
m a -> t m a
lift m POSIXTime
forall (m :: * -> *). MonadNow m => m POSIXTime
getPOSIXTime