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

Safe HaskellNone
LanguageHaskell2010

Units.Simple

Contents

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 details

Defined in Units.Simple.Quantity

Methods

fmap :: (a -> b) -> Quantity us a -> Quantity us b #

(<$) :: a -> Quantity us b -> Quantity us a #

Applicative (Quantity us) Source # 
Instance details

Defined in Units.Simple.Quantity

Methods

pure :: 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 details

Defined in Units.Simple.Quantity

Methods

succ :: 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 details

Defined 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 details

Defined in Units.Simple.Quantity

Methods

pi :: 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 details

Defined 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 details

Defined in Units.Simple.Quantity

Methods

quot :: 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 details

Defined 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 details

Defined in Units.Simple.Quantity

Methods

compare :: 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 details

Defined in Units.Simple.Quantity

Methods

toRational :: Quantity us a -> Rational #

(KnownSymbol (UnitRepr us), Show a) => Show (Quantity us a) Source # 
Instance details

Defined in Units.Simple.Quantity

Methods

showsPrec :: 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 #

Instances
Eq Unit Source # 
Instance details

Defined in Units.Simple.Unit

Methods

(==) :: Unit -> Unit -> Bool #

(/=) :: Unit -> Unit -> Bool #

Ord Unit Source # 
Instance details

Defined in Units.Simple.Unit

Methods

compare :: Unit -> Unit -> Ordering #

(<) :: Unit -> Unit -> Bool #

(<=) :: Unit -> Unit -> Bool #

(>) :: Unit -> Unit -> Bool #

(>=) :: Unit -> Unit -> Bool #

max :: Unit -> Unit -> Unit #

min :: Unit -> Unit -> Unit #

Show Unit Source # 
Instance details

Defined in Units.Simple.Unit

Methods

showsPrec :: 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

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

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 #