-- Hoogle documentation, generated by Haddock -- See Hoogle, http://www.haskell.org/hoogle/ -- | Unit conversion and manipulation library. -- -- Credit goes to https://github.com/jdreaver/quantities from -- which this package is initially a fork. A library for creating and -- manipulating physical quantities, which are a numerical value -- associated with a unit of measurement. Included is an expression -- parser and a huge list of predefined quantities with which to parse -- strings into a Quantity datatype. Once created, a quantity can be -- converted to different units or queried for its dimensionality. A user -- can also operate on quantities arithmetically, and doing so uses -- automatic unit conversion and simplification. @package jinquantities @version 0.1.0 -- | Base module for all data structures. module Data.Quantities.Data -- | String representation of a unit. Examples: "meter", "foot" type Symbol = String -- | Representation of single unit. For example: "mm^2" is represented as -- --
-- SimpleUnit { symbol = "meter", prefix = "milli", power = 2.0 }
--
data SimpleUnit
SimpleUnit :: String -> String -> Double -> SimpleUnit
[symbol] :: SimpleUnit -> String
[prefix] :: SimpleUnit -> String
[power] :: SimpleUnit -> Double
-- | Data type to hold compound units, which are simple units multiplied
-- together.
data CompoundUnit
CompoundUnit :: Definitions -> [SimpleUnit] -> CompoundUnit
-- | Definitions used to create the units.
[defs] :: CompoundUnit -> Definitions
-- | List of SimpleUnits that is interpreted as the units being multiplied
-- together.
[sUnits] :: CompoundUnit -> [SimpleUnit]
-- | Show a single unit, but prepend with / if negative
showCompUnit' :: SimpleUnit -> String
-- | Removes decimal if almost integer.
showPower :: Double -> String
-- | Will be used when we allow pretty printing of fractional units.
showPrettyNum :: (Show a, Num a) => a -> String
-- | Combination of magnitude and units.
data Quantity a
Quantity :: a -> CompoundUnit -> Quantity a
-- | Numerical magnitude of quantity.
--
-- -- >>> magnitude <$> fromString "100 N * m" -- Right 100.0 --[magnitude] :: Quantity a -> a -- | Units associated with quantity. -- --
-- >>> units <$> fromString "3.4 m/s^2" -- Right meter / second ** 2 --[units] :: Quantity a -> CompoundUnit -- | Convenience function to extract SimpleUnit collection from Quantity's -- CompoundUnit. units' :: Quantity a -> [SimpleUnit] -- | Convenience function to extract Definitions from Quantity's -- CompoundUnit. defs' :: Quantity a -> Definitions -- | Convenience function to make quantity with no definitions. baseQuant :: a -> [SimpleUnit] -> Quantity a -- | Sort units but put negative units at end. showSort :: [SimpleUnit] -> [SimpleUnit] -- | Custom error type data QuantityError a -- | Used when trying to parse an undefined unit. UndefinedUnitError :: String -> QuantityError a -- | Used when converting units that do not have the same dimensionality -- (example: convert meter to second). DimensionalityError :: CompoundUnit -> CompoundUnit -> QuantityError a -- | Used internally when defining units and a unit is already defined. UnitAlreadyDefinedError :: String -> QuantityError a -- | Used internally when defining units and a prefix is already defined. PrefixAlreadyDefinedError :: String -> QuantityError a -- | Used when a string cannot be parsed. ParserError :: String -> QuantityError a -- | Used when two quantities come from different Definitions. DifferentDefinitionsError :: CompoundUnit -> CompoundUnit -> QuantityError a -- | Used when a scaling factor is present in a unit conversion. ScalingFactorError :: (Quantity a) -> QuantityError a -- | Useful for monadic computations with QuantityErrors. Some -- examples: -- --
-- computation :: QuantityComputation Quantity -- computation = do -- x <- fromString "mile/hr" -- y <- unitsFromString "m/s" -- convert x y ---- -- Returns Right 0.44704 meter / second -- --
-- computation :: QuantityComputation Quantity -- computation = do -- x <- fromString "BADUNIT" -- convertBase x ---- -- Returns Left (UndefinedUnitError BADUNIT) type QuantityComputation a = Either (QuantityError a) -- | Combines equivalent units and removes units with powers of zero. reduceUnits :: Quantity a -> Quantity a -- | Helper function for reduceUnits. reduceUnits' :: [SimpleUnit] -> [SimpleUnit] -- | Removes units with powers of zero that are left over from other -- computations. removeZeros :: [SimpleUnit] -> [SimpleUnit] -- | Negate the powers of a list of SimpleUnits. invertUnits :: [SimpleUnit] -> [SimpleUnit] -- | Inverts unit by negating the power field. invertSimpleUnit :: SimpleUnit -> SimpleUnit -- | Multiplies two quantities. multiplyQuants :: (Num a) => Quantity a -> Quantity a -> Quantity a -- | Divides two quantities. divideQuants :: (Fractional a) => Quantity a -> Quantity a -> Quantity a -- | Exponentiates a quantity with an integer exptQuants :: (Real a, Floating a) => Quantity a -> a -> Quantity a -- | Data type for the three definition types. Used to hold definitions -- information when parsing. data Definition PrefixDefinition :: Symbol -> Double -> [Symbol] -> Definition [defPrefix] :: Definition -> Symbol [factor] :: Definition -> Double [defSynonyms] :: Definition -> [Symbol] BaseDefinition :: Symbol -> Symbol -> [Symbol] -> Definition [base] :: Definition -> Symbol [dimBase] :: Definition -> Symbol [defSynonyms] :: Definition -> [Symbol] UnitDefinition :: Symbol -> Quantity Double -> [Symbol] -> Definition [defSymbol] :: Definition -> Symbol [quantity] :: Definition -> Quantity Double [defSynonyms] :: Definition -> [Symbol] -- | Holds information about defined units, prefixes, and bases. Used when -- parsing new units and performing units conversions. data Definitions Definitions :: Map String (Double, [SimpleUnit]) -> Map String String -> [String] -> [String] -> Map String Double -> Map String String -> Map String String -> Int -> Definitions -- | Map from symbol to base units and conversion factor to those units. [bases] :: Definitions -> Map String (Double, [SimpleUnit]) -- | Map from alias to symbol. Symbols without aliases are present as -- identity maps. [synonyms] :: Definitions -> Map String String -- | List of all units (no aliases). Used in prefix parser, and to detect -- duplicate definitions. [unitsList] :: Definitions -> [String] -- | List of all prefixes (no aliases). Used in prefix parser, and to -- detect duplicate prefix definitions. [prefixes] :: Definitions -> [String] -- | Multiplicative factor of prefixes. [prefixValues] :: Definitions -> Map String Double -- | Map from prefix alias to prefix. [prefixSynonyms] :: Definitions -> Map String String -- | Map from base symbols to unit types. [unitTypes] :: Definitions -> Map String String -- | Hash of the definitions string used to create definitions. Defaults to -- -1 if modified or no string was used. [defStringHash] :: Definitions -> Int -- | Default, empty set of definitions. emptyDefinitions :: Definitions -- | Combine two Definitions structures unionDefinitions :: Definitions -> Definitions -> Definitions instance GHC.Classes.Eq a => GHC.Classes.Eq (Data.Quantities.Data.QuantityError a) instance GHC.Show.Show a => GHC.Show.Show (Data.Quantities.Data.QuantityError a) instance GHC.Classes.Ord Data.Quantities.Data.Definition instance GHC.Classes.Eq Data.Quantities.Data.Definition instance GHC.Show.Show Data.Quantities.Data.Definition instance GHC.Classes.Ord a => GHC.Classes.Ord (Data.Quantities.Data.Quantity a) instance GHC.Classes.Ord Data.Quantities.Data.CompoundUnit instance GHC.Classes.Eq Data.Quantities.Data.CompoundUnit instance GHC.Classes.Ord Data.Quantities.Data.Definitions instance GHC.Show.Show Data.Quantities.Data.Definitions instance GHC.Classes.Ord Data.Quantities.Data.SimpleUnit instance GHC.Classes.Eq Data.Quantities.Data.SimpleUnit instance GHC.Show.Show a => GHC.Show.Show (Data.Quantities.Data.Quantity a) instance GHC.Classes.Eq a => GHC.Classes.Eq (Data.Quantities.Data.Quantity a) instance GHC.Show.Show Data.Quantities.Data.CompoundUnit instance GHC.Classes.Eq Data.Quantities.Data.Definitions instance GHC.Show.Show Data.Quantities.Data.SimpleUnit -- | Module to perform unit conversions, compute dimensionality, and -- convert to base units. module Data.Quantities.Convert -- | Convert quantity to given units. -- --
-- >>> convert <$> fromString "m" <*> unitsFromString "ft" -- Right (Right 3.280839895013123 foot) --convert :: (Fractional a) => Quantity a -> CompoundUnit -> Either (QuantityError a) (Quantity a) -- | Convert a quantity to its base units. -- --
-- >>> convertBase <$> fromString "newton" -- Right 1000.0 gram meter / second ** 2 --convertBase :: (Fractional a) => Quantity a -> Quantity a -- | Convert quantity to given units. convert' :: (Fractional a) => Definitions -> Quantity a -> CompoundUnit -> Either (QuantityError a) (Quantity a) -- | Convert a quantity to its base units. convertBase' :: (Fractional a) => Definitions -> Quantity a -> Quantity a -- | Converts a composite unit to its base quantity toBase :: Definitions -> [SimpleUnit] -> Quantity Double -- | Converts a simple unit to its base quantity. simpleToBase :: Definitions -> SimpleUnit -> Quantity Double -- | Computes dimensionality of quantity. -- --
-- >>> dimensionality <$> fromString "newton" -- Right [length] [mass] / [time] ** 2 --dimensionality :: Quantity a -> CompoundUnit -- | Computes dimensionality of a list of SimpleUnits. Stores the -- dimensionality as a list of SimpleUnits as well, so we don't need a -- whole new type. dimensionality' :: Definitions -> [SimpleUnit] -> [SimpleUnit] -- | Adds two quantities. Second quantity is converted to units of first -- quantity. addQuants :: (Fractional a) => Quantity a -> Quantity a -> Either (QuantityError a) (Quantity a) -- | Subtract two quantities. Second quantity is converted to units of -- first quantity. subtractQuants :: (Fractional a) => Quantity a -> Quantity a -> Either (QuantityError a) (Quantity a) -- | Helper function used in addQuants and subtractQuants. linearQuants :: (Fractional a) => (a -> a -> a) -> Quantity a -> Quantity a -> Either (QuantityError a) (Quantity a) -- | Holds the default definition string. module Data.Quantities.DefaultUnits -- | View the source code for this declaration to see what units and -- prefixes are defined by default. -- -- This string holds the definitions for units and prefixes. Base units -- are defined by the name of the unit, the name of the base in brackets, -- and any aliases for the unit after that, all separated by equal signs: -- meter = [length] = m. Prefixes are defined by placing a dash -- after all identifiers, and providing a value for the prefix: -- milli- = 1e-3 = m-. Other units are defined by using -- previously defined units in an expression: minute = 60 * -- second = min. -- -- The reason these definitions aren't placed in a text file is so you -- don't have to operate your whole program in the IO monad. Users can -- copy this file into their source and modify definitions, or simply add -- a few definitions to the end of this string. -- -- These definitions are taken almost verbatim from the Pint unit -- conversion library for the Python programming language. Check them out -- on GitHub. defaultDefString :: String -- | Parse expressions with numbers and units. -- -- This module provides a basic expression grammar that parses numbers -- and units. module Data.Quantities.ExprParser -- | Alternate definition for spaces. Just actual spaces. spaces' :: Parser String -- | Parse quantity expression; addition and subtraction allowed. parseExprQuant :: Definitions -> String -> Either (QuantityError Double) (Quantity Double) -- | Simple type used for shorthand type EQuant = Either (QuantityError Double) (Quantity Double) -- | Using already compiled definitions, parse expression. Also allows for -- expressions like "exp1 => exp2" in the middle, which converts the -- quantity exp1 into the units of the quantity exp2. parseExpr :: Definitions -> Parser EQuant -- | Parser that accepts "=>" in between two expressions. parseConvertExpr :: Definitions -> Parser EQuant parseExpr' :: Definitions -> Parser EQuant parseTerm :: Definitions -> Parser EQuant parseFactor :: Definitions -> Parser EQuant parseExpt :: Definitions -> Parser EQuant parseNestedExpr :: Definitions -> Parser EQuant parseExptOp :: Definitions -> Parser EQuant parseTermOp :: Definitions -> Parser EQuant parseFactorOp :: Definitions -> Parser EQuant exptOp :: Parser (EQuant -> EQuant -> EQuant) addOp :: Parser (EQuant -> EQuant -> EQuant) mulOp :: Parser (EQuant -> EQuant -> EQuant) -- | Modification of addQuants to account for Either QuantityError -- Quantity. addEQuants :: EQuant -> EQuant -> EQuant -- | Modification of subtractQuants to account for Either QuantityError -- Quantity. subtractEQuants :: EQuant -> EQuant -> EQuant -- | Modification of multiplyQuants to account for Either QuantityError -- Quantity. multiplyEQuants :: EQuant -> EQuant -> EQuant -- | Modification of divideQuants to account for Either QuantityError -- Quantity. divideEQuants :: EQuant -> EQuant -> EQuant -- | Modification of exptQuants to account for Either QuantityError -- Quantity. Returns error if dimensional quantity used in exponent. exptEQuants :: EQuant -> EQuant -> EQuant -- | Modification of parseSymbolNum to handle parsing errors. parseESymbolNum :: Definitions -> Parser EQuant -- | Parses a symbol and then parses a prefix form that symbol. parseESymbol :: Definitions -> Parser EQuant -- | Parse a number and insert the given definitions into the CompoundUnit. parseENum :: Definitions -> Parser EQuant -- | Parses out prefixes and aliases from quantity's units. preprocessQuantity :: Definitions -> Quantity Double -> EQuant -- | Parses prefix and alias, if applicable, from a SimpleUnit. preprocessUnit :: Definitions -> SimpleUnit -> Either (QuantityError Double) SimpleUnit -- | Try to parse a prefix from a symbol. Otherwise, just return the -- symbol. prefixParser :: Definitions -> String -> (String, String) -- | Helper function for prefixParser that is a Parsec parser. prefixParser' :: Definitions -> Parser String -- | Converts string to a Quantity using an expression grammar parser. This -- parser does not parser addition or subtraction, and is used for unit -- definitions. parseMultExpr :: Parser (Quantity Double) parseMultExpr' :: Parser (Quantity Double) parseMultFactor :: Parser (Quantity Double) parseMultExpt :: Parser (Quantity Double) parseMultNestedExpr :: Parser (Quantity Double) parseMultExptOp :: Parser (Quantity Double) parseMultFactorOp :: Parser (Quantity Double) exptMultOp :: Parser (Quantity Double -> Quantity Double -> Quantity Double) mulMultOp :: Parser (Quantity Double -> Quantity Double -> Quantity Double) exptMultQuants' :: (Quantity Double -> Quantity Double -> Quantity Double) -- | Parse either a symbol or a number. parseSymbolNum :: Parser (Quantity Double) -- | Parse a symbol with an optional negative sign. A symbol can contain -- alphanumeric characters and the character '_'. parseSymbol' :: Parser (Quantity Double) -- | Parent function for parseNum' to parse a number. parseNum :: Parser (Quantity Double) -- | Meat of number parser. Parse digits with an optional negative sign and -- optional exponential. For example, -5.2e4. parseNum' :: Parser Double -- | Parses just the exponential part of a number. For example, parses "4" -- from "-5.2e4". parseExponential :: Parser String -- | Negate a number if the first argument is a negative sign. timesSign :: String -> Double -> Double -- | Uses parsec to parse definition lines. module Data.Quantities.DefinitionParser -- | Parse multiline string of definitions (say, from a file) into a list -- of definitions. parseDefinitions :: String -> [Definition] -- | Parsec parser for definitions. parseDefinitions' :: Parser [Definition] -- | Parse any definition line parseDef :: Parser Definition -- | Custom eol parsec parser. eol :: Parser Char -- | Parse a line containing unit definition Ex: minute = 60 s = min parseDefLine :: Parser Definition -- | Parses a unit definition. Example: foot = 12 in = ft = feet parseUnitDef :: Parser Definition -- | Parses the synonyms at the end of a base or unit definition. parseSynonym :: Parser Symbol -- | Parse line containing base definition. Ex: meter = [length] = m parseBaseLine :: Parser Definition -- | Parse the base of a base definition. Example: [length] -> length parseBase :: Parser (Symbol, Symbol) -- | Parse line containing prefix definition Ex: milli- = 1e-3 = m- parsePrefixLine :: Parser Definition -- | Parse the prefix part of a prefix definition. Example: yocto- -> -- yocto parsePrefix :: Parser (Symbol, Double) -- | Parse the synonyms for a prefix definition. parsePrefixSynonym :: Parser Symbol -- | Parse a symbol for a unit parseSymbol :: Parser Symbol -- | This module builds a Definitions object from a string. module Data.Quantities.Definitions -- | Convert string of definitions into Definitions structure. See -- source code for defaultDefString for an example. readDefinitions :: String -> Either (QuantityError Double) Definitions -- | Monad used for addDefinition. type DefineMonad = StateT Definitions (Either (QuantityError Double)) -- | Converts a list of definitions to the Definitions data structure. -- Modifies an emptyDefinitions object by combining the incremental -- additions of each Definition. makeDefinitions :: [Definition] -> Either (QuantityError Double) Definitions -- | Add one definition to the definitions. Creates a new Definitions -- object using the information in the Definition, and then unions the -- Definitions in the state monad with this new object. addDefinition :: Definition -> DefineMonad () -- | Computes intersection of two lists checkDefined :: [Symbol] -> [Symbol] -> [Symbol] -- | Variant of the DJB2 hash; -- http://stackoverflow.com/a/9263004/1333514 hash :: String -> Int -- | Add a hash of the definitions string to a group of Definitions. Meant -- to be the last step, after definitions are created. Used for -- Definitions comparison. addDefinitionsHash :: String -> Definitions -> Definitions -- | Defines the common constructors used to build quantities. module Data.Quantities.Constructors -- | Default set of definitions that come predefined. defaultDefinitions :: Either (QuantityError Double) Definitions -- | Create a Quantity by parsing a string. Uses an -- UndefinedUnitError for undefined units. Handles arithmetic -- expressions as well. -- --
-- >>> fromString "25 m/s" -- Right 25.0 meter / second -- -- >>> fromString "fakeunit" -- Left (UndefinedUnitError "fakeunit") -- -- >>> fromString "ft + 12in" -- Right 2.0 foot ---- -- This function also supports unit conversions, by placing "=>" in -- between two valid expressions. This behavior is undefined (and returns -- a ScalingFactorError) if the quantity to be converted to has a -- magnitude. -- --
-- >>> fromString "min => s" -- Right 60.0 second -- -- >>> fromString "2 ft + 6 in => ft" -- Right 2.5 foot -- -- >>> fromString "m => 3 ft" -- Left (ScalingFactorError 3.0 foot) ---- -- Make sure not to use dimensional quantities in exponents. -- --
-- >>> fromString "m ** 2" -- Right 1.0 meter ** 2 -- -- >>> fromString "m ** (2s)" -- Left (ParserError "Used non-dimensionless exponent in ( Right 1.0 meter ) ** ( Right 2.0 second )") --fromString :: String -> Either (QuantityError Double) (Quantity Double) -- | Create quantities with custom definitions. -- --
-- >>> let myDefString = defaultDefString ++ "\nmy_unit = 100 s" -- -- >>> let (Right d) = readDefinitions myDefString -- -- >>> let myFromString = fromString' d -- -- >>> myFromString "25 my_unit" -- Right 25.0 my_unit --fromString' :: Definitions -> String -> Either (QuantityError Double) (Quantity Double) -- | Parse units from a string. Equivalent to fmap units . -- fromString -- --
-- >>> unitsFromString "N * s" -- Right newton second --unitsFromString :: String -> Either (QuantityError Double) CompoundUnit -- | This package is used to create and manipulate physical quantities, -- which are a numerical value associated with a unit of measurement. -- -- In this package, values with units are represented with the Quantity -- type. Included is an expression parser and a huge list of predefined -- quantities with which to parse strings into a Quantity datatype. Once -- created, a quantity can be converted to different units or queried for -- its dimensionality. A user can also operate on quantities -- arithmetically, and doing so uses automatic unit conversion and -- simplification. module Data.Quantities -- | Create a Quantity by parsing a string. Uses an -- UndefinedUnitError for undefined units. Handles arithmetic -- expressions as well. -- --
-- >>> fromString "25 m/s" -- Right 25.0 meter / second -- -- >>> fromString "fakeunit" -- Left (UndefinedUnitError "fakeunit") -- -- >>> fromString "ft + 12in" -- Right 2.0 foot ---- -- This function also supports unit conversions, by placing "=>" in -- between two valid expressions. This behavior is undefined (and returns -- a ScalingFactorError) if the quantity to be converted to has a -- magnitude. -- --
-- >>> fromString "min => s" -- Right 60.0 second -- -- >>> fromString "2 ft + 6 in => ft" -- Right 2.5 foot -- -- >>> fromString "m => 3 ft" -- Left (ScalingFactorError 3.0 foot) ---- -- Make sure not to use dimensional quantities in exponents. -- --
-- >>> fromString "m ** 2" -- Right 1.0 meter ** 2 -- -- >>> fromString "m ** (2s)" -- Left (ParserError "Used non-dimensionless exponent in ( Right 1.0 meter ) ** ( Right 2.0 second )") --fromString :: String -> Either (QuantityError Double) (Quantity Double) -- | Parse units from a string. Equivalent to fmap units . -- fromString -- --
-- >>> unitsFromString "N * s" -- Right newton second --unitsFromString :: String -> Either (QuantityError Double) CompoundUnit -- | Holds information about defined units, prefixes, and bases. Used when -- parsing new units and performing units conversions. data Definitions -- | Combination of magnitude and units. data Quantity a -- | Numerical magnitude of quantity. -- --
-- >>> magnitude <$> fromString "100 N * m" -- Right 100.0 --magnitude :: Quantity a -> a -- | Units associated with quantity. -- --
-- >>> units <$> fromString "3.4 m/s^2" -- Right meter / second ** 2 --units :: Quantity a -> CompoundUnit -- | Data type to hold compound units, which are simple units multiplied -- together. data CompoundUnit -- | Convert quantity to given units. -- --
-- >>> convert <$> fromString "m" <*> unitsFromString "ft" -- Right (Right 3.280839895013123 foot) --convert :: (Fractional a) => Quantity a -> CompoundUnit -> Either (QuantityError a) (Quantity a) -- | Convert a quantity to its base units. -- --
-- >>> convertBase <$> fromString "newton" -- Right 1000.0 gram meter / second ** 2 --convertBase :: (Fractional a) => Quantity a -> Quantity a -- | Computes dimensionality of quantity. -- --
-- >>> dimensionality <$> fromString "newton" -- Right [length] [mass] / [time] ** 2 --dimensionality :: Quantity a -> CompoundUnit -- | Adds two quantities. Second quantity is converted to units of first -- quantity. addQuants :: (Fractional a) => Quantity a -> Quantity a -> Either (QuantityError a) (Quantity a) -- | Subtract two quantities. Second quantity is converted to units of -- first quantity. subtractQuants :: (Fractional a) => Quantity a -> Quantity a -> Either (QuantityError a) (Quantity a) -- | Multiplies two quantities. multiplyQuants :: (Num a) => Quantity a -> Quantity a -> Quantity a -- | Divides two quantities. divideQuants :: (Fractional a) => Quantity a -> Quantity a -> Quantity a -- | Exponentiates a quantity with an integer exptQuants :: (Real a, Floating a) => Quantity a -> a -> Quantity a -- | Create quantities with custom definitions. -- --
-- >>> let myDefString = defaultDefString ++ "\nmy_unit = 100 s" -- -- >>> let (Right d) = readDefinitions myDefString -- -- >>> let myFromString = fromString' d -- -- >>> myFromString "25 my_unit" -- Right 25.0 my_unit --fromString' :: Definitions -> String -> Either (QuantityError Double) (Quantity Double) -- | Convert string of definitions into Definitions structure. See -- source code for defaultDefString for an example. readDefinitions :: String -> Either (QuantityError Double) Definitions -- | View the source code for this declaration to see what units and -- prefixes are defined by default. -- -- This string holds the definitions for units and prefixes. Base units -- are defined by the name of the unit, the name of the base in brackets, -- and any aliases for the unit after that, all separated by equal signs: -- meter = [length] = m. Prefixes are defined by placing a dash -- after all identifiers, and providing a value for the prefix: -- milli- = 1e-3 = m-. Other units are defined by using -- previously defined units in an expression: minute = 60 * -- second = min. -- -- The reason these definitions aren't placed in a text file is so you -- don't have to operate your whole program in the IO monad. Users can -- copy this file into their source and modify definitions, or simply add -- a few definitions to the end of this string. -- -- These definitions are taken almost verbatim from the Pint unit -- conversion library for the Python programming language. Check them out -- on GitHub. defaultDefString :: String -- | Custom error type data QuantityError a -- | Used when trying to parse an undefined unit. UndefinedUnitError :: String -> QuantityError a -- | Used when converting units that do not have the same dimensionality -- (example: convert meter to second). DimensionalityError :: CompoundUnit -> CompoundUnit -> QuantityError a -- | Used internally when defining units and a unit is already defined. UnitAlreadyDefinedError :: String -> QuantityError a -- | Used internally when defining units and a prefix is already defined. PrefixAlreadyDefinedError :: String -> QuantityError a -- | Used when a string cannot be parsed. ParserError :: String -> QuantityError a -- | Used when two quantities come from different Definitions. DifferentDefinitionsError :: CompoundUnit -> CompoundUnit -> QuantityError a -- | Used when a scaling factor is present in a unit conversion. ScalingFactorError :: (Quantity a) -> QuantityError a -- | Useful for monadic computations with QuantityErrors. Some -- examples: -- --
-- computation :: QuantityComputation Quantity -- computation = do -- x <- fromString "mile/hr" -- y <- unitsFromString "m/s" -- convert x y ---- -- Returns Right 0.44704 meter / second -- --
-- computation :: QuantityComputation Quantity -- computation = do -- x <- fromString "BADUNIT" -- convertBase x ---- -- Returns Left (UndefinedUnitError BADUNIT) type QuantityComputation a = Either (QuantityError a)