freer-simple-time-0.1.0.0: src/Control/Monad/Freer/Time.hs
{-|
Module : Control.Monad.Freer.Time
Description : Effect for working with the current time
Copyright : (c) Ben Weitzman 2018
License : MIT
Maintainer : ben@costarastrolgoy.com
Stability : experimental
Portability : POSIX
-}
module Control.Monad.Freer.Time
(currentTime
,Time
,runTime
,runTimeAt
,runInstantaneously
)
where
import Control.Monad.Freer
import Data.Time
-- | The 'Time' effect gives an interface to accessing the current time
data Time a where
CurrentTime :: Time UTCTime
-- | Get the current time
currentTime :: (Member Time r) => Eff r UTCTime
currentTime = send CurrentTime
-- | Use 'IO' to handle getting the current time
runTime :: Member IO r => Eff (Time ': r) a -> Eff r a
runTime = interpret $ \CurrentTime -> send getCurrentTime
-- | Use a given time that the program will consider "current"
runTimeAt :: UTCTime -> Eff (Time ': r) a -> Eff r a
runTimeAt instant = interpret $ \CurrentTime -> return instant
-- | Use 'IO' get the current time, but make the program think that
-- everything is happening at the same instant. All calls to 'currentTime'
-- will return the same, present-ish 'UTCTime'
runInstantaneously :: (Member IO r) => Eff (Time ': r) a -> Eff r a
runInstantaneously eff = do
now <- runTime currentTime
runTimeAt now eff