polysemy-time: Polysemy effect for time

[ library, time ] [ Propose Tags ]

Please see the readme on Github at https://github.com/tek/polysemy-time

[Skip to Readme]
Versions [RSS] [faq],,,,
Change log changelog.md
Dependencies aeson (>=1.4 && <1.6), base (==4.*), composition (==1.0.*), containers, data-default (==0.7.*), either, polysemy (>=1.3 && <1.6), relude (>=0.7 && <1.1), string-interpolate (>=0.2 && <0.4), template-haskell, text, time, torsor (==0.1.*) [details]
License BSD-2-Clause-Patent
Copyright 2020 Torsten Schmits
Author Torsten Schmits
Maintainer tek@tryp.io
Category Time
Uploaded by tek at 2021-04-06T19:03:58Z
Distributions NixOS:
Downloads 353 total (98 in the last 30 days)
Rating (no votes yet) [estimated by Bayesian average]
Your Rating
  • λ
  • λ
  • λ
Status Hackage Matrix CI
Docs uploaded by user
Build status unknown [no reports yet]


[Index] [Quick Jump]


Maintainer's Corner

For package maintainers and hackage trustees


Readme for polysemy-time-

[back to package description]


This Haskell library provides a Polysemy effect for accessing the current time and date and an implementation for time and chronos.


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

prog ::
  Ord t =>
  Member (Time t d) 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
    interpretTimeChronos prog
    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 :: *) (date :: *) :: 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 and 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.