time-units (empty) → 1.0.0
raw patch · 4 files changed
+293/−0 lines, 4 filesdep +basesetup-changed
Dependencies added: base
Files
- Data/Time/Units.hs +237/−0
- LICENSE +25/−0
- Setup.hs +2/−0
- time-units.cabal +29/−0
+ Data/Time/Units.hs view
@@ -0,0 +1,237 @@+{-# LANGUAGE DeriveDataTypeable #-}+{-# LANGUAGE GeneralizedNewtypeDeriving #-}+-- |This module defines types for many useful time periods, as well as+-- mechanisms for converting between them.+module Data.Time.Units(+ TimeUnit(..)+ , Attosecond+ , Femtosecond+ , Picosecond+ , Nanosecond+ , Microsecond+ , Millisecond+ , Second+ , Minute+ , Hour+ , Day+ , Week+ , Fortnight+ , addTime+ , subTime+ , convertUnit+ , getCPUTimeWithUnit+ )+ where++import Data.Ix(Ix)+import Data.Data(Data)+import Data.List(isPrefixOf)+import Data.Typeable(Typeable)+import System.CPUTime++-- |A generic class that describes all the units of time. We use microseconds+-- here because that tends to be what GHC (at least) tends to use as its +-- system-level minimum tick size.+class TimeUnit a where+ -- |Converts the given unit of time into microseconds, flooring the value+ -- if it comes to a fractional number of microseconds. (In other words:+ -- be careful, you may lose precision!)+ toMicroseconds :: a -> Integer+ -- |Converts the given number of microseconds into the unit of time, flooring+ -- the value if it comes to a fraction number of the given unit. (In other+ -- words: be careful, you may lose precision!)+ fromMicroseconds :: Integer -> a++-- |Add two times together to get a useful third time unit. As per usual,+-- you'll want to make sure that you are careful regarding precision. This+-- function goes through microseconds as an intermediary form.+addTime :: (TimeUnit a, TimeUnit b, TimeUnit c) => a -> b -> c+addTime x y = fromMicroseconds (toMicroseconds x + toMicroseconds y)++-- |Subtract the second time from the first, to get a useful third time unit.+-- As per usual, you'll want to make sure that you are careful regarding+-- precision. This function goes through microseconds as an intermediary form.+subTime :: (TimeUnit a, TimeUnit b, TimeUnit c) => a -> b -> c+subTime x y = fromMicroseconds (toMicroseconds x - toMicroseconds y)++-- |Convert one time unit to another. Note that if you move from a smaller+-- time unit to a larger one, or between two time units smaller than a+-- microsecond, you will lose precision.+convertUnit :: (TimeUnit a, TimeUnit b) => a -> b+convertUnit = fromMicroseconds . toMicroseconds++-- |Get the current CPU time in your favorite units. This is probably not+-- very useful in itself, but is likely useful for comparison purposes ...+getCPUTimeWithUnit :: TimeUnit a => IO a+getCPUTimeWithUnit =+ (fromMicroseconds . toMicroseconds . Picosecond) `fmap` getCPUTime++--++newtype Attosecond = Attosecond Integer+ deriving (Enum,Eq,Integral,Data,Num,Ord,Real,Ix,Typeable)++instance TimeUnit Attosecond where+ toMicroseconds (Attosecond x) = x `div` (10 ^ 12)+ fromMicroseconds x = Attosecond (x * (10 ^ 12))+instance Show Attosecond where+ show (Attosecond x) = show x ++ "as"+instance Read Attosecond where+ readsPrec = readUnit Attosecond "as"++readUnit :: (Integer -> a) -> String ->+ Int -> String ->+ [(a, String)]+readUnit builder unitstr prec str = processItems builder (readsPrec prec str)+ where+ processItems :: (Integer -> a) -> [(Integer,String)] -> [(a,String)]+ processItems builder [] = []+ processItems builder ((a,s):rest)+ | unitstr `isPrefixOf` s =+ (builder a, drop (length unitstr) s) : (processItems builder rest)+ | otherwise =+ processItems builder rest++--++newtype Femtosecond = Femtosecond Integer+ deriving (Enum,Eq,Integral,Data,Num,Ord,Real,Ix,Typeable)++instance TimeUnit Femtosecond where+ toMicroseconds (Femtosecond x) = x `div` (10 ^ 9)+ fromMicroseconds x = Femtosecond (x * (10 ^ 9))+instance Show Femtosecond where+ show (Femtosecond x) = show x ++ "fs"+instance Read Femtosecond where+ readsPrec = readUnit Femtosecond "fs"++--++newtype Picosecond = Picosecond Integer+ deriving (Enum,Eq,Integral,Data,Num,Ord,Real,Ix,Typeable)++instance TimeUnit Picosecond where+ toMicroseconds (Picosecond x) = x `div` (10 ^ 6)+ fromMicroseconds x = Picosecond (x * (10 ^ 6))+instance Show Picosecond where+ show (Picosecond x) = show x ++ "ps"+instance Read Picosecond where+ readsPrec = readUnit Picosecond "ps"++--++newtype Nanosecond = Nanosecond Integer+ deriving (Enum,Eq,Integral,Data,Num,Ord,Real,Ix,Typeable)++instance TimeUnit Nanosecond where+ toMicroseconds (Nanosecond x) = x `div` (10 ^ 3)+ fromMicroseconds x = Nanosecond (x * (10 ^ 3))+instance Show Nanosecond where+ show (Nanosecond x) = show x ++ "ns"+instance Read Nanosecond where+ readsPrec = readUnit Nanosecond "ns"++--++newtype Microsecond = Microsecond Integer+ deriving (Enum,Eq,Integral,Data,Num,Ord,Real,Ix,Typeable)++instance TimeUnit Microsecond where+ toMicroseconds (Microsecond x) = x+ fromMicroseconds x = Microsecond x+instance Show Microsecond where+ show (Microsecond x) = show x ++ "µs"+instance Read Microsecond where+ readsPrec = readUnit Microsecond "µs"++--++newtype Millisecond = Millisecond Integer+ deriving (Enum,Eq,Integral,Data,Num,Ord,Real,Ix,Typeable)++instance TimeUnit Millisecond where+ toMicroseconds (Millisecond x) = x * (10 ^ 3)+ fromMicroseconds x = Millisecond (x `div` (10 ^ 3))+instance Show Millisecond where+ show (Millisecond x) = show x ++ "ms"+instance Read Millisecond where+ readsPrec = readUnit Millisecond "ms"++--++newtype Second = Second Integer+ deriving (Enum,Eq,Integral,Data,Num,Ord,Real,Ix,Typeable)++instance TimeUnit Second where+ toMicroseconds (Second x) = x * (10 ^ 6)+ fromMicroseconds x = Second (x `div` (10 ^ 6))+instance Show Second where+ show (Second x) = show x ++ "s"+instance Read Second where+ readsPrec = readUnit Second "s"++--++newtype Minute = Minute Integer+ deriving (Enum,Eq,Integral,Data,Num,Ord,Real,Ix,Typeable)++instance TimeUnit Minute where+ toMicroseconds (Minute x) = x * (toMicroseconds $ Second 60)+ fromMicroseconds x = Minute (x `div` (toMicroseconds $ Second 60))+instance Show Minute where+ show (Minute x) = show x ++ "m"+instance Read Minute where+ readsPrec = readUnit Minute "m"++--++newtype Hour = Hour Integer+ deriving (Enum,Eq,Integral,Data,Num,Ord,Real,Ix,Typeable)++instance TimeUnit Hour where+ toMicroseconds (Hour x) = x * (toMicroseconds $ Minute 60)+ fromMicroseconds x = Hour (x `div` (toMicroseconds $ Minute 60))+instance Show Hour where+ show (Hour x) = show x ++ "h"+instance Read Hour where+ readsPrec = readUnit Hour "h"++--++newtype Day = Day Integer+ deriving (Enum,Eq,Integral,Data,Num,Ord,Real,Ix,Typeable)++instance TimeUnit Day where+ toMicroseconds (Day x) = x * (toMicroseconds $ Hour 24)+ fromMicroseconds x = Day (x `div` (toMicroseconds $ Hour 24))+instance Show Day where+ show (Day x) = show x ++ "d"+instance Read Day where+ readsPrec = readUnit Day "d"++--++newtype Week = Week Integer+ deriving (Enum,Eq,Integral,Data,Num,Ord,Real,Ix,Typeable)++instance TimeUnit Week where+ toMicroseconds (Week x) = x * (toMicroseconds $ Day 7)+ fromMicroseconds x = Week (x `div` (toMicroseconds $ Day 7))+instance Show Week where+ show (Week x) = show x ++ "w"+instance Read Week where+ readsPrec = readUnit Week "w"++--++newtype Fortnight = Fortnight Integer+ deriving (Enum,Eq,Integral,Data,Num,Ord,Real,Ix,Typeable)++instance TimeUnit Fortnight where+ toMicroseconds (Fortnight x) = x * (toMicroseconds $ Week 2)+ fromMicroseconds x = Fortnight (x `div` (toMicroseconds $ Week 2))+instance Show Fortnight where+ show (Fortnight x) = show x ++ "fn"+instance Read Fortnight where+ readsPrec = readUnit Fortnight "fn"+
+ LICENSE view
@@ -0,0 +1,25 @@+Copyright (c) 2011 Adam Wick+All rights reserved.++Redistribution and use in source and binary forms, with or without+modification, are permitted provided that the following conditions are met:++ * Redistributions of source code must retain the above copyright notice, this+ list of conditions and the following disclaimer.+ * Redistributions in binary form must reproduce the above copyright notice,+ this list of conditions and the following disclaimer in the documentation+ and/or other materials provided with the distribution. + * Neither the name Adam Wick nor the names of any contributors+ may be used to endorse or promote products derived from this software+ without specific prior written permission.++THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND+ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED+WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE+DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE+FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL+DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR+SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER+CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,+OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE+OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ Setup.hs view
@@ -0,0 +1,2 @@+import Distribution.Simple+main = defaultMain
+ time-units.cabal view
@@ -0,0 +1,29 @@+Name: time-units+Version: 1.0.0+Build-Type: Simple+Cabal-Version: >= 1.6+License: BSD3+License-File: LICENSE+Author: Adam Wick <awick@uhsure.com>+Maintainer: Adam Wick <awick@uhusre.com>+Homepage: http://github.com/acw/time-units+Category: Data+Synopsis: A basic library for defining units of time as types.++Description:+ In many cases, it is useful (either for error checking or documentation+ reasons) to define input and output types as having a particular unit of+ time. In addition, by creating a type class defining type units, this+ library should make it easier to separate the units of time the developer+ wants to think in versus the units of time the library author wants to+ think in.++Library+ Build-Depends: base >= 4.0 && < 5.0+ Exposed-Modules: Data.Time.Units+ Extensions: DeriveDataTypeable,GeneralizedNewtypeDeriving++source-repository head+ type: git+ location: http://github.com/acw/time-units+