packages feed

time-interval 0.1.0.0 → 0.1.1

raw patch · 4 files changed

+115/−96 lines, 4 filesdep ~time-units

Dependency ranges changed: time-units

Files

− NEWS
@@ -1,23 +0,0 @@-This file lists the user-visible interesting changes between releases. For a-full list of changes to the source, see the ChangeLog.----time-interval 0.1.0.0 -- 2015-09-10-===================================--General, build and documentation changes:--* (This is the first release, so everything is new)--New APIs, features and enhancements:--* (This is the first release, so everything is a new feature)--Bug fixes:--* (This is just the first release)--Dependency changes:--* (This is the first release)
+ NEWS.md view
@@ -0,0 +1,48 @@+This file lists the user-visible interesting changes between releases. For a+full list of changes to the source, see the ChangeLog.++++time-interval 0.1.1      2016-05-30+===================================++General, build and documentation changes:++* Add stack.yaml for building with stack and latest stackage LTS+* Better docs, new usage scenario as the previous one was invalid++New APIs, features and enhancements:++* Several new conversion functions, and `time` is deprecated now+* `TimeInterval` has `Num`, `Integral` and `Real` instances++Bug fixes:++* (None)++Dependency changes:++* (None)++++++time-interval 0.1.0.0 -- 2015-09-10+===================================++General, build and documentation changes:++* (This is the first release, so everything is new)++New APIs, features and enhancements:++* (This is the first release, so everything is a new feature)++Bug fixes:++* (This is just the first release)++Dependency changes:++* (This is the first release)
src/Data/Time/Interval.hs view
@@ -1,6 +1,6 @@ {- This file is part of time-interval.  -- - Written in 2015 by fr33domlover <fr33domlover@rel4tion.org>.+ - Written in 2015, 2016 by fr33domlover <fr33domlover@riseup.net>.  -  - ♡ Copying is an act of love. Please copy, reuse and share.  -@@ -13,92 +13,85 @@  - <http://creativecommons.org/publicdomain/zero/1.0/>.  -} --- | Suppose you have a program which periodically reloads state and saves some--- logs, and you'd like the intervals for these periodic actions to be--- expressed using time units, and abstract away the internal representation--- until the site of actual use. Your code may look like this:+-- To derive Enum instance for TimeInterval+{-# LANGUAGE GeneralizedNewtypeDeriving #-}++-- | Suppose you have 'Settings' type, and one of its fields specifies an+-- amount of time. Suppose you want to use "Data.Time.Units" for that, because+-- it abstracts away the direct use or 'Int' or 'Integer'. Using 'TimeUnit'+-- directly would require to add the concrete time unit type as a type+-- parameter of 'Settings' (or use GHC type related extensions): ----- > data AppState tr ts = AppState--- >     { userName       :: String--- >     , newMessages    :: [String]--- >     , reloadInterval :: tr--- >     , saveInterval   :: ts+-- > data Settings t = Settings+-- >     { x :: Int+-- >     , y :: Text+-- >     , z :: t -- >     }--- >--- > type App tr ts = StateT (AppState tr ts) IO--- >--- > setReloadInterval :: TimeUnit t => t -> App ()--- > setReloadInterval new = modify $ \ s -> s { reloadInterval = new }--- >--- > syncStateWithFiles :: (TimeUnit tr, TimeUnit ts) => App tr ts ()--- > syncStateWithFiles = do--- >     reloadMicrosec <- liftM toMicroseconds $ gets reloadInterval--- >     saveMicrosec <- liftM toMicroseconds $ gets saveInterval--- >     {- ... use the values ... -} ----- And usage looks like this:------ > setReloadInterval (5 :: Second)------ So every time you add, change or remove a time field, all your type--- signatures need to be updated and all your @App@ actions, even unrelated to--- those times, are stuck with time type parameters in their type signatures.------ An easy and common approach to avoid all the mess is to store the time as an--- integer, i.e. applying 'toMicroseconds' when setting the value rather than--- when using it. That makes things much easier, but then your type (and your--- API) expose the time directly as a number of microseconds, and people end up--- writing things like @1000 * 1000 * 60 * 5@ to say "5 minuts". It's also an--- internal technical detail there's no reason to expose, and should be--- possible to change without breaking anything - e.g. what if your scheduling--- tool one day moves to a higher precision than microseconds? Your high-level--- API would ideally not let that change float all the way up.------ Here's how things can work when using this library.+-- And any use of @z@ would require to specify the @TimeUnit t =>@ constraint.+-- If you want to add more settings fields later which are time durations,+-- you'll need to add more type variables which may break code which uses the+-- 'Settings' type. ----- > data AppState = AppState--- >     { userName       :: String--- >     , newMessages    :: [String]--- >     , reloadInterval :: TimeInterval--- >     , saveInterval   :: TimeInterval+-- > data Settings t1 t2 t3 = Settings+-- >     { x :: Int+-- >     , y :: Text+-- >     , z :: t1+-- >     , u :: t2+-- >     , v :: t3 -- >     }--- >--- > type App = StateT AppState IO--- >--- > setReloadInterval :: TimeUnit t => t -> App ()--- > setReloadInterval new = modify $ \ s -> s { reloadInterval = time new }--- >--- > syncStateWithFiles :: App ()--- > syncStateWithFiles = do--- >     reloadMicrosec <- liftM microseconds $ gets reloadInterval--- >     saveMicrosec <- liftM microseconds $ gets saveInterval--- >     {- ... use the values ... -} ----- And usage looks the same:------ > setReloadInterval (5 :: Second)+-- This package provides something between 'Int' and 'TimeUnit'. A concrete+-- type for specifying time durations, which both hide the integers and avoid+-- the type variables: ----- Also, even if you let the user use the 'time' function in their code, e.g.--- like this:+-- > data Settings = Settings+-- >     { x :: Int+-- >     , y :: Text+-- >     , z :: TimeInterval+-- >     , u :: TimeInterval+-- >     , v :: TimeInterval+-- >     } ----- > setReloadInterval $ time (5 :: Second)+-- There is nothing magical here, this is simply a convenience package for+-- people who encounter this issue in their code. ----- ... you stil get the advantages from both worlds.+-- Note that currently 'TimeInterval' stores time as microseconds internally.+-- This may be a problem if you plan to work with smaller intervals+-- (nanoseconds, picoseconds, etc.). If you have such needs, please contact the+-- maintainer to discuss a solution. module Data.Time.Interval     ( TimeInterval ()+    , fromTimeUnit+    , toTimeUnit+    , toMicroUnit     , time     , microseconds     ) where -import Data.Time.Units (TimeUnit (..))+import Data.Time.Units  -- | A time duration.-newtype TimeInterval = TimeInterval Integer deriving (Eq, Ord, Show)+newtype TimeInterval = TimeInterval Integer+    deriving (Enum, Eq, Integral, Ord, Num, Real, Show)  -- | Convert a time value expressed in a some time unit into a 'TimeInterval'.+fromTimeUnit :: TimeUnit t => t -> TimeInterval+fromTimeUnit = TimeInterval . toMicroseconds++-- | Convert a 'TimeInterval' to a 'TimeUnit' instance.+toTimeUnit :: TimeUnit t => TimeInterval -> t+toTimeUnit = fromMicroseconds . microseconds++-- | Specialized 'toTimeUnit' for converting to 'Microsecond' units.+toMicroUnit :: TimeInterval -> Microsecond+toMicroUnit = toTimeUnit++-- | Deprecated alias of 'fromTimeUnit'. time :: TimeUnit t => t -> TimeInterval-time = TimeInterval . toMicroseconds+time = fromTimeUnit+{-# DEPRECATED time "Use 'fromTimeUnit' instead" #-}  -- | Express a 'TimeInterval' in microseconds. microseconds :: TimeInterval -> Integer
time-interval.cabal view
@@ -1,10 +1,11 @@ name:                time-interval-version:             0.1.0.0+version:             0.1.1 synopsis:            Use a time unit class, but hold a concrete time type. description:   Two common ways to represent and hold short time intervals seem to be:   .   1. Hold time in microseconds as an 'Int' or 'Integer'+  .   2. Use time units abstraction, e.g. see the time-units package   .   While the second option is a great abstraction to use in APIs, it works for@@ -30,28 +31,28 @@   you'll probably want this library for short time lengths (at most seconds,   minutes, hours). For calendar based and related time functions and types, see   the @time@ package.-homepage:            http://rel4tion.org/projects/time-interval/-bug-reports:         http://rel4tion.org/projects/time-interval/tickets/+homepage:            http://hub.darcs.net/fr33domlover/time-interval+bug-reports:         mailto:fr33domlover@riseup.net license:             PublicDomain license-file:        COPYING author:              fr33domlover maintainer:          fr33domlover@riseup.net copyright:           ♡ Copying is an act of love. Please copy, reuse and share.-category:            Web+category:            Data build-type:          Simple-extra-source-files:  AUTHORS ChangeLog COPYING INSTALL NEWS README.md+extra-source-files:  AUTHORS ChangeLog COPYING INSTALL NEWS.md README.md cabal-version:       >=1.10  source-repository head   type:                darcs-  location:            http://dev.rel4tion.org/fr33domlover/time-interval+  location:            http://hub.darcs.net/fr33domlover/time-interval  library   exposed-modules:     Data.Time.Interval   -- other-modules:          -- other-extensions:       build-depends:       base       >=4.7 && <5-                     , time-units >=1+                     , time-units   hs-source-dirs:      src   default-language:    Haskell2010   ghc-options:         -Wall