polysemy-time: A Polysemy effect for time

[ library, time ] [ Propose Tags ]
Versions [RSS],,,,,,,,,,,,,,,,,,,,,,
Change log changelog.md
Dependencies aeson (>= && <2.3), base (>= && <4.20), incipit-core (>= && <0.7), template-haskell (>= && <2.22), time (>=1.12.2 && <1.13), torsor (>=0.1 && <0.2) [details]
License BSD-2-Clause-Patent
Copyright 2023 Torsten Schmits
Author Torsten Schmits
Maintainer hackage@tryp.io
Category Time
Home page https://github.com/tek/polysemy-time#readme
Bug tracker https://github.com/tek/polysemy-time/issues
Source repo head: git clone https://github.com/tek/polysemy-time
Uploaded by tek at 2024-05-26T15:44:59Z
Reverse Dependencies 13 direct, 17 indirect [details]
Downloads 3288 total (131 in the last 30 days)
Rating (no votes yet) [estimated by Bayesian average]
Your Rating
  • λ
  • λ
  • λ
Status Docs uploaded by user
Build status unknown [no reports yet]

Readme for polysemy-time-

[back to package description]


This Haskell library provides a Polysemy effect for accessing the current time and date, and interpreters using time.


import Data.Time (UTCTime)
import Polysemy (Members, runM)
import qualified Polysemy.Time as Time
import Polysemy.Time (MilliSeconds(MilliSeconds), Seconds(Seconds), Time, interpretTimeGhcAt, mkDatetime, year)

prog ::
  Ord t =>
  Members [Time t d, Embed IO] r =>
  Sem r ()
prog = do
  time1 <- Time.now
  Time.sleep (MilliSeconds 10)
  time2 <- Time.now
  print (time1 < time2)
  -- True

testTime :: UTCTime
testTime =
  mkDatetime 1845 12 31 23 59 59

main :: IO ()
main =
  runM do
    interpretTimeGhcAt testTime do
      Time.sleep (Seconds 1)
      time <- Time.now
      print (year time)
      -- Years { unYear = 1846 }


The only effect contained in polysemy-time is:

data Time (time :: Type) (date :: Type) :: Effect where
  Now :: Time t d m t
  Today :: Time t d m d
  Sleep :: TimeUnit u => u -> Time t d m ()
  SetTime :: t -> Time t d m ()
  SetDate :: d -> Time t d m ()

Interpreters are provided for the time library bundled with GHC. The project polysemy-chronos contains an alternative implementation for chronos.

The type parameters correspond to the representations in the implementation, like Data.Time.UTCTime/Chronos.Time and Data.Time.Day/Chronos.Date.

SetTime and SetDate only have meaning when you're running in a testing context.

A special interpreter variant suffixed with At exists for both implementations, with which the current time is overridden to be relative to the supplied override fixed at the start of interpretation. This is useful for testing.


A set of newtypes representing timespans are provided for convenience. Internally, the interpreters operate on NanoSeconds.

The class TimeUnit ties those types, and the types Chronos.Timespan and Data.Time.DiffTime, together to allow you to convert between them with the function convert:

>>> convert (picosecondsToDiffTime 50000000) :: MicroSeconds
MicroSeconds {unMicroSeconds = 50}

>>> convert (Days 5) :: Timespan
Timespan {getTimespan = 432000000000000}

The class Calendar allows you to construct UTCTime and Chronos.Datetime from integers with the function mkDatetime, as demonstrated in the first example.