{-# LANGUAGE UndecidableInstances #-} {-# OPTIONS_GHC -Wno-orphans #-} -- | Time measurement via 'MonadTime'. module Effectful.Time ( -- * Effect Time (..) , MonadTime (..) -- ** Handlers , runTime , runFrozenTime ) where import Control.Monad.IO.Class import Control.Monad.Time import Data.Time import Effectful import Effectful.Dispatch.Dynamic import GHC.Clock (getMonotonicTime) -- | Provide the ability to use the 'MonadTime' instance of 'Eff'. data Time :: Effect where CurrentTime :: Time m UTCTime MonotonicTime :: Time m Double type instance DispatchOf Time = Dynamic -- | Run a 'Time' effect via 'IO'. runTime :: IOE :> es => Eff (Time : es) a -> Eff es a runTime = interpret $ \_ -> \case CurrentTime -> liftIO getCurrentTime MonotonicTime -> liftIO getMonotonicTime -- | Run a 'Time' effect with a frozen value of the 'CurrentTime' operation. -- -- /Note:/ the 'MonotonicTime' operation works the same way as in 'runTime'. runFrozenTime :: IOE :> es => UTCTime -> Eff (Time : es) a -> Eff es a runFrozenTime time = interpret $ \_ -> \case CurrentTime -> pure time MonotonicTime -> liftIO getMonotonicTime ---------------------------------------- -- Orphan instance instance Time :> es => MonadTime (Eff es) where currentTime = send CurrentTime monotonicTime = send MonotonicTime