module HMath.Units (
Dimension,
dimension,
dimensionExponents,
dimensionless,
lengthDimension,
massDimension,
timeDimension,
temperatureDimension,
angleDimension,
dataDimension,
Unit,
unit,
unitName,
unitDimension,
unitScale,
unitOffset,
unitProduct,
unitQuotient,
unitPower,
Quantity,
quantity,
temperatureDifference,
quantityDimension,
siValue,
inUnit,
convert,
addQuantity,
subtractQuantity,
multiplyQuantity,
divideQuantity,
SIPrefix (..),
siPrefixes,
prefixed,
metre,
kilometre,
centimetre,
millimetre,
inch,
foot,
yard,
mile,
nauticalMile,
squareMetre,
hectare,
cubicMetre,
litre,
millilitre,
kilogram,
gram,
tonne,
pound,
second,
minute,
hour,
day,
metresPerSecond,
kilometresPerHour,
milesPerHour,
metresPerSecondSquared,
newton,
joule,
watt,
pascal,
bar,
atmosphere,
kelvin,
celsius,
fahrenheit,
hertz,
bit,
byte,
kibibyte,
mebibyte,
gigabyte,
radian,
degree,
gradian,
radiansToDegrees,
degreesToRadians,
radiansToGradians,
gradiansToRadians,
) where
import HMath.Constants (constantName, constantValue, mathematicalConstants)
import HMath.Error (MathError (..))
newtype Dimension = Dimension [Integer] deriving (Dimension -> Dimension -> Bool
(Dimension -> Dimension -> Bool)
-> (Dimension -> Dimension -> Bool) -> Eq Dimension
forall a. (a -> a -> Bool) -> (a -> a -> Bool) -> Eq a
$c== :: Dimension -> Dimension -> Bool
== :: Dimension -> Dimension -> Bool
$c/= :: Dimension -> Dimension -> Bool
/= :: Dimension -> Dimension -> Bool
Eq, Int -> Dimension -> ShowS
[Dimension] -> ShowS
Dimension -> String
(Int -> Dimension -> ShowS)
-> (Dimension -> String)
-> ([Dimension] -> ShowS)
-> Show Dimension
forall a.
(Int -> a -> ShowS) -> (a -> String) -> ([a] -> ShowS) -> Show a
$cshowsPrec :: Int -> Dimension -> ShowS
showsPrec :: Int -> Dimension -> ShowS
$cshow :: Dimension -> String
show :: Dimension -> String
$cshowList :: [Dimension] -> ShowS
showList :: [Dimension] -> ShowS
Show)
dimension :: [Integer] -> Either MathError Dimension
dimension :: [Integer] -> Either MathError Dimension
dimension [Integer]
xs
| [Integer] -> Int
forall a. [a] -> Int
forall (t :: * -> *) a. Foldable t => t a -> Int
length [Integer]
xs Int -> Int -> Bool
forall a. Eq a => a -> a -> Bool
/= Int
9 = MathError -> Either MathError Dimension
forall a b. a -> Either a b
Left (String -> MathError
InvalidArgument String
"dimension requires nine exponents")
| Bool
otherwise = Dimension -> Either MathError Dimension
forall a b. b -> Either a b
Right ([Integer] -> Dimension
Dimension [Integer]
xs)
dimensionExponents :: Dimension -> [Integer]
dimensionExponents :: Dimension -> [Integer]
dimensionExponents (Dimension [Integer]
xs) = [Integer]
xs
dimensionless
, lengthDimension
, massDimension
, timeDimension
, temperatureDimension
, angleDimension
, dataDimension ::
Dimension
dimensionless :: Dimension
dimensionless = [Integer] -> Dimension
Dimension (Int -> Integer -> [Integer]
forall a. Int -> a -> [a]
replicate Int
9 Integer
0)
lengthDimension :: Dimension
lengthDimension = Int -> Dimension
base Int
0
massDimension :: Dimension
massDimension = Int -> Dimension
base Int
1
timeDimension :: Dimension
timeDimension = Int -> Dimension
base Int
2
temperatureDimension :: Dimension
temperatureDimension = Int -> Dimension
base Int
4
dataDimension :: Dimension
dataDimension = Int -> Dimension
base Int
7
angleDimension :: Dimension
angleDimension = Int -> Dimension
base Int
8
base :: Int -> Dimension
base :: Int -> Dimension
base Int
i = [Integer] -> Dimension
Dimension [if Int
i Int -> Int -> Bool
forall a. Eq a => a -> a -> Bool
== Int
j then Integer
1 else Integer
0 | Int
j <- [Int
0 .. Int
8]]
combine :: (Integer -> Integer -> Integer) -> Dimension -> Dimension -> Dimension
combine :: (Integer -> Integer -> Integer)
-> Dimension -> Dimension -> Dimension
combine Integer -> Integer -> Integer
op (Dimension [Integer]
a) (Dimension [Integer]
b) = [Integer] -> Dimension
Dimension ((Integer -> Integer -> Integer)
-> [Integer] -> [Integer] -> [Integer]
forall a b c. (a -> b -> c) -> [a] -> [b] -> [c]
zipWith Integer -> Integer -> Integer
op [Integer]
a [Integer]
b)
scaleDimension :: Integer -> Dimension -> Dimension
scaleDimension :: Integer -> Dimension -> Dimension
scaleDimension Integer
n (Dimension [Integer]
xs) = [Integer] -> Dimension
Dimension ((Integer -> Integer) -> [Integer] -> [Integer]
forall a b. (a -> b) -> [a] -> [b]
map (Integer
n Integer -> Integer -> Integer
forall a. Num a => a -> a -> a
*) [Integer]
xs)
data Unit = Unit String Dimension Rational Rational deriving (Unit -> Unit -> Bool
(Unit -> Unit -> Bool) -> (Unit -> Unit -> Bool) -> Eq Unit
forall a. (a -> a -> Bool) -> (a -> a -> Bool) -> Eq a
$c== :: Unit -> Unit -> Bool
== :: Unit -> Unit -> Bool
$c/= :: Unit -> Unit -> Bool
/= :: Unit -> Unit -> Bool
Eq, Int -> Unit -> ShowS
[Unit] -> ShowS
Unit -> String
(Int -> Unit -> ShowS)
-> (Unit -> String) -> ([Unit] -> ShowS) -> Show Unit
forall a.
(Int -> a -> ShowS) -> (a -> String) -> ([a] -> ShowS) -> Show a
$cshowsPrec :: Int -> Unit -> ShowS
showsPrec :: Int -> Unit -> ShowS
$cshow :: Unit -> String
show :: Unit -> String
$cshowList :: [Unit] -> ShowS
showList :: [Unit] -> ShowS
Show)
unitName :: Unit -> String
unitName :: Unit -> String
unitName (Unit String
name Dimension
_ Rational
_ Rational
_) = String
name
unitDimension :: Unit -> Dimension
unitDimension :: Unit -> Dimension
unitDimension (Unit String
_ Dimension
dim Rational
_ Rational
_) = Dimension
dim
unitScale :: Unit -> Rational
unitScale :: Unit -> Rational
unitScale (Unit String
_ Dimension
_ Rational
scale Rational
_) = Rational
scale
unitOffset :: Unit -> Rational
unitOffset :: Unit -> Rational
unitOffset (Unit String
_ Dimension
_ Rational
_ Rational
offset) = Rational
offset
unit :: String -> Dimension -> Rational -> Rational -> Either MathError Unit
unit :: String
-> Dimension -> Rational -> Rational -> Either MathError Unit
unit String
name Dimension
dim Rational
scale Rational
offset
| Rational
scale Rational -> Rational -> Bool
forall a. Ord a => a -> a -> Bool
<= Rational
0 = MathError -> Either MathError Unit
forall a b. a -> Either a b
Left (String -> MathError
InvalidArgument String
"unit scale must be positive")
| Rational
offset Rational -> Rational -> Bool
forall a. Eq a => a -> a -> Bool
/= Rational
0 Bool -> Bool -> Bool
&& Dimension
dim Dimension -> Dimension -> Bool
forall a. Eq a => a -> a -> Bool
/= Dimension
temperatureDimension =
MathError -> Either MathError Unit
forall a b. a -> Either a b
Left (String -> MathError
DomainError String
"affine offset requires temperature dimension")
| Bool
otherwise = Unit -> Either MathError Unit
forall a b. b -> Either a b
Right (String -> Dimension -> Rational -> Rational -> Unit
Unit String
name Dimension
dim Rational
scale Rational
offset)
unitProduct, unitQuotient :: Unit -> Unit -> Either MathError Unit
unitProduct :: Unit -> Unit -> Either MathError Unit
unitProduct Unit
a Unit
b
| Unit -> Rational
unitOffset Unit
a Rational -> Rational -> Bool
forall a. Eq a => a -> a -> Bool
/= Rational
0 Bool -> Bool -> Bool
|| Unit -> Rational
unitOffset Unit
b Rational -> Rational -> Bool
forall a. Eq a => a -> a -> Bool
/= Rational
0 = MathError -> Either MathError Unit
forall a b. a -> Either a b
Left (String -> MathError
DomainError String
"cannot multiply affine units")
| Bool
otherwise =
Unit -> Either MathError Unit
forall a b. b -> Either a b
Right
( String -> Dimension -> Rational -> Rational -> Unit
Unit
(Unit -> String
unitName Unit
a String -> ShowS
forall a. [a] -> [a] -> [a]
++ String
" " String -> ShowS
forall a. [a] -> [a] -> [a]
++ Unit -> String
unitName Unit
b)
((Integer -> Integer -> Integer)
-> Dimension -> Dimension -> Dimension
combine Integer -> Integer -> Integer
forall a. Num a => a -> a -> a
(+) (Unit -> Dimension
unitDimension Unit
a) (Unit -> Dimension
unitDimension Unit
b))
(Unit -> Rational
unitScale Unit
a Rational -> Rational -> Rational
forall a. Num a => a -> a -> a
* Unit -> Rational
unitScale Unit
b)
Rational
0
)
unitQuotient :: Unit -> Unit -> Either MathError Unit
unitQuotient Unit
a Unit
b
| Unit -> Rational
unitOffset Unit
a Rational -> Rational -> Bool
forall a. Eq a => a -> a -> Bool
/= Rational
0 Bool -> Bool -> Bool
|| Unit -> Rational
unitOffset Unit
b Rational -> Rational -> Bool
forall a. Eq a => a -> a -> Bool
/= Rational
0 = MathError -> Either MathError Unit
forall a b. a -> Either a b
Left (String -> MathError
DomainError String
"cannot divide affine units")
| Bool
otherwise =
Unit -> Either MathError Unit
forall a b. b -> Either a b
Right
( String -> Dimension -> Rational -> Rational -> Unit
Unit
(Unit -> String
unitName Unit
a String -> ShowS
forall a. [a] -> [a] -> [a]
++ String
"/" String -> ShowS
forall a. [a] -> [a] -> [a]
++ Unit -> String
unitName Unit
b)
((Integer -> Integer -> Integer)
-> Dimension -> Dimension -> Dimension
combine (-) (Unit -> Dimension
unitDimension Unit
a) (Unit -> Dimension
unitDimension Unit
b))
(Unit -> Rational
unitScale Unit
a Rational -> Rational -> Rational
forall a. Fractional a => a -> a -> a
/ Unit -> Rational
unitScale Unit
b)
Rational
0
)
unitPower :: Unit -> Integer -> Either MathError Unit
unitPower :: Unit -> Integer -> Either MathError Unit
unitPower Unit
a Integer
n
| Unit -> Rational
unitOffset Unit
a Rational -> Rational -> Bool
forall a. Eq a => a -> a -> Bool
/= Rational
0 = MathError -> Either MathError Unit
forall a b. a -> Either a b
Left (String -> MathError
DomainError String
"cannot exponentiate affine units")
| Bool
otherwise =
Unit -> Either MathError Unit
forall a b. b -> Either a b
Right (String -> Dimension -> Rational -> Rational -> Unit
Unit (Unit -> String
unitName Unit
a String -> ShowS
forall a. [a] -> [a] -> [a]
++ String
"^" String -> ShowS
forall a. [a] -> [a] -> [a]
++ Integer -> String
forall a. Show a => a -> String
show Integer
n) (Integer -> Dimension -> Dimension
scaleDimension Integer
n (Unit -> Dimension
unitDimension Unit
a)) (Unit -> Rational
unitScale Unit
a Rational -> Integer -> Rational
forall a b. (Fractional a, Integral b) => a -> b -> a
^^ Integer
n) Rational
0)
data Quantity = Quantity Dimension Rational Bool deriving (Quantity -> Quantity -> Bool
(Quantity -> Quantity -> Bool)
-> (Quantity -> Quantity -> Bool) -> Eq Quantity
forall a. (a -> a -> Bool) -> (a -> a -> Bool) -> Eq a
$c== :: Quantity -> Quantity -> Bool
== :: Quantity -> Quantity -> Bool
$c/= :: Quantity -> Quantity -> Bool
/= :: Quantity -> Quantity -> Bool
Eq, Int -> Quantity -> ShowS
[Quantity] -> ShowS
Quantity -> String
(Int -> Quantity -> ShowS)
-> (Quantity -> String) -> ([Quantity] -> ShowS) -> Show Quantity
forall a.
(Int -> a -> ShowS) -> (a -> String) -> ([a] -> ShowS) -> Show a
$cshowsPrec :: Int -> Quantity -> ShowS
showsPrec :: Int -> Quantity -> ShowS
$cshow :: Quantity -> String
show :: Quantity -> String
$cshowList :: [Quantity] -> ShowS
showList :: [Quantity] -> ShowS
Show)
quantity :: Unit -> Rational -> Quantity
quantity :: Unit -> Rational -> Quantity
quantity Unit
u Rational
x =
Dimension -> Rational -> Bool -> Quantity
Quantity
(Unit -> Dimension
unitDimension Unit
u)
(Rational
x Rational -> Rational -> Rational
forall a. Num a => a -> a -> a
* Unit -> Rational
unitScale Unit
u Rational -> Rational -> Rational
forall a. Num a => a -> a -> a
+ Unit -> Rational
unitOffset Unit
u)
(Unit -> Dimension
unitDimension Unit
u Dimension -> Dimension -> Bool
forall a. Eq a => a -> a -> Bool
== Dimension
temperatureDimension)
temperatureDifference :: Unit -> Rational -> Either MathError Quantity
temperatureDifference :: Unit -> Rational -> Either MathError Quantity
temperatureDifference Unit
u Rational
x
| Unit -> Dimension
unitDimension Unit
u Dimension -> Dimension -> Bool
forall a. Eq a => a -> a -> Bool
/= Dimension
temperatureDimension =
MathError -> Either MathError Quantity
forall a b. a -> Either a b
Left (String -> MathError
DomainError String
"temperature difference requires temperature unit")
| Bool
otherwise = Quantity -> Either MathError Quantity
forall a b. b -> Either a b
Right (Dimension -> Rational -> Bool -> Quantity
Quantity Dimension
temperatureDimension (Rational
x Rational -> Rational -> Rational
forall a. Num a => a -> a -> a
* Unit -> Rational
unitScale Unit
u) Bool
False)
quantityDimension :: Quantity -> Dimension
quantityDimension :: Quantity -> Dimension
quantityDimension (Quantity Dimension
d Rational
_ Bool
_) = Dimension
d
siValue :: Quantity -> Rational
siValue :: Quantity -> Rational
siValue (Quantity Dimension
_ Rational
x Bool
_) = Rational
x
inUnit :: Unit -> Quantity -> Either MathError Rational
inUnit :: Unit -> Quantity -> Either MathError Rational
inUnit Unit
u (Quantity Dimension
d Rational
x Bool
absoluteTemp)
| Unit -> Dimension
unitDimension Unit
u Dimension -> Dimension -> Bool
forall a. Eq a => a -> a -> Bool
/= Dimension
d = MathError -> Either MathError Rational
forall a b. a -> Either a b
Left (String -> MathError
DomainError String
"incompatible dimensions")
| Bool
otherwise = Rational -> Either MathError Rational
forall a b. b -> Either a b
Right ((Rational
x Rational -> Rational -> Rational
forall a. Num a => a -> a -> a
- (if Bool
absoluteTemp then Unit -> Rational
unitOffset Unit
u else Rational
0)) Rational -> Rational -> Rational
forall a. Fractional a => a -> a -> a
/ Unit -> Rational
unitScale Unit
u)
convert :: Unit -> Unit -> Rational -> Either MathError Rational
convert :: Unit -> Unit -> Rational -> Either MathError Rational
convert Unit
a Unit
b Rational
x = Unit -> Quantity -> Either MathError Rational
inUnit Unit
b (Unit -> Rational -> Quantity
quantity Unit
a Rational
x)
addQuantity
, subtractQuantity
, multiplyQuantity
, divideQuantity ::
Quantity -> Quantity -> Either MathError Quantity
addQuantity :: Quantity -> Quantity -> Either MathError Quantity
addQuantity (Quantity Dimension
d Rational
a Bool
absA) (Quantity Dimension
e Rational
b Bool
absB)
| Dimension
d Dimension -> Dimension -> Bool
forall a. Eq a => a -> a -> Bool
/= Dimension
e = MathError -> Either MathError Quantity
forall a b. a -> Either a b
Left (String -> MathError
DomainError String
"incompatible dimensions")
| Bool
absA Bool -> Bool -> Bool
&& Bool
absB = MathError -> Either MathError Quantity
forall a b. a -> Either a b
Left (String -> MathError
DomainError String
"cannot add absolute temperatures")
| Bool
otherwise = Quantity -> Either MathError Quantity
forall a b. b -> Either a b
Right (Dimension -> Rational -> Bool -> Quantity
Quantity Dimension
d (Rational
a Rational -> Rational -> Rational
forall a. Num a => a -> a -> a
+ Rational
b) (Bool
absA Bool -> Bool -> Bool
|| Bool
absB))
subtractQuantity :: Quantity -> Quantity -> Either MathError Quantity
subtractQuantity (Quantity Dimension
d Rational
a Bool
absA) (Quantity Dimension
e Rational
b Bool
absB)
| Dimension
d Dimension -> Dimension -> Bool
forall a. Eq a => a -> a -> Bool
/= Dimension
e = MathError -> Either MathError Quantity
forall a b. a -> Either a b
Left (String -> MathError
DomainError String
"incompatible dimensions")
| Bool -> Bool
not Bool
absA Bool -> Bool -> Bool
&& Bool
absB = MathError -> Either MathError Quantity
forall a b. a -> Either a b
Left (String -> MathError
DomainError String
"cannot subtract absolute temperature from difference")
| Bool
otherwise = Quantity -> Either MathError Quantity
forall a b. b -> Either a b
Right (Dimension -> Rational -> Bool -> Quantity
Quantity Dimension
d (Rational
a Rational -> Rational -> Rational
forall a. Num a => a -> a -> a
- Rational
b) (Bool
absA Bool -> Bool -> Bool
&& Bool -> Bool
not Bool
absB))
multiplyQuantity :: Quantity -> Quantity -> Either MathError Quantity
multiplyQuantity (Quantity Dimension
d Rational
a Bool
absA) (Quantity Dimension
e Rational
b Bool
absB)
| Bool
absA Bool -> Bool -> Bool
|| Bool
absB = MathError -> Either MathError Quantity
forall a b. a -> Either a b
Left (String -> MathError
DomainError String
"cannot multiply absolute temperatures")
| Bool
otherwise = Quantity -> Either MathError Quantity
forall a b. b -> Either a b
Right (Dimension -> Rational -> Bool -> Quantity
Quantity ((Integer -> Integer -> Integer)
-> Dimension -> Dimension -> Dimension
combine Integer -> Integer -> Integer
forall a. Num a => a -> a -> a
(+) Dimension
d Dimension
e) (Rational
a Rational -> Rational -> Rational
forall a. Num a => a -> a -> a
* Rational
b) Bool
False)
divideQuantity :: Quantity -> Quantity -> Either MathError Quantity
divideQuantity (Quantity Dimension
d Rational
a Bool
absA) (Quantity Dimension
e Rational
b Bool
absB)
| Bool
absA Bool -> Bool -> Bool
|| Bool
absB = MathError -> Either MathError Quantity
forall a b. a -> Either a b
Left (String -> MathError
DomainError String
"cannot divide absolute temperatures")
| Rational
b Rational -> Rational -> Bool
forall a. Eq a => a -> a -> Bool
== Rational
0 = MathError -> Either MathError Quantity
forall a b. a -> Either a b
Left (String -> MathError
DomainError String
"quantity division by zero")
| Bool
otherwise = Quantity -> Either MathError Quantity
forall a b. b -> Either a b
Right (Dimension -> Rational -> Bool -> Quantity
Quantity ((Integer -> Integer -> Integer)
-> Dimension -> Dimension -> Dimension
combine (-) Dimension
d Dimension
e) (Rational
a Rational -> Rational -> Rational
forall a. Fractional a => a -> a -> a
/ Rational
b) Bool
False)
data SIPrefix = SIPrefix
{ SIPrefix -> String
prefixName :: String
, SIPrefix -> String
prefixSymbol :: String
, SIPrefix -> Int
prefixExponent :: Int
}
deriving (SIPrefix -> SIPrefix -> Bool
(SIPrefix -> SIPrefix -> Bool)
-> (SIPrefix -> SIPrefix -> Bool) -> Eq SIPrefix
forall a. (a -> a -> Bool) -> (a -> a -> Bool) -> Eq a
$c== :: SIPrefix -> SIPrefix -> Bool
== :: SIPrefix -> SIPrefix -> Bool
$c/= :: SIPrefix -> SIPrefix -> Bool
/= :: SIPrefix -> SIPrefix -> Bool
Eq, Int -> SIPrefix -> ShowS
[SIPrefix] -> ShowS
SIPrefix -> String
(Int -> SIPrefix -> ShowS)
-> (SIPrefix -> String) -> ([SIPrefix] -> ShowS) -> Show SIPrefix
forall a.
(Int -> a -> ShowS) -> (a -> String) -> ([a] -> ShowS) -> Show a
$cshowsPrec :: Int -> SIPrefix -> ShowS
showsPrec :: Int -> SIPrefix -> ShowS
$cshow :: SIPrefix -> String
show :: SIPrefix -> String
$cshowList :: [SIPrefix] -> ShowS
showList :: [SIPrefix] -> ShowS
Show)
siPrefixes :: [SIPrefix]
siPrefixes :: [SIPrefix]
siPrefixes =
[ String -> String -> Int -> SIPrefix
SIPrefix String
n String
s Int
e
| (String
n, String
s, Int
e) <-
[ (String
"quetta", String
"Q", Int
30)
, (String
"ronna", String
"R", Int
27)
, (String
"yotta", String
"Y", Int
24)
, (String
"zetta", String
"Z", Int
21)
, (String
"exa", String
"E", Int
18)
, (String
"peta", String
"P", Int
15)
, (String
"tera", String
"T", Int
12)
, (String
"giga", String
"G", Int
9)
, (String
"mega", String
"M", Int
6)
, (String
"kilo", String
"k", Int
3)
, (String
"hecto", String
"h", Int
2)
, (String
"deca", String
"da", Int
1)
, (String
"deci", String
"d", -Int
1)
, (String
"centi", String
"c", -Int
2)
, (String
"milli", String
"m", -Int
3)
, (String
"micro", String
"u", -Int
6)
, (String
"nano", String
"n", -Int
9)
, (String
"pico", String
"p", -Int
12)
, (String
"femto", String
"f", -Int
15)
, (String
"atto", String
"a", -Int
18)
, (String
"zepto", String
"z", -Int
21)
, (String
"yocto", String
"y", -Int
24)
, (String
"ronto", String
"r", -Int
27)
, (String
"quecto", String
"q", -Int
30)
]
]
prefixed :: SIPrefix -> Unit -> Either MathError Unit
prefixed :: SIPrefix -> Unit -> Either MathError Unit
prefixed SIPrefix
p Unit
u
| Unit -> Rational
unitOffset Unit
u Rational -> Rational -> Bool
forall a. Eq a => a -> a -> Bool
/= Rational
0 = MathError -> Either MathError Unit
forall a b. a -> Either a b
Left (String -> MathError
DomainError String
"cannot prefix affine unit")
| Integer -> Integer
forall a. Num a => a -> a
abs (Int -> Integer
forall a. Integral a => a -> Integer
toInteger (SIPrefix -> Int
prefixExponent SIPrefix
p)) Integer -> Integer -> Bool
forall a. Ord a => a -> a -> Bool
> Integer
10000 =
MathError -> Either MathError Unit
forall a b. a -> Either a b
Left (String -> MathError
InvalidArgument String
"prefix exponent exceeds resource limit")
| Bool
otherwise =
let e :: Int
e = SIPrefix -> Int
prefixExponent SIPrefix
p; s :: Rational
s = if Int
e Int -> Int -> Bool
forall a. Ord a => a -> a -> Bool
>= Int
0 then Integer -> Rational
forall a. Num a => Integer -> a
fromInteger (Integer
10 Integer -> Int -> Integer
forall a b. (Num a, Integral b) => a -> b -> a
^ Int
e) else Rational
1 Rational -> Rational -> Rational
forall a. Fractional a => a -> a -> a
/ Integer -> Rational
forall a. Num a => Integer -> a
fromInteger (Integer
10 Integer -> Int -> Integer
forall a b. (Num a, Integral b) => a -> b -> a
^ Int -> Int
forall a. Num a => a -> a
negate Int
e)
in Unit -> Either MathError Unit
forall a b. b -> Either a b
Right (String -> Dimension -> Rational -> Rational -> Unit
Unit (SIPrefix -> String
prefixSymbol SIPrefix
p String -> ShowS
forall a. [a] -> [a] -> [a]
++ Unit -> String
unitName Unit
u) (Unit -> Dimension
unitDimension Unit
u) (Rational
s Rational -> Rational -> Rational
forall a. Num a => a -> a -> a
* Unit -> Rational
unitScale Unit
u) Rational
0)
metre, kilometre, centimetre, millimetre, inch, foot, yard, mile, nauticalMile :: Unit
metre :: Unit
metre = String -> Dimension -> Rational -> Rational -> Unit
Unit String
"m" Dimension
lengthDimension Rational
1 Rational
0
kilometre :: Unit
kilometre = String -> Dimension -> Rational -> Rational -> Unit
Unit String
"km" Dimension
lengthDimension Rational
1000 Rational
0
centimetre :: Unit
centimetre = String -> Dimension -> Rational -> Rational -> Unit
Unit String
"cm" Dimension
lengthDimension Rational
0.01 Rational
0
millimetre :: Unit
millimetre = String -> Dimension -> Rational -> Rational -> Unit
Unit String
"mm" Dimension
lengthDimension Rational
0.001 Rational
0
inch :: Unit
inch = String -> Dimension -> Rational -> Rational -> Unit
Unit String
"in" Dimension
lengthDimension Rational
0.0254 Rational
0
= String -> Dimension -> Rational -> Rational -> Unit
Unit String
"ft" Dimension
lengthDimension Rational
0.3048 Rational
0
yard :: Unit
yard = String -> Dimension -> Rational -> Rational -> Unit
Unit String
"yd" Dimension
lengthDimension Rational
0.9144 Rational
0
mile :: Unit
mile = String -> Dimension -> Rational -> Rational -> Unit
Unit String
"mi" Dimension
lengthDimension Rational
1609.344 Rational
0
nauticalMile :: Unit
nauticalMile = String -> Dimension -> Rational -> Rational -> Unit
Unit String
"nmi" Dimension
lengthDimension Rational
1852 Rational
0
squareMetre, hectare, cubicMetre, litre, millilitre :: Unit
squareMetre :: Unit
squareMetre = String -> Dimension -> Rational -> Rational -> Unit
Unit String
"m^2" (Integer -> Dimension -> Dimension
scaleDimension Integer
2 Dimension
lengthDimension) Rational
1 Rational
0
hectare :: Unit
hectare = String -> Dimension -> Rational -> Rational -> Unit
Unit String
"ha" (Integer -> Dimension -> Dimension
scaleDimension Integer
2 Dimension
lengthDimension) Rational
10000 Rational
0
cubicMetre :: Unit
cubicMetre = String -> Dimension -> Rational -> Rational -> Unit
Unit String
"m^3" (Integer -> Dimension -> Dimension
scaleDimension Integer
3 Dimension
lengthDimension) Rational
1 Rational
0
litre :: Unit
litre = String -> Dimension -> Rational -> Rational -> Unit
Unit String
"L" (Integer -> Dimension -> Dimension
scaleDimension Integer
3 Dimension
lengthDimension) Rational
0.001 Rational
0
millilitre :: Unit
millilitre = String -> Dimension -> Rational -> Rational -> Unit
Unit String
"mL" (Integer -> Dimension -> Dimension
scaleDimension Integer
3 Dimension
lengthDimension) Rational
0.000001 Rational
0
kilogram, gram, tonne, pound, second, minute, hour, day :: Unit
kilogram :: Unit
kilogram = String -> Dimension -> Rational -> Rational -> Unit
Unit String
"kg" Dimension
massDimension Rational
1 Rational
0
gram :: Unit
gram = String -> Dimension -> Rational -> Rational -> Unit
Unit String
"g" Dimension
massDimension Rational
0.001 Rational
0
tonne :: Unit
tonne = String -> Dimension -> Rational -> Rational -> Unit
Unit String
"t" Dimension
massDimension Rational
1000 Rational
0
pound :: Unit
pound = String -> Dimension -> Rational -> Rational -> Unit
Unit String
"lb" Dimension
massDimension Rational
0.45359237 Rational
0
second :: Unit
second = String -> Dimension -> Rational -> Rational -> Unit
Unit String
"s" Dimension
timeDimension Rational
1 Rational
0
minute :: Unit
minute = String -> Dimension -> Rational -> Rational -> Unit
Unit String
"min" Dimension
timeDimension Rational
60 Rational
0
hour :: Unit
hour = String -> Dimension -> Rational -> Rational -> Unit
Unit String
"h" Dimension
timeDimension Rational
3600 Rational
0
day :: Unit
day = String -> Dimension -> Rational -> Rational -> Unit
Unit String
"d" Dimension
timeDimension Rational
86400 Rational
0
metresPerSecond, kilometresPerHour, milesPerHour, metresPerSecondSquared :: Unit
metresPerSecond :: Unit
metresPerSecond = String -> Dimension -> Rational -> Rational -> Unit
Unit String
"m/s" ((Integer -> Integer -> Integer)
-> Dimension -> Dimension -> Dimension
combine (-) Dimension
lengthDimension Dimension
timeDimension) Rational
1 Rational
0
kilometresPerHour :: Unit
kilometresPerHour = String -> Dimension -> Rational -> Rational -> Unit
Unit String
"km/h" (Unit -> Dimension
unitDimension Unit
metresPerSecond) (Rational
1000 Rational -> Rational -> Rational
forall a. Fractional a => a -> a -> a
/ Rational
3600) Rational
0
milesPerHour :: Unit
milesPerHour = String -> Dimension -> Rational -> Rational -> Unit
Unit String
"mi/h" (Unit -> Dimension
unitDimension Unit
metresPerSecond) (Rational
1609.344 Rational -> Rational -> Rational
forall a. Fractional a => a -> a -> a
/ Rational
3600) Rational
0
metresPerSecondSquared :: Unit
metresPerSecondSquared = String -> Dimension -> Rational -> Rational -> Unit
Unit String
"m/s^2" ((Integer -> Integer -> Integer)
-> Dimension -> Dimension -> Dimension
combine (-) Dimension
lengthDimension (Integer -> Dimension -> Dimension
scaleDimension Integer
2 Dimension
timeDimension)) Rational
1 Rational
0
newton, joule, watt, pascal, bar, atmosphere :: Unit
newton :: Unit
newton = String -> Dimension -> Rational -> Rational -> Unit
Unit String
"N" ((Integer -> Integer -> Integer)
-> Dimension -> Dimension -> Dimension
combine Integer -> Integer -> Integer
forall a. Num a => a -> a -> a
(+) Dimension
massDimension (Unit -> Dimension
unitDimension Unit
metresPerSecondSquared)) Rational
1 Rational
0
joule :: Unit
joule = String -> Dimension -> Rational -> Rational -> Unit
Unit String
"J" ((Integer -> Integer -> Integer)
-> Dimension -> Dimension -> Dimension
combine Integer -> Integer -> Integer
forall a. Num a => a -> a -> a
(+) (Unit -> Dimension
unitDimension Unit
newton) Dimension
lengthDimension) Rational
1 Rational
0
watt :: Unit
watt = String -> Dimension -> Rational -> Rational -> Unit
Unit String
"W" ((Integer -> Integer -> Integer)
-> Dimension -> Dimension -> Dimension
combine (-) (Unit -> Dimension
unitDimension Unit
joule) Dimension
timeDimension) Rational
1 Rational
0
pascal :: Unit
pascal = String -> Dimension -> Rational -> Rational -> Unit
Unit String
"Pa" ((Integer -> Integer -> Integer)
-> Dimension -> Dimension -> Dimension
combine (-) (Unit -> Dimension
unitDimension Unit
newton) (Unit -> Dimension
unitDimension Unit
squareMetre)) Rational
1 Rational
0
bar :: Unit
bar = String -> Dimension -> Rational -> Rational -> Unit
Unit String
"bar" (Unit -> Dimension
unitDimension Unit
pascal) Rational
100000 Rational
0
atmosphere :: Unit
atmosphere = String -> Dimension -> Rational -> Rational -> Unit
Unit String
"atm" (Unit -> Dimension
unitDimension Unit
pascal) Rational
101325 Rational
0
kelvin, celsius, fahrenheit, hertz, bit, byte, kibibyte, mebibyte, gigabyte :: Unit
kelvin :: Unit
kelvin = String -> Dimension -> Rational -> Rational -> Unit
Unit String
"K" Dimension
temperatureDimension Rational
1 Rational
0
celsius :: Unit
celsius = String -> Dimension -> Rational -> Rational -> Unit
Unit String
"degC" Dimension
temperatureDimension Rational
1 Rational
273.15
fahrenheit :: Unit
fahrenheit = String -> Dimension -> Rational -> Rational -> Unit
Unit String
"degF" Dimension
temperatureDimension (Rational
5 Rational -> Rational -> Rational
forall a. Fractional a => a -> a -> a
/ Rational
9) (Rational
273.15 Rational -> Rational -> Rational
forall a. Num a => a -> a -> a
- Rational
32 Rational -> Rational -> Rational
forall a. Num a => a -> a -> a
* Rational
5 Rational -> Rational -> Rational
forall a. Fractional a => a -> a -> a
/ Rational
9)
hertz :: Unit
hertz = String -> Dimension -> Rational -> Rational -> Unit
Unit String
"Hz" (Integer -> Dimension -> Dimension
scaleDimension (-Integer
1) Dimension
timeDimension) Rational
1 Rational
0
bit :: Unit
bit = String -> Dimension -> Rational -> Rational -> Unit
Unit String
"bit" Dimension
dataDimension Rational
1 Rational
0
byte :: Unit
byte = String -> Dimension -> Rational -> Rational -> Unit
Unit String
"B" Dimension
dataDimension Rational
8 Rational
0
kibibyte :: Unit
kibibyte = String -> Dimension -> Rational -> Rational -> Unit
Unit String
"KiB" Dimension
dataDimension (Rational
8 Rational -> Rational -> Rational
forall a. Num a => a -> a -> a
* Rational
1024) Rational
0
mebibyte :: Unit
mebibyte = String -> Dimension -> Rational -> Rational -> Unit
Unit String
"MiB" Dimension
dataDimension (Rational
8 Rational -> Rational -> Rational
forall a. Num a => a -> a -> a
* Rational
1024 Rational -> Rational -> Rational
forall a. Num a => a -> a -> a
* Rational
1024) Rational
0
gigabyte :: Unit
gigabyte = String -> Dimension -> Rational -> Rational -> Unit
Unit String
"GB" Dimension
dataDimension (Rational
8 Rational -> Rational -> Rational
forall a. Num a => a -> a -> a
* Rational
10 Rational -> Int -> Rational
forall a b. (Num a, Integral b) => a -> b -> a
^ (Int
9 :: Int)) Rational
0
radian, degree, gradian :: Unit
radian :: Unit
radian = String -> Dimension -> Rational -> Rational -> Unit
Unit String
"rad" Dimension
angleDimension Rational
1 Rational
0
degree :: Unit
degree = String -> Dimension -> Rational -> Rational -> Unit
Unit String
"deg" Dimension
angleDimension (Rational
piR Rational -> Rational -> Rational
forall a. Fractional a => a -> a -> a
/ Rational
180) Rational
0
gradian :: Unit
gradian = String -> Dimension -> Rational -> Rational -> Unit
Unit String
"grad" Dimension
angleDimension (Rational
piR Rational -> Rational -> Rational
forall a. Fractional a => a -> a -> a
/ Rational
200) Rational
0
piR :: Rational
piR :: Rational
piR = case (Constant -> Bool) -> [Constant] -> [Constant]
forall a. (a -> Bool) -> [a] -> [a]
filter ((String -> String -> Bool
forall a. Eq a => a -> a -> Bool
== String
"pi") (String -> Bool) -> (Constant -> String) -> Constant -> Bool
forall b c a. (b -> c) -> (a -> b) -> a -> c
. Constant -> String
constantName) [Constant]
mathematicalConstants of
Constant
c : [Constant]
_ -> Constant -> Rational
constantValue Constant
c
[] -> Rational
3.14159265358979323846264338327950288419716939937510
radiansToDegrees, degreesToRadians, radiansToGradians, gradiansToRadians :: (Floating a) => a -> a
radiansToDegrees :: forall a. Floating a => a -> a
radiansToDegrees a
x = a
x a -> a -> a
forall a. Num a => a -> a -> a
* a
180 a -> a -> a
forall a. Fractional a => a -> a -> a
/ a
forall a. Floating a => a
pi
degreesToRadians :: forall a. Floating a => a -> a
degreesToRadians a
x = a
x a -> a -> a
forall a. Num a => a -> a -> a
* a
forall a. Floating a => a
pi a -> a -> a
forall a. Fractional a => a -> a -> a
/ a
180
radiansToGradians :: forall a. Floating a => a -> a
radiansToGradians a
x = a
x a -> a -> a
forall a. Num a => a -> a -> a
* a
200 a -> a -> a
forall a. Fractional a => a -> a -> a
/ a
forall a. Floating a => a
pi
gradiansToRadians :: forall a. Floating a => a -> a
gradiansToRadians a
x = a
x a -> a -> a
forall a. Num a => a -> a -> a
* a
forall a. Floating a => a
pi a -> a -> a
forall a. Fractional a => a -> a -> a
/ a
200