simple-units-0.1.0.0: Simple arithmetic with SI units using type-checked dimensional analysis.

Units.Simple

Synopsis

# The Quantity type

data Quantity (us :: Units) a Source #

A numerical quantity with some associated unit. Units are not created directly with this constructor, but through the individual unit functions.

Examples:

>>> meter -- a unitary quantity associated to meters.
1 m
>>> 2.5*ampere -- constructing through literal arithmetic
2.5 A
>>> candela' 3.14 -- constructing through the unit constructors
3.14 cd
>>> :set -XDataKinds
>>> 2 :: Quantity (SingleUnit 'Second) Rational
2 % 1 s


Associated units are represented through a phantom parameter of the Units kind synonym. These are currently implemented as a type-level pair of lists representing the power to which each unit is raised. Units can be inspected through showUnits.

New constructors may be written by combining the provided ones, such as

>>> let newton = kilogram .* meter ./ (second .* second)
>>> 23*newton
23.0 kg*m/s^2

>>> let g = 6.67408e-11 * newton .* (meter .* meter) ./ (kilogram .* kilogram)
>>> g -- gravitational constant
6.67408e-11 m^3/kg*s^2
>>> let gravity m1 m2 r = g .* (m1 * kilogram) .* (m2 * kilogram) ./ (r*meter .* r*meter)
>>> let earth_mass = 5.972e24 * kilogram
>>> let mars_mass = 6.417e23 * kilogram
>>> let earth_radius = 6371e3 * meter
>>> let mars_radius = 3389.5e3 * meter
>>> let weight_on_earth mass = gravity mass earth_mass earth_radius
>>> let weight_on_mars mass = gravity mass mars_mass mars_radius
>>> weight_on_earth (80 * kilogram)
785.5719790179963 kg*m/s^2
>>> weight_on_mars (80 * kilogram)
298.22370259533704 kg*m/s^2
>>> fromQuantity $weight_on_mars 1 / (fromQuantity$ weight_on_earth 1)
0.3796261966575378

Instances
 Functor (Quantity us) Source # Instance detailsDefined in Units.Simple.Quantity Methodsfmap :: (a -> b) -> Quantity us a -> Quantity us b #(<\$) :: a -> Quantity us b -> Quantity us a # Source # Instance detailsDefined in Units.Simple.Quantity Methodspure :: a -> Quantity us a #(<*>) :: Quantity us (a -> b) -> Quantity us a -> Quantity us b #liftA2 :: (a -> b -> c) -> Quantity us a -> Quantity us b -> Quantity us c #(*>) :: Quantity us a -> Quantity us b -> Quantity us b #(<*) :: Quantity us a -> Quantity us b -> Quantity us a # Enum a => Enum (Quantity us a) Source # Instance detailsDefined in Units.Simple.Quantity Methodssucc :: Quantity us a -> Quantity us a #pred :: Quantity us a -> Quantity us a #toEnum :: Int -> Quantity us a #fromEnum :: Quantity us a -> Int #enumFrom :: Quantity us a -> [Quantity us a] #enumFromThen :: Quantity us a -> Quantity us a -> [Quantity us a] #enumFromTo :: Quantity us a -> Quantity us a -> [Quantity us a] #enumFromThenTo :: Quantity us a -> Quantity us a -> Quantity us a -> [Quantity us a] # Eq a => Eq (Quantity us a) Source # Instance detailsDefined in Units.Simple.Quantity Methods(==) :: Quantity us a -> Quantity us a -> Bool #(/=) :: Quantity us a -> Quantity us a -> Bool # Floating a => Floating (Quantity us a) Source # Instance detailsDefined in Units.Simple.Quantity Methodspi :: Quantity us a #exp :: Quantity us a -> Quantity us a #log :: Quantity us a -> Quantity us a #sqrt :: Quantity us a -> Quantity us a #(**) :: Quantity us a -> Quantity us a -> Quantity us a #logBase :: Quantity us a -> Quantity us a -> Quantity us a #sin :: Quantity us a -> Quantity us a #cos :: Quantity us a -> Quantity us a #tan :: Quantity us a -> Quantity us a #asin :: Quantity us a -> Quantity us a #acos :: Quantity us a -> Quantity us a #atan :: Quantity us a -> Quantity us a #sinh :: Quantity us a -> Quantity us a #cosh :: Quantity us a -> Quantity us a #tanh :: Quantity us a -> Quantity us a #asinh :: Quantity us a -> Quantity us a #acosh :: Quantity us a -> Quantity us a #atanh :: Quantity us a -> Quantity us a #log1p :: Quantity us a -> Quantity us a #expm1 :: Quantity us a -> Quantity us a #log1pexp :: Quantity us a -> Quantity us a #log1mexp :: Quantity us a -> Quantity us a # Fractional a => Fractional (Quantity us a) Source # Instance detailsDefined in Units.Simple.Quantity Methods(/) :: Quantity us a -> Quantity us a -> Quantity us a #recip :: Quantity us a -> Quantity us a #fromRational :: Rational -> Quantity us a # Integral a => Integral (Quantity us a) Source # Instance detailsDefined in Units.Simple.Quantity Methodsquot :: Quantity us a -> Quantity us a -> Quantity us a #rem :: Quantity us a -> Quantity us a -> Quantity us a #div :: Quantity us a -> Quantity us a -> Quantity us a #mod :: Quantity us a -> Quantity us a -> Quantity us a #quotRem :: Quantity us a -> Quantity us a -> (Quantity us a, Quantity us a) #divMod :: Quantity us a -> Quantity us a -> (Quantity us a, Quantity us a) #toInteger :: Quantity us a -> Integer # Num a => Num (Quantity us a) Source # Instance detailsDefined in Units.Simple.Quantity Methods(+) :: Quantity us a -> Quantity us a -> Quantity us a #(-) :: Quantity us a -> Quantity us a -> Quantity us a #(*) :: Quantity us a -> Quantity us a -> Quantity us a #negate :: Quantity us a -> Quantity us a #abs :: Quantity us a -> Quantity us a #signum :: Quantity us a -> Quantity us a #fromInteger :: Integer -> Quantity us a # Ord a => Ord (Quantity us a) Source # Instance detailsDefined in Units.Simple.Quantity Methodscompare :: Quantity us a -> Quantity us a -> Ordering #(<) :: Quantity us a -> Quantity us a -> Bool #(<=) :: Quantity us a -> Quantity us a -> Bool #(>) :: Quantity us a -> Quantity us a -> Bool #(>=) :: Quantity us a -> Quantity us a -> Bool #max :: Quantity us a -> Quantity us a -> Quantity us a #min :: Quantity us a -> Quantity us a -> Quantity us a # Real a => Real (Quantity us a) Source # Instance detailsDefined in Units.Simple.Quantity MethodstoRational :: Quantity us a -> Rational # (KnownSymbol (UnitRepr us), Show a) => Show (Quantity us a) Source # Instance detailsDefined in Units.Simple.Quantity MethodsshowsPrec :: Int -> Quantity us a -> ShowS #show :: Quantity us a -> String #showList :: [Quantity us a] -> ShowS #

fromQuantity :: Quantity us a -> a Source #

Unwraps a Quantity, losing all unit information

data Unit Source #

Constructors

 Meter Kilogram Second Ampere Kelvin Mole Candela
Instances
 Source # Instance detailsDefined in Units.Simple.Unit Methods(==) :: Unit -> Unit -> Bool #(/=) :: Unit -> Unit -> Bool # Source # Instance detailsDefined in Units.Simple.Unit Methodscompare :: Unit -> Unit -> Ordering #(<) :: Unit -> Unit -> Bool #(<=) :: Unit -> Unit -> Bool #(>) :: Unit -> Unit -> Bool #(>=) :: Unit -> Unit -> Bool #max :: Unit -> Unit -> Unit #min :: Unit -> Unit -> Unit # Source # Instance detailsDefined in Units.Simple.Unit MethodsshowsPrec :: Int -> Unit -> ShowS #show :: Unit -> String #showList :: [Unit] -> ShowS #

type Units = ([Unit'], [Unit']) Source #

type SingleUnit (u :: Unit) = '('['(u, 1)], '[]) Source #

type UnitRepr (us :: Units) = UnitRepr' (Eval (Fst us)) (Eval (Snd us)) Source #

showUnits :: forall us. KnownSymbol (UnitRepr us) => String Source #

A string representation of Units. Useful for debugging.

# Basic arithmetic with quantities

(.+) :: (SameUnits u1 u2, Num a) => Quantity u1 a -> Quantity u2 a -> Quantity u1 a infixl 5 Source #

Sums two quantities with the same units. Summing quantities with different units results in a type error.

Examples:

>>> 2*meter .+ 3*meter
5 m
>>> 2*meter .+ 1*second

<interactive>:16:1-19: error:
• Unit mismatch: m and s
• In the expression: 2 * meter .+ 1 * second
In an equation for ‘it’: it = 2 * meter .+ 1 * second


(.-) :: (SameUnits u1 u2, Num a) => Quantity u1 a -> Quantity u2 a -> Quantity u1 a infixl 5 Source #

Subtracts two quantities with the same units. Subtracting quantities with different units results in a type error.

Examples:

>>> let newton = kilogram .* meter ./ (second .* second)
>>> 10*newton - 2*newton
8.0 kg*m/s^2


(.*) :: Num a => Quantity us1 a -> Quantity us2 a -> Quantity (MergeUnits us1 us2) a infixl 6 Source #

Multiplies two quantities correctly merging their units.

Examples:

>>> meter .* meter
1 m^2
>>> let mps = meter ./ second
>>> 20*mps .* 60*second
1200.0 m


Important: Though Quantity a has a Num instance for convenience, it must not be used for anything other than interacting with literals, otherwise the units will not be correct:

>>> 2*meter * 3*meter -- note that (*) was used in place of (.*)
6 m
>>> 2*meter .* 3*meter -- this is the correct usage
6 m^2


(./) :: Fractional a => Quantity us1 a -> Quantity us2 a -> Quantity (MergeUnits us1 (Recip us2)) a infixl 6 Source #

Divides a quantity by another correctly merging their units.

Examples:

>>> let coulomb = second .* ampere
>>> 20*coulomb ./ 2*second
10.0 A


# Base SI Units

Smart constructors for quantities in all the base SI Units. The constructors are provided in both unitary (non-ticked) and function (ticked) forms.

Examples:

>>> 273.0*kelvin -- unitary form
273.0 K
>>> kelvin' 273.0 -- function form
273.0 K


A quantity with no associated dimension. Can be multiplied or divided by any other quantity, but can only be added to or subtracted from other adimensional quantities.

>>> 2*adim + 4*adim
6 <adimensional>
>>> adim .+ meter

<interactive>:79:1-13: error:
• Unit mismatch: <adimensional> and m
• In the expression: adim .+ meter
In an equation for ‘it’: it = adim .+ meter


adim' :: Num a => a -> Quantity Adimensional a Source #