Skip to content

buzden/idris2-time-for-sleep

Folders and files

NameName
Last commit message
Last commit date

Latest commit

 

History

26 Commits
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 

Repository files navigation

Time (for sleep)

Some data type for time and finite time duration, plus an interface for getting the current time and sleeping for some time.

Idea behind

The main reason why this library happened is to provide a way of overloadable timed sleeping with potential for non-blocking sleeping for monads that support this.

Time data

Time cat be represented with two data types: Time and FinDuration.

One type is for an absolute time, the other is for a distance between two points in time.

There are common operations of creation and querying to these data types and they are put into an interface TimeValue. For external conversions (including creation with integer literals) an UntypedTime type is used.

For example:

timeToWait : FinDuration
timeToWait = 100.millis

hms : TimeValue v => v -> String
hms v = "\{show v.hoursComponent}:\{show v.minutesComponent}:\{show v.secondsComponent}.\{show v.millisComponent}"

conv : UntypedTime
conv = 6.days.asSeconds

Durations can be added using the semigroup's operation <+> and they can be multiplied and divided by a natural number. Underlying time value is discrete, so beware of rounding when dividing.

timeToWait' : FinDuration
timeToWait' = timeToWait <+> 12.seconds

twiceAsLong : FinDuration
twiceAsLong = 2 * timeToWait'

aThird : FinDuration
aThird = timeToWait / 3

Also, duration can be got as a difference between two time points (an absolute value), and time can be shifted using the duration.

shiftByTwoSec : Time -> Time
shiftByTwoSec t = t + 2.seconds

passedTime : (start, current : Time) -> FinDuration
passedTime start current = current - start

Interpolation

Interpolation interface is implemented for FinDuration data type. So, you can use it for printing meaningful text, say

errorMessage : FinDuration -> String
errorMessage duration = "Error occurred after \{duration}"

There is a default interpolation which prints period in words, but tries to be short. Also, some non-default ones also exist, e.g.

log : FinDuration -> (msg : String) -> IO ()
log d msg = do
  let _ = ISO8601
  putStrLn "\{d}: \{msg}"

Then call like

log (3.minutes <+> 5.seconds) "start"

would print something like

PT3M5S: start

Currently, several interpolation forms exist:

  • the default, Wrds: 3 min 5 sec
  • Words: 3 minutes, 5 seconds
  • Semicoloned: 00:03:05
  • ISO8601 (for periods): PT3M5S

Interfaces

For getting the current time in a context m, there is an interface Timed m which provides a function currentTime.

sinceStored : MonadState Time m => Timed m => m FinDuration
sinceStored = pure $ !currentTime - !get

There is also an interface allowing to sleep for the given duration or to sleep till the desired moment of time:

printMetered : CanSleep m => HasIO m => FinDuration -> String -> m ()
printMetered d str = do
  putStrLn str
  sleepFor d
  putStrLn str
  sleepFor d
  putStrLn str

About

Some time type + interfaces for getting time and sleeping

Resources

License

Stars

Watchers

Forks

Releases

No releases published

Packages

No packages published

Languages