{-# LANGUAGE CPP, FlexibleContexts, FlexibleInstances, UndecidableInstances #-}

#if __GLASGOW_HASKELL__ < 710
{-# LANGUAGE OverlappingInstances #-}
#endif

module Control.Monad.Time (MonadTime(..)) where

import Control.Monad.Trans
import Data.Time
import GHC.Clock (getMonotonicTime)

-- | Class of monads which make it possible to measure time.
class Monad m => MonadTime m where
  currentTime :: m UTCTime
  monotonicTime :: m Double

-- | Base instance for IO.
instance MonadTime IO where
  currentTime :: IO UTCTime
currentTime = IO UTCTime
getCurrentTime
  monotonicTime :: IO Double
monotonicTime = IO Double
getMonotonicTime

-- | Generic, overlapping instance.
instance {-# OVERLAPPABLE #-} (
    MonadTime m
  , MonadTrans t
  , Monad (t m)
  ) => MonadTime (t m) where
    currentTime :: t m UTCTime
currentTime = m UTCTime -> t m UTCTime
forall (t :: (* -> *) -> * -> *) (m :: * -> *) a.
(MonadTrans t, Monad m) =>
m a -> t m a
lift m UTCTime
forall (m :: * -> *). MonadTime m => m UTCTime
currentTime
    monotonicTime :: t m Double
monotonicTime = m Double -> t m Double
forall (t :: (* -> *) -> * -> *) (m :: * -> *) a.
(MonadTrans t, Monad m) =>
m a -> t m a
lift m Double
forall (m :: * -> *). MonadTime m => m Double
monotonicTime