{-# LANGUAGE DataKinds #-}
{-# LANGUAGE RankNTypes #-}
module Numeric.Units.Dimensional.SIUnits
(
metre, meter, gram, second, ampere, kelvin, mole, candela,
radian, steradian, hertz, newton, pascal, joule, watt, coulomb, volt, farad, ohm, siemens, weber, tesla, henry, lumen, lux,
degreeCelsius, fromDegreeCelsiusAbsolute, toDegreeCelsiusAbsolute,
becquerel, gray, sievert, katal,
minute, hour, day,
hectare, litre, liter, tonne, metricTon,
degree, arcminute, arcsecond,
degreeOfArc, minuteOfArc, secondOfArc,
astronomicalUnit,
deka, deca, hecto, kilo, mega, giga, tera, peta, exa, zetta, yotta,
deci, centi, milli, micro, nano, pico, femto, atto, zepto, yocto,
Prefix, applyPrefix, siPrefixes
)
where
import Data.Ratio
import Numeric.Units.Dimensional
import Numeric.Units.Dimensional.Quantities
import Numeric.Units.Dimensional.UnitNames (Prefix, siPrefixes)
import qualified Numeric.Units.Dimensional.UnitNames as N
import Numeric.Units.Dimensional.UnitNames.Internal (ucum, ucumMetric)
import qualified Numeric.Units.Dimensional.UnitNames.Internal as I
import Numeric.NumType.DK.Integers ( pos3 )
import Prelude ( Eq(..), ($), Num, Fractional, Floating, otherwise, error)
import qualified Prelude
applyMultiple :: (Num a) => Prefix -> Unit 'Metric d a -> Unit 'NonMetric d a
applyMultiple p u | denominator x == 1 = mkUnitZ n' (numerator x) u
| otherwise = error "Attempt to apply a submultiple prefix as a multiple."
where
n' = N.applyPrefix p (name u)
x = N.scaleFactor p
deka, deca, hecto, kilo, mega, giga, tera, peta, exa, zetta, yotta
:: Num a => Unit 'Metric d a -> Unit 'NonMetric d a
deka = applyMultiple I.deka
deca = deka
hecto = applyMultiple I.hecto
kilo = applyMultiple I.kilo
mega = applyMultiple I.mega
giga = applyMultiple I.giga
tera = applyMultiple I.tera
peta = applyMultiple I.peta
exa = applyMultiple I.exa
zetta = applyMultiple I.zetta
yotta = applyMultiple I.yotta
applyPrefix :: (Fractional a) => Prefix -> Unit 'Metric d a -> Unit 'NonMetric d a
applyPrefix p u = mkUnitQ n' x u
where
n' = N.applyPrefix p (name u)
x = N.scaleFactor p
deci, centi, milli, micro, nano, pico, femto, atto, zepto, yocto
:: Fractional a => Unit 'Metric d a -> Unit 'NonMetric d a
deci = applyPrefix I.deci
centi = applyPrefix I.centi
milli = applyPrefix I.milli
micro = applyPrefix I.micro
nano = applyPrefix I.nano
pico = applyPrefix I.pico
femto = applyPrefix I.femto
atto = applyPrefix I.atto
zepto = applyPrefix I.zepto
yocto = applyPrefix I.yocto
metre, meter :: Num a => Unit 'Metric DLength a
metre = mkUnitZ I.nMeter 1 siUnit
meter = metre
gram :: Fractional a => Unit 'Metric DMass a
gram = mkUnitQ I.nGram 1e-3 siUnit
second :: Num a => Unit 'Metric DTime a
second = mkUnitZ I.nSecond 1 siUnit
ampere :: Num a => Unit 'Metric DElectricCurrent a
ampere = mkUnitZ I.nAmpere 1 siUnit
kelvin :: Num a => Unit 'Metric DThermodynamicTemperature a
kelvin = mkUnitZ I.nKelvin 1 siUnit
mole :: Num a => Unit 'Metric DAmountOfSubstance a
mole = mkUnitZ I.nMole 1 siUnit
candela :: Num a => Unit 'Metric DLuminousIntensity a
candela = mkUnitZ I.nCandela 1 siUnit
radian :: Num a => Unit 'Metric DPlaneAngle a
radian = mkUnitZ (ucumMetric "rad" "rad" "radian") 1 siUnit
steradian :: Num a => Unit 'Metric DSolidAngle a
steradian = mkUnitZ (ucumMetric "sr" "sr" "steradian") 1 siUnit
hertz :: Num a => Unit 'Metric DFrequency a
hertz = mkUnitZ (ucumMetric "Hz" "Hz" "Hertz") 1 $ siUnit
newton :: Num a => Unit 'Metric DForce a
newton = mkUnitZ (ucumMetric "N" "N" "Newton") 1 $ siUnit
pascal :: Num a => Unit 'Metric DPressure a
pascal = mkUnitZ (ucumMetric "Pa" "Pa" "Pascal") 1 $ siUnit
joule :: Num a => Unit 'Metric DEnergy a
joule = mkUnitZ (ucumMetric "J" "J" "Joule") 1 $ siUnit
watt :: Num a => Unit 'Metric DPower a
watt = mkUnitZ (ucumMetric "W" "W" "Watt") 1 $ siUnit
coulomb :: Num a => Unit 'Metric DElectricCharge a
coulomb = mkUnitZ (ucumMetric "C" "C" "Coulomb") 1 $ siUnit
volt :: Num a => Unit 'Metric DElectricPotential a
volt = mkUnitZ (ucumMetric "V" "V" "Volt") 1 $ siUnit
farad :: Num a => Unit 'Metric DCapacitance a
farad = mkUnitZ (ucumMetric "F" "F" "Farad") 1 $ siUnit
ohm :: Num a => Unit 'Metric DElectricResistance a
ohm = mkUnitZ (ucumMetric "Ohm" "Ω" "Ohm") 1 $ siUnit
siemens :: Num a => Unit 'Metric DElectricConductance a
siemens = mkUnitZ (ucumMetric "S" "S" "Siemens") 1 $ siUnit
weber :: Num a => Unit 'Metric DMagneticFlux a
weber = mkUnitZ (ucumMetric "Wb" "Wb" "Weber") 1 $ siUnit
tesla :: Num a => Unit 'Metric DMagneticFluxDensity a
tesla = mkUnitZ (ucumMetric "T" "T" "Tesla") 1 $ siUnit
henry :: Num a => Unit 'Metric DInductance a
henry = mkUnitZ (ucumMetric "H" "H" "Henry") 1 $ siUnit
lumen :: Num a => Unit 'Metric DLuminousFlux a
lumen = mkUnitZ (ucumMetric "lm" "lm" "lumen") 1 $ siUnit
lux :: Num a => Unit 'Metric DIlluminance a
lux = mkUnitZ (ucumMetric "lx" "lx" "lux") 1 $ siUnit
degreeCelsius :: Num a => Unit 'Metric DCelsiusTemperature a
degreeCelsius = kelvin
fromDegreeCelsiusAbsolute :: Floating a => a -> ThermodynamicTemperature a
fromDegreeCelsiusAbsolute x = x *~ degreeCelsius + 273.15 *~ degreeCelsius
toDegreeCelsiusAbsolute :: Floating a => ThermodynamicTemperature a -> a
toDegreeCelsiusAbsolute x = (x - 273.15 *~ degreeCelsius) /~ degreeCelsius
becquerel :: Num a => Unit 'Metric DActivity a
becquerel = mkUnitZ (ucumMetric "Bq" "Bq" "Becquerel") 1 $ siUnit
gray :: Num a => Unit 'Metric DAbsorbedDose a
gray = mkUnitZ (ucumMetric "Gy" "Gy" "Gray") 1 $ siUnit
sievert :: Num a => Unit 'Metric DDoseEquivalent a
sievert = mkUnitZ (ucumMetric "Sv" "Sv" "Sievert") 1 $ siUnit
katal :: Num a => Unit 'Metric DCatalyticActivity a
katal = mkUnitZ (ucumMetric "kat" "kat" "katal") 1 $ siUnit
minute, hour, day :: Num a => Unit 'NonMetric DTime a
minute = mkUnitZ (ucum "min" "min" "minute") 60 $ second
hour = mkUnitZ (ucum "h" "h" "hour") 60 $ minute
day = mkUnitZ (ucum "d" "d" "day") 24 $ hour
degree, arcminute, arcsecond :: Floating a => Unit 'NonMetric DPlaneAngle a
degree = mkUnitR (ucum "deg" "°" "degree") (Prelude.pi Prelude./ 180) $ radian
arcminute = mkUnitR (ucum "'" "'" "arcminute") (Prelude.recip 60) $ degreeOfArc
arcsecond = mkUnitR (ucum "''" "''" "arcsecond") (Prelude.recip 60) $ minuteOfArc
degreeOfArc, minuteOfArc, secondOfArc :: Floating a => Unit 'NonMetric DPlaneAngle a
degreeOfArc = degree
secondOfArc = arcsecond
minuteOfArc = arcminute
hectare :: Fractional a => Unit 'NonMetric DArea a
hectare = square (hecto meter)
litre, liter :: Fractional a => Unit 'Metric DVolume a
litre = mkUnitQ (ucumMetric "L" "L" "litre") 1 $ deci meter ^ pos3
liter = litre
tonne, metricTon :: Num a => Unit 'Metric DMass a
tonne = mkUnitZ (ucumMetric "t" "t" "tonne") 1000 $ siUnit
metricTon = tonne
astronomicalUnit :: Num a => Unit 'NonMetric DLength a
astronomicalUnit = mkUnitZ (ucum "AU" "AU" "astronomical unit") 149597870700 $ meter