haskellator-0.1.0.0: SI-Units supporting calculator
Safe HaskellSafe-Inferred
LanguageHaskell2010

Math.Haskellator.Internal.TH.UnitGeneration

Description

Generate the unit type and function to work with them

Synopsis

Documentation

data Quantity Source #

A quantity made of a base unit and other related units

Constructors

Quantity UnitDef [UnitDef] 

data UnitDef Source #

Definition of a Unit

Constructors

UnitDef String String Double 

data Value u Source #

A simple representation of a value with a unit. The unit's type is parameterized, since the unit can be a simple Unit or a Dimension.

Constructors

Value 

Fields

Instances

Instances details
Show u => Show (Value u) Source # 
Instance details

Defined in Math.Haskellator.Internal.TH.UnitGeneration

Methods

showsPrec :: Int -> Value u -> ShowS #

show :: Value u -> String #

showList :: [Value u] -> ShowS #

generateUnits :: [Quantity] -> Q [Dec] Source #

Generate the unit types and function to work with them. Imagine the following call: generateUnits [Quantity (UnitDef Meter "m" 1) [UnitDef Kilometer "km" 1000]]. This function will then generate the following code:

  • A data type with all the units
data Unit = Meter Int | Kilometer Int
  • An instance of Show for the data type
instance Show Unit where -- e is the exponent (is not equal to 1)
  show Meter = "m^e"
  show Kilometer = "km^e"
  • A function to convert a string to a unit
unitFromString :: String -> Either String Unit
unitFromString "m" = Right (Meter 1)
unitFromString "km" = Right (Kilometer 1)
unitFromString x = Left x
  • A function to convert a value to the base unit
convertToBase :: Value UnitExp -> Value UnitExp
convertToBase (Value v (Meter e)) = Value ((v * 1.0) ^ e) (Meter e)
convertToBase (Value v (KiloMeter e)) = Value ((v * 0.0001) ^ e) (Meter e)
  • A function to convert a base unit to another unit
convertTo :: Value UnitExp -> UnitExp -> Maybe (Value UnitExp)
convertTo (Value v (UnitExp Meter es)) (UnitExp Meter et) | es == et = (Just $ Value (v / (1.0 ** fromIntegral es)) (UnitExp Meter es))
                                                          | otherwise = Nothing
convertTo (Value v (UnitExp Meter es)) (UnitExp Kilometer et) | es == et = Just $ Value (v / (1000.0 ** fromIntegral es)) (UnitExp Kilometer et)
                                                              | otherwise = Nothing
convertTo _ _ = Nothing
  • A function to check whether a given unit is a specific unit
isMeter :: Unit -> Bool
isMeter (Meter _) = True
isMeter _ = False
isKilometer :: Unit -> Bool
isKilometer (Kilometer _) = True
isKilometer _ = False
  • A function that creates a UnitExp
meter :: Int -> UnitExp
meter e = UnitExp $ Meter e
kilometers :: Int -> UnitExp
kilometers e = UnitExp $ Kilometer e