{-| 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