-- Hoogle documentation, generated by Haddock
-- See Hoogle, http://www.haskell.org/hoogle/


-- | Statically checked physical dimensions,
--   using Type Families and Data Kinds.
--   
--   Dimensional is a library providing data types for performing
--   arithmetic with physical quantities and units. Information about the
--   physical dimensions of the quantities and units is embedded in their
--   types and the validity of operations is verified by the type checker
--   at compile time. The boxing and unboxing of numerical values as
--   quantities is done by multiplication and division with units. The
--   library is designed to, as far as is practical, enforce/encourage best
--   practices of unit usage. Version 1 of the dimensional package differs
--   from earlier version in that the dimension tracking is implemented
--   using Closed Type Families and Data Kinds rather than functional
--   dependencies. This enables a number of features, including improved
--   support for unit names and quantities with statically-unknown
--   dimensions. Requires GHC 7.8 or later.
@package dimensional
@version 1.0.1.3


-- | Provides a type level representation of <a>Variant</a>s of dimensional
--   values, which may be quantities or units.
module Numeric.Units.Dimensional.Variants

-- | The kind of variants of dimensional values.
data Variant

-- | The value is a quantity.
DQuantity :: Variant

-- | The value is a unit, possibly a <a>Metric</a> unit.
DUnit :: Metricality -> Variant

-- | Encodes whether a unit is a metric unit, that is, whether it can be
--   combined with a metric prefix to form a related unit.
data Metricality

-- | Capable of receiving a metric prefix.
Metric :: Metricality

-- | Incapable of receiving a metric prefix.
NonMetric :: Metricality

-- | Forms the product of two <a>Variant</a>s.
--   
--   The product of units is a non-metric unit.
--   
--   The product of quantities is a quantity.

-- | Weakens a <a>Variant</a> by forgetting possibly uninteresting
--   type-level information.
instance GHC.Generics.Generic Numeric.Units.Dimensional.Variants.Variant
instance Data.Data.Data Numeric.Units.Dimensional.Variants.Variant
instance GHC.Classes.Ord Numeric.Units.Dimensional.Variants.Variant
instance GHC.Classes.Eq Numeric.Units.Dimensional.Variants.Variant
instance GHC.Generics.Generic Numeric.Units.Dimensional.Variants.Metricality
instance Data.Data.Data Numeric.Units.Dimensional.Variants.Metricality
instance GHC.Classes.Ord Numeric.Units.Dimensional.Variants.Metricality
instance GHC.Classes.Eq Numeric.Units.Dimensional.Variants.Metricality

module Numeric.Units.Dimensional.UnitNames.InterchangeNames

-- | Represents the authority which issued an interchange name for a unit.
data InterchangeNameAuthority

-- | The interchange name originated with the Unified Code for Units of
--   Measure.
UCUM :: InterchangeNameAuthority

-- | The interchange name originated with the dimensional library.
DimensionalLibrary :: InterchangeNameAuthority

-- | The interchange name originated with a user of the dimensional
--   library.
Custom :: InterchangeNameAuthority
data InterchangeName
InterchangeName :: String -> InterchangeNameAuthority -> InterchangeName
[name] :: InterchangeName -> String
[authority] :: InterchangeName -> InterchangeNameAuthority

-- | Determines the authority which issued the interchange name of a unit
--   or unit name. For composite units, this is the least-authoritative
--   interchange name of any constituent name.
--   
--   Note that the least-authoritative authority is the one sorted as
--   greatest by the <a>Ord</a> instance of
--   <a>InterchangeNameAuthority</a>.
class HasInterchangeName a
interchangeName :: HasInterchangeName a => a -> InterchangeName
instance GHC.Generics.Generic Numeric.Units.Dimensional.UnitNames.InterchangeNames.InterchangeName
instance Data.Data.Data Numeric.Units.Dimensional.UnitNames.InterchangeNames.InterchangeName
instance GHC.Classes.Ord Numeric.Units.Dimensional.UnitNames.InterchangeNames.InterchangeName
instance GHC.Classes.Eq Numeric.Units.Dimensional.UnitNames.InterchangeNames.InterchangeName
instance GHC.Generics.Generic Numeric.Units.Dimensional.UnitNames.InterchangeNames.InterchangeNameAuthority
instance Data.Data.Data Numeric.Units.Dimensional.UnitNames.InterchangeNames.InterchangeNameAuthority
instance GHC.Show.Show Numeric.Units.Dimensional.UnitNames.InterchangeNames.InterchangeNameAuthority
instance GHC.Classes.Ord Numeric.Units.Dimensional.UnitNames.InterchangeNames.InterchangeNameAuthority
instance GHC.Classes.Eq Numeric.Units.Dimensional.UnitNames.InterchangeNames.InterchangeNameAuthority
instance GHC.Show.Show Numeric.Units.Dimensional.UnitNames.InterchangeNames.InterchangeName
instance Numeric.Units.Dimensional.UnitNames.InterchangeNames.HasInterchangeName Numeric.Units.Dimensional.UnitNames.InterchangeNames.InterchangeName


-- | This module defines physical dimensions expressed in terms of the SI
--   base dimensions, including arithmetic.
module Numeric.Units.Dimensional.Dimensions.TermLevel

-- | A physical dimension, encoded as 7 integers, representing a
--   factorization of the dimension into the 7 SI base dimensions. By
--   convention they are stored in the same order as in the
--   <a>Dimension</a> data kind.
data Dimension'
Dim' :: !Int -> !Int -> !Int -> !Int -> !Int -> !Int -> !Int -> Dimension'

-- | Dimensional values inhabit this class, which allows access to a
--   term-level representation of their dimension.
class HasDimension a

-- | Obtains a term-level representation of a value's dimension.
dimension :: HasDimension a => a -> Dimension'

-- | Forms the product of two dimensions.
(*) :: Dimension' -> Dimension' -> Dimension'
infixl 7 *

-- | Forms the quotient of two dimensions.
(/) :: Dimension' -> Dimension' -> Dimension'
infixl 7 /

-- | Raises a dimension to an integer power.
(^) :: Dimension' -> Int -> Dimension'
infixr 8 ^

-- | Forms the reciprocal of a dimension.
recip :: Dimension' -> Dimension'

-- | The dimension of dimensionless values.
dOne :: Dimension'
dLength :: Dimension'
dMass :: Dimension'
dTime :: Dimension'
dElectricCurrent :: Dimension'
dThermodynamicTemperature :: Dimension'
dAmountOfSubstance :: Dimension'
dLuminousIntensity :: Dimension'

-- | Converts a dimension to a list of 7 integers, representing the
--   exponent associated with each of the 7 SI base dimensions in the
--   standard order.
asList :: Dimension' -> [Int]
instance GHC.Classes.Ord Numeric.Units.Dimensional.Dimensions.TermLevel.Dimension'
instance GHC.Classes.Eq Numeric.Units.Dimensional.Dimensions.TermLevel.Dimension'
instance GHC.Show.Show Numeric.Units.Dimensional.Dimensions.TermLevel.Dimension'
instance GHC.Base.Monoid Numeric.Units.Dimensional.Dimensions.TermLevel.Dimension'
instance Numeric.Units.Dimensional.Dimensions.TermLevel.HasDimension Numeric.Units.Dimensional.Dimensions.TermLevel.Dimension'


-- | This module defines type-level physical dimensions expressed in terms
--   of the SI base dimensions using <a>NumType</a> for type-level
--   integers.
--   
--   Type-level arithmetic, synonyms for the base dimensions, and
--   conversion to the term-level are included.
module Numeric.Units.Dimensional.Dimensions.TypeLevel

-- | Represents a physical dimension in the basis of the 7 SI base
--   dimensions, where the respective dimensions are represented by type
--   variables using the following convention.
--   
--   <ul>
--   <li>l: Length</li>
--   <li>m: Mass</li>
--   <li>t: Time</li>
--   <li>i: Electric current</li>
--   <li>th: Thermodynamic temperature</li>
--   <li>n: Amount of substance</li>
--   <li>j: Luminous intensity</li>
--   </ul>
--   
--   For the equivalent term-level representation, see <a>Dimension'</a>
data Dimension
Dim :: TypeInt -> TypeInt -> TypeInt -> TypeInt -> TypeInt -> TypeInt -> TypeInt -> Dimension

-- | Multiplication of dimensions corresponds to adding of the base
--   dimensions' exponents.

-- | Division of dimensions corresponds to subtraction of the base
--   dimensions' exponents.

-- | Powers of dimensions corresponds to multiplication of the base
--   dimensions' exponents by the exponent.
--   
--   We limit ourselves to integer powers of Dimensionals as fractional
--   powers make little physical sense.

-- | The reciprocal of a dimension is defined as the result of dividing
--   <a>DOne</a> by it, or of negating each of the base dimensions'
--   exponents.
type Recip (d :: Dimension) = DOne / d

-- | Roots of dimensions corresponds to division of the base dimensions'
--   exponents by the order(?) of the root.
--   
--   See <a>sqrt</a>, <tt>cbrt</tt>, and <tt>nroot</tt> for the
--   corresponding term-level operations.

-- | The type-level dimensions of dimensionless values.
type DOne = Dim Zero Zero Zero Zero Zero Zero Zero
type DLength = Dim Pos1 Zero Zero Zero Zero Zero Zero
type DMass = Dim Zero Pos1 Zero Zero Zero Zero Zero
type DTime = Dim Zero Zero Pos1 Zero Zero Zero Zero
type DElectricCurrent = Dim Zero Zero Zero Pos1 Zero Zero Zero
type DThermodynamicTemperature = Dim Zero Zero Zero Zero Pos1 Zero Zero
type DAmountOfSubstance = Dim Zero Zero Zero Zero Zero Pos1 Zero
type DLuminousIntensity = Dim Zero Zero Zero Zero Zero Zero Pos1

-- | A KnownDimension is one for which we can construct a term-level
--   representation. Each validly constructed type of kind <a>Dimension</a>
--   has a <a>KnownDimension</a> instance.
--   
--   While <a>KnownDimension</a> is a constraint synonym, the presence of
--   <tt><a>KnownDimension</a> d</tt> in a context allows use of
--   <tt><a>dimension</a> :: <a>Proxy</a> d -&gt; <a>Dimension'</a></tt>.
type KnownDimension (d :: Dimension) = HasDimension (Proxy d)
instance (Numeric.NumType.DK.Integers.KnownTypeInt l, Numeric.NumType.DK.Integers.KnownTypeInt m, Numeric.NumType.DK.Integers.KnownTypeInt t, Numeric.NumType.DK.Integers.KnownTypeInt i, Numeric.NumType.DK.Integers.KnownTypeInt th, Numeric.NumType.DK.Integers.KnownTypeInt n, Numeric.NumType.DK.Integers.KnownTypeInt j) => Numeric.Units.Dimensional.Dimensions.TermLevel.HasDimension (Data.Proxy.Proxy ('Numeric.Units.Dimensional.Dimensions.TypeLevel.Dim l m t i th n j))


-- | This module provides types and functions for manipulating unit names.
--   
--   Please note that the details of the name representation may be less
--   stable than the other APIs provided by this package, as new features
--   using them are still being developed.
module Numeric.Units.Dimensional.UnitNames

-- | The name of a unit.
data UnitName (m :: Metricality)

-- | Represents the name of an atomic unit or prefix.
data NameAtom (m :: NameAtomType)

-- | The name of a metric prefix.
type PrefixName = NameAtom PrefixAtom

-- | Encodes whether a unit is a metric unit, that is, whether it can be
--   combined with a metric prefix to form a related unit.
data Metricality

-- | Capable of receiving a metric prefix.
Metric :: Metricality

-- | Incapable of receiving a metric prefix.
NonMetric :: Metricality

-- | Constructs an atomic name for a custom unit.
atom :: String -> String -> String -> UnitName NonMetric

-- | Forms a <a>UnitName</a> from a <a>Metric</a> name by applying a metric
--   prefix.
applyPrefix :: PrefixName -> UnitName Metric -> UnitName NonMetric

-- | Form a <a>UnitName</a> by taking the product of two others.
(*) :: UnitName m1 -> UnitName m2 -> UnitName NonMetric
infixl 7 *

-- | Form a <a>UnitName</a> by dividing one by another.
(/) :: UnitName m1 -> UnitName m2 -> UnitName NonMetric
infixl 7 /

-- | Form a <a>UnitName</a> by raising a name to an integer power.
(^) :: UnitName m -> Int -> UnitName NonMetric
infixr 8 ^

-- | Forms the product of a list of <a>UnitName</a>s.
--   
--   If you wish to form a heterogenous product of <a>Metric</a> and
--   <a>NonMetric</a> units you should apply <a>weaken</a> to the
--   <a>Metric</a> ones.
product :: Foldable f => f (UnitName NonMetric) -> UnitName NonMetric
reduce :: UnitName m -> UnitName m

-- | Constructs a <a>UnitName</a> by applying a grouping operation to
--   another <a>UnitName</a>, which may be useful to express precedence.
grouped :: UnitName m -> UnitName NonMetric

-- | The name of the base unit associated with a specified dimension.
baseUnitName :: Dimension' -> UnitName NonMetric
nOne :: UnitName NonMetric
nMeter :: UnitName Metric
nGram :: UnitName Metric
nKilogram :: UnitName NonMetric
nSecond :: UnitName Metric
nAmpere :: UnitName Metric
nKelvin :: UnitName Metric
nMole :: UnitName Metric
nCandela :: UnitName Metric
deka :: PrefixName
hecto :: PrefixName
kilo :: PrefixName
mega :: PrefixName
giga :: PrefixName
tera :: PrefixName
peta :: PrefixName
exa :: PrefixName
zetta :: PrefixName
yotta :: PrefixName
deci :: PrefixName
centi :: PrefixName
milli :: PrefixName
micro :: PrefixName
nano :: PrefixName
pico :: PrefixName
femto :: PrefixName
atto :: PrefixName
zepto :: PrefixName
yocto :: PrefixName

-- | The type of a unit name transformation that may be associated with an
--   operation that takes a single unit as input.
type UnitNameTransformer = forall m. UnitName m -> UnitName NonMetric

-- | The type of a unit name transformation that may be associated with an
--   operation that takes two units as input.
type UnitNameTransformer2 = forall m1 m2. UnitName m1 -> UnitName m2 -> UnitName NonMetric

-- | Convert a <a>UnitName</a> which may or may not be <a>Metric</a> to one
--   which is certainly <a>NonMetric</a>.
weaken :: UnitName m -> UnitName NonMetric

-- | Attempt to convert a <a>UnitName</a> which may or may not be
--   <a>Metric</a> to one which is certainly <a>Metric</a>.
strengthen :: UnitName m -> Maybe (UnitName Metric)

-- | Convert a <a>UnitName</a> of one <a>Metricality</a> into a name of the
--   other metricality by strengthening or weakening if neccessary. Because
--   it may not be possible to strengthen, the result is returned in a
--   <a>Maybe</a> wrapper.
relax :: forall m1 m2. (Typeable m1, Typeable m2) => UnitName m1 -> Maybe (UnitName m2)


-- | Provides both term-level and type-level representations for physical
--   dimensions in a single import for convenience.
--   
--   Presuming that users intend to work primarily with type level
--   dimensions, this module hides arithmetic operators over term level
--   dimensions and aliases for the base term-level dimensions to avoid
--   namespace pollution. These features are available directly from
--   <a>Numeric.Units.Dimensional.Dimensions.TermLevel</a> if desired.
module Numeric.Units.Dimensional.Dimensions


-- | Re-exports the raw <a>Quantity</a> constructor from the
--   Numeric.Units.Dimensional.Internal module, along with <a>coerce</a>,
--   for convenience in converting between raw representations and
--   dimensional values.
--   
--   Note that use of these constructs requires the user to verify the
--   dimensional safety of the conversion, because the coercion doesn't
--   explicitly mention the unit of the representation.
--   
--   Note that the haddock documentation doesn't mention the
--   <a>Quantity</a> constructor because it is a part of the
--   <a>Dimensional</a> associated data family, but it is exported by this
--   module.
module Numeric.Units.Dimensional.Coercion

-- | The function <tt>coerce</tt> allows you to safely convert between
--   values of types that have the same representation with no run-time
--   overhead. In the simplest case you can use it instead of a newtype
--   constructor, to go from the newtype's concrete type to the abstract
--   type. But it also works in more complicated settings, e.g. converting
--   a list of newtypes to a list of concrete types.
coerce :: Coercible * a b => a -> b


-- | <h1>Summary</h1>
--   
--   In this module we provide data types for performing arithmetic with
--   physical quantities and units. Information about the physical
--   dimensions of the quantities/units is embedded in their types and the
--   validity of operations is verified by the type checker at compile
--   time. The boxing and unboxing of numerical values as quantities is
--   done by multiplication and division of units, of which an incomplete
--   set is provided.
--   
--   We limit ourselves to "Newtonian" physics. We do not attempt to
--   accommodate relativistic physics in which e.g. addition of length and
--   time would be valid.
--   
--   As far as possible and/or practical the conventions and guidelines of
--   NIST's "Guide for the Use of the International System of Units (SI)"
--   <a>[1]</a> are followed. Occasionally we will reference specific
--   sections from the guide and deviations will be explained.
--   
--   <h2>Disclaimer</h2>
--   
--   Merely an engineer, the author doubtlessly uses a language and
--   notation that makes mathematicians and physicist cringe. He does not
--   mind constructive criticism (or pull requests).
--   
--   The sets of functions and units defined herein are incomplete and
--   reflect only the author's needs to date. Again, patches are welcome.
--   
--   <h1>Usage</h1>
--   
--   <h2>Preliminaries</h2>
--   
--   This module requires GHC 7.8 or later. We utilize Data Kinds,
--   TypeNats, Closed Type Families, etc. Clients of the module are
--   generally not required to use these extensions.
--   
--   Clients probably will want to use the NegativeLiterals extension.
--   
--   <h2>Examples</h2>
--   
--   We have defined operators and units that allow us to define and work
--   with physical quantities. A physical quantity is defined by
--   multiplying a number with a unit (the type signature is optional).
--   
--   <pre>
--   v :: Velocity Prelude.Double
--   v = 90 *~ (kilo meter / hour)
--   </pre>
--   
--   It follows naturally that the numerical value of a quantity is
--   obtained by division by a unit.
--   
--   <pre>
--   numval :: Prelude.Double
--   numval = v /~ (meter / second)
--   </pre>
--   
--   The notion of a quantity as the product of a numerical value and a
--   unit is supported by 7.1 "Value and numerical value of a quantity" of
--   <a>[1]</a>. While the above syntax is fairly natural it is unfortunate
--   that it must violate a number of the guidelines in <a>[1]</a>, in
--   particular 9.3 "Spelling unit names with prefixes", 9.4 "Spelling unit
--   names obtained by multiplication", 9.5 "Spelling unit names obtained
--   by division".
--   
--   As a more elaborate example of how to use the module we define a
--   function for calculating the escape velocity of a celestial body
--   <a>[2]</a>.
--   
--   <pre>
--   escapeVelocity :: (Floating a) =&gt; Mass a -&gt; Length a -&gt; Velocity a
--   escapeVelocity m r = sqrt (two * g * m / r)
--     where
--         two = 2 *~ one
--         g = 6.6720e-11 *~ (newton * meter ^ pos2 / kilo gram ^ pos2)
--   </pre>
--   
--   The following is an example GHC session where the above function is
--   used to calculate the escape velocity of Earth in kilometer per
--   second.
--   
--   <pre>
--   &gt;&gt;&gt; :set +t
--   
--   &gt;&gt;&gt; let me = 5.9742e24 *~ kilo gram -- Mass of Earth.
--   me :: Quantity DMass GHC.Float.Double
--   
--   &gt;&gt;&gt; let re = 6372.792 *~ kilo meter -- Mean radius of Earth.
--   re :: Quantity DLength GHC.Float.Double
--   
--   &gt;&gt;&gt; let ve = escapeVelocity me re   -- Escape velocity of Earth.
--   ve :: Velocity GHC.Float.Double
--   
--   &gt;&gt;&gt; ve /~ (kilo meter / second)
--   11.184537332296259
--   it :: GHC.Float.Double
--   </pre>
--   
--   For completeness we should also show an example of the error messages
--   we will get from GHC when performing invalid arithmetic. In the best
--   case GHC will be able to use the type synonyms we have defined in its
--   error messages.
--   
--   <pre>
--   &gt;&gt;&gt; x = 1 *~ meter + 1 *~ second
--   Couldn't match type 'Numeric.NumType.DK.Integers.Zero
--                  with 'Numeric.NumType.DK.Integers.Pos1
--     Expected type: Unit 'Metric DLength a
--       Actual type: Unit 'Metric DTime a
--     In the second argument of `(*~)', namely `second'
--     In the second argument of `(+)', namely `1 *~ second'
--   </pre>
--   
--   In other cases the error messages aren't very friendly.
--   
--   <pre>
--   &gt;&gt;&gt; x = 1 *~ meter / (1 *~ second) + 1 *~ kilo gram
--   Couldn't match type 'Numeric.NumType.DK.Integers.Zero
--                  with 'Numeric.NumType.DK.Integers.Neg1
--     Expected type: Quantity DMass a
--       Actual type: Dimensional
--                      ('Numeric.Units.Dimensional.Variants.DQuantity
--                       Numeric.Units.Dimensional.Variants.* 'Numeric.Units.Dimensional.Variants.DQuantity)
--                      (DLength / DTime)
--                      a
--     In the first argument of `(+)', namely `1 *~ meter / (1 *~ second)'
--     In the expression: 1 *~ meter / (1 *~ second) + 1 *~ kilo gram
--     In an equation for `x':
--         x = 1 *~ meter / (1 *~ second) + 1 *~ kilo gram
--   </pre>
--   
--   It is the author's experience that the usefullness of the compiler
--   error messages is more often than not limited to pinpointing the
--   location of errors.
--   
--   <h1>Notes</h1>
--   
--   <h2>Future work</h2>
--   
--   While there is an insane amount of units in use around the world it is
--   reasonable to provide at least all SI units. Units outside of SI will
--   most likely be added on an as-needed basis.
--   
--   There are also plenty of elementary functions to add. The
--   <a>Floating</a> class can be used as reference.
--   
--   Additional physics models could be implemented. See <a>[3]</a> for
--   ideas.
--   
--   <h2>Related work</h2>
--   
--   Henning Thielemann numeric prelude has a physical units library,
--   however, checking of dimensions is dynamic rather than static. Aaron
--   Denney has created a toy example of statically checked physical
--   dimensions covering only length and time. HaskellWiki has pointers
--   <a>[4]</a> to these.
--   
--   Also see Samuel Hoffstaetter's blog post <a>[5]</a> which uses
--   techniques similar to this library.
--   
--   Libraries with similar functionality exist for other programming
--   languages and may serve as inspiration. The author has found the Java
--   library JScience <a>[6]</a> and the Fortress programming language
--   <a>[7]</a> particularly noteworthy.
--   
--   <h2>References</h2>
--   
--   <ol>
--   <li><a>http://physics.nist.gov/Pubs/SP811/</a></li>
--   <li><a>http://en.wikipedia.org/wiki/Escape_velocity</a></li>
--   
--   <li><a>http://jscience.org/api/org/jscience/physics/models/package-summary.html</a></li>
--   <li><a>http://www.haskell.org/haskellwiki/Physical_units</a></li>
--   
--   <li><a>http://liftm.wordpress.com/2007/06/03/scientificdimension-type-arithmetic-and-physical-units-in-haskell/</a></li>
--   <li><a>http://jscience.org/</a></li>
--   <li><a>http://research.sun.com/projects/plrg/fortress.pdf</a></li>
--   </ol>
module Numeric.Units.Dimensional

-- | A unit of measurement.
type Unit (m :: Metricality) = Dimensional (DUnit m)

-- | A dimensional quantity.
type Quantity = Dimensional DQuantity

-- | Encodes whether a unit is a metric unit, that is, whether it can be
--   combined with a metric prefix to form a related unit.
data Metricality

-- | Capable of receiving a metric prefix.
Metric :: Metricality

-- | Incapable of receiving a metric prefix.
NonMetric :: Metricality

-- | Represents a physical dimension in the basis of the 7 SI base
--   dimensions, where the respective dimensions are represented by type
--   variables using the following convention.
--   
--   <ul>
--   <li>l: Length</li>
--   <li>m: Mass</li>
--   <li>t: Time</li>
--   <li>i: Electric current</li>
--   <li>th: Thermodynamic temperature</li>
--   <li>n: Amount of substance</li>
--   <li>j: Luminous intensity</li>
--   </ul>
--   
--   For the equivalent term-level representation, see <a>Dimension'</a>
data Dimension
Dim :: TypeInt -> TypeInt -> TypeInt -> TypeInt -> TypeInt -> TypeInt -> TypeInt -> Dimension

-- | Multiplication of dimensions corresponds to adding of the base
--   dimensions' exponents.

-- | Division of dimensions corresponds to subtraction of the base
--   dimensions' exponents.

-- | Powers of dimensions corresponds to multiplication of the base
--   dimensions' exponents by the exponent.
--   
--   We limit ourselves to integer powers of Dimensionals as fractional
--   powers make little physical sense.

-- | Roots of dimensions corresponds to division of the base dimensions'
--   exponents by the order(?) of the root.
--   
--   See <a>sqrt</a>, <tt>cbrt</tt>, and <tt>nroot</tt> for the
--   corresponding term-level operations.

-- | The reciprocal of a dimension is defined as the result of dividing
--   <a>DOne</a> by it, or of negating each of the base dimensions'
--   exponents.
type Recip (d :: Dimension) = DOne / d

-- | A physical dimension, encoded as 7 integers, representing a
--   factorization of the dimension into the 7 SI base dimensions. By
--   convention they are stored in the same order as in the
--   <a>Dimension</a> data kind.
data Dimension'
Dim' :: !Int -> !Int -> !Int -> !Int -> !Int -> !Int -> !Int -> Dimension'

-- | Dimensional values inhabit this class, which allows access to a
--   term-level representation of their dimension.
class HasDimension a

-- | Obtains a term-level representation of a value's dimension.
dimension :: HasDimension a => a -> Dimension'

-- | A KnownDimension is one for which we can construct a term-level
--   representation. Each validly constructed type of kind <a>Dimension</a>
--   has a <a>KnownDimension</a> instance.
--   
--   While <a>KnownDimension</a> is a constraint synonym, the presence of
--   <tt><a>KnownDimension</a> d</tt> in a context allows use of
--   <tt><a>dimension</a> :: <a>Proxy</a> d -&gt; <a>Dimension'</a></tt>.
type KnownDimension (d :: Dimension) = HasDimension (Proxy d)

-- | Forms a <a>Quantity</a> by multipliying a number and a unit.
(*~) :: Num a => a -> Unit m d a -> Quantity d a
infixl 7 *~

-- | Divides a <a>Quantity</a> by a <a>Unit</a> of the same physical
--   dimension, obtaining the numerical value of the quantity expressed in
--   that unit.
(/~) :: Fractional a => Quantity d a -> Unit m d a -> a
infixl 7 /~

-- | Raises a <a>Quantity</a> or <a>Unit</a> to an integer power.
--   
--   Because the power chosen impacts the <a>Dimension</a> of the result,
--   it is necessary to supply a type-level representation of the exponent
--   in the form of a <a>Proxy</a> to some <a>TypeInt</a>. Convenience
--   values <tt>pos1</tt>, <a>pos2</a>, <tt>neg1</tt>, ... are supplied by
--   the <a>Numeric.NumType.DK.Integers</a> module. The most commonly used
--   ones are also reexported by <a>Numeric.Units.Dimensional.Prelude</a>.
--   
--   The intimidating type signature captures the similarity between these
--   operations and ensures that composite <a>Unit</a>s are
--   <tt>NotPrefixable</tt>.
(^) :: (Fractional a, KnownTypeInt i, KnownVariant v, KnownVariant (Weaken v)) => Dimensional v d1 a -> Proxy i -> Dimensional (Weaken v) (d1 ^ i) a
infixr 8 ^

-- | Computes the nth root of a <a>Quantity</a> using <a>**</a>.
--   
--   The <a>Root</a> type family will prevent application of this operator
--   where the result would have a fractional dimension or where n is zero.
--   
--   Because the root chosen impacts the <a>Dimension</a> of the result, it
--   is necessary to supply a type-level representation of the root in the
--   form of a <a>Proxy</a> to some <a>TypeInt</a>. Convenience values
--   <tt>pos1</tt>, <a>pos2</a>, <tt>neg1</tt>, ... are supplied by the
--   <a>Numeric.NumType.DK.Integers</a> module. The most commonly used ones
--   are also reexported by <a>Numeric.Units.Dimensional.Prelude</a>.
--   
--   Also available in prefix form, see <a>nroot</a>.
(^/) :: (KnownTypeInt n, Floating a) => Quantity d a -> Proxy n -> Quantity (Root d n) a
infixr 8 ^/

-- | Raises a dimensionless quantity to a floating power using <a>**</a>.
(**) :: Floating a => Dimensionless a -> Dimensionless a -> Dimensionless a
infixr 8 **

-- | Multiplies two <a>Quantity</a>s or two <a>Unit</a>s.
--   
--   The intimidating type signature captures the similarity between these
--   operations and ensures that composite <a>Unit</a>s are
--   <a>NonMetric</a>.
(*) :: (KnownVariant v1, KnownVariant v2, KnownVariant (v1 * v2), Num a) => Dimensional v1 d1 a -> Dimensional v2 d2 a -> Dimensional (v1 * v2) (d1 * d2) a
infixl 7 *

-- | Divides one <a>Quantity</a> by another or one <a>Unit</a> by another.
--   
--   The intimidating type signature captures the similarity between these
--   operations and ensures that composite <a>Unit</a>s are
--   <tt>NotPrefixable</tt>.
(/) :: (KnownVariant v1, KnownVariant v2, KnownVariant (v1 * v2), Fractional a) => Dimensional v1 d1 a -> Dimensional v2 d2 a -> Dimensional (v1 * v2) (d1 / d2) a
infixl 7 /

-- | Adds two <a>Quantity</a>s.
(+) :: Num a => Quantity d a -> Quantity d a -> Quantity d a
infixl 6 +

-- | Subtracts one <a>Quantity</a> from another.
(-) :: Num a => Quantity d a -> Quantity d a -> Quantity d a
infixl 6 -

-- | Negates the value of a <a>Quantity</a>.
negate :: Num a => Quantity d a -> Quantity d a

-- | Takes the absolute value of a <a>Quantity</a>.
abs :: Num a => Quantity d a -> Quantity d a

-- | Computes the nth root of a <a>Quantity</a> using <a>**</a>.
--   
--   The <a>Root</a> type family will prevent application of this operator
--   where the result would have a fractional dimension or where n is zero.
--   
--   Because the root chosen impacts the <a>Dimension</a> of the result, it
--   is necessary to supply a type-level representation of the root in the
--   form of a <a>Proxy</a> to some <a>TypeInt</a>. Convenience values
--   <tt>pos1</tt>, <a>pos2</a>, <tt>neg1</tt>, ... are supplied by the
--   <a>Numeric.NumType.DK.Integers</a> module. The most commonly used ones
--   are also reexported by <a>Numeric.Units.Dimensional.Prelude</a>.
--   
--   Also available in operator form, see <a>^/</a>.
nroot :: (KnownTypeInt n, Floating a) => Proxy n -> Quantity d a -> Quantity (Root d n) a

-- | Computes the square root of a <a>Quantity</a> using <a>**</a>.
--   
--   The <a>Root</a> type family will prevent application where the
--   supplied quantity does not have a square dimension.
--   
--   <pre>
--   sqrt x == nroot pos2 x
--   </pre>
sqrt :: Floating a => Quantity d a -> Quantity (Root d Pos2) a

-- | Computes the cube root of a <a>Quantity</a> using <a>**</a>.
--   
--   The <a>Root</a> type family will prevent application where the
--   supplied quantity does not have a cubic dimension.
--   
--   <pre>
--   cbrt x == nroot pos3 x
--   </pre>
cbrt :: Floating a => Quantity d a -> Quantity (Root d Pos3) a
exp :: Floating a => Dimensionless a -> Dimensionless a
log :: Floating a => Dimensionless a -> Dimensionless a
sin :: Floating a => Dimensionless a -> Dimensionless a
cos :: Floating a => Dimensionless a -> Dimensionless a
tan :: Floating a => Dimensionless a -> Dimensionless a
asin :: Floating a => Dimensionless a -> Dimensionless a
acos :: Floating a => Dimensionless a -> Dimensionless a
atan :: Floating a => Dimensionless a -> Dimensionless a
sinh :: Floating a => Dimensionless a -> Dimensionless a
cosh :: Floating a => Dimensionless a -> Dimensionless a
tanh :: Floating a => Dimensionless a -> Dimensionless a
asinh :: Floating a => Dimensionless a -> Dimensionless a
acosh :: Floating a => Dimensionless a -> Dimensionless a
atanh :: Floating a => Dimensionless a -> Dimensionless a

-- | The standard two argument arctangent function. Since it interprets its
--   two arguments in comparison with one another, the input may have any
--   dimension.
atan2 :: (RealFloat a) => Quantity d a -> Quantity d a -> Dimensionless a

-- | Applies <a>*~</a> to all values in a functor.
(*~~) :: (Functor f, Num a) => f a -> Unit m d a -> f (Quantity d a)
infixl 7 *~~

-- | Applies <a>/~</a> to all values in a functor.
(/~~) :: (Functor f, Fractional a) => f (Quantity d a) -> Unit m d a -> f a
infixl 7 /~~

-- | The sum of all elements in a list.
sum :: (Num a, Foldable f) => f (Quantity d a) -> Quantity d a

-- | The arithmetic mean of all elements in a list.
mean :: (Fractional a, Foldable f) => f (Quantity d a) -> Quantity d a

-- | The length of the foldable data structure as a <a>Dimensionless</a>.
--   This can be useful for purposes of e.g. calculating averages.
dimensionlessLength :: (Num a, Foldable f) => f (Dimensional v d a) -> Dimensionless a

-- | Returns a list of quantities between given bounds.
nFromTo :: (Fractional a, Integral b) => Quantity d a -> Quantity d a -> b -> [Quantity d a]

-- | The type-level dimensions of dimensionless values.
type DOne = Dim Zero Zero Zero Zero Zero Zero Zero
type DLength = Dim Pos1 Zero Zero Zero Zero Zero Zero
type DMass = Dim Zero Pos1 Zero Zero Zero Zero Zero
type DTime = Dim Zero Zero Pos1 Zero Zero Zero Zero
type DElectricCurrent = Dim Zero Zero Zero Pos1 Zero Zero Zero
type DThermodynamicTemperature = Dim Zero Zero Zero Zero Pos1 Zero Zero
type DAmountOfSubstance = Dim Zero Zero Zero Zero Zero Pos1 Zero
type DLuminousIntensity = Dim Zero Zero Zero Zero Zero Zero Pos1
type Dimensionless = Quantity DOne
type Length = Quantity DLength
type Mass = Quantity DMass
type Time = Quantity DTime
type ElectricCurrent = Quantity DElectricCurrent
type ThermodynamicTemperature = Quantity DThermodynamicTemperature
type AmountOfSubstance = Quantity DAmountOfSubstance
type LuminousIntensity = Quantity DLuminousIntensity

-- | The constant for zero is polymorphic, allowing it to express zero
--   <a>Length</a> or <tt>Capacitance</tt> or <tt>Velocity</tt> etc, in
--   addition to the <a>Dimensionless</a> value zero.
_0 :: Num a => Quantity d a
_1 :: (Num a) => Dimensionless a
_2 :: (Num a) => Dimensionless a
_3 :: (Num a) => Dimensionless a
_4 :: (Num a) => Dimensionless a
_5 :: (Num a) => Dimensionless a
_6 :: (Num a) => Dimensionless a
_7 :: (Num a) => Dimensionless a
_8 :: (Num a) => Dimensionless a
_9 :: (Num a) => Dimensionless a
pi :: Floating a => Dimensionless a

-- | Twice <a>pi</a>.
--   
--   For background on <a>tau</a> see
--   <a>http://tauday.com/tau-manifesto</a> (but also feel free to review
--   <a>http://www.thepimanifesto.com)</a>.
tau :: Floating a => Dimensionless a

-- | A polymorphic <a>Unit</a> which can be used in place of the coherent
--   SI base unit of any dimension. This allows polymorphic quantity
--   creation and destruction without exposing the <a>Dimensional</a>
--   constructor.
siUnit :: forall d a. (KnownDimension d, Num a) => Unit NonMetric d a

-- | The unit <a>one</a> has dimension <a>DOne</a> and is the base unit of
--   dimensionless values.
--   
--   As detailed in 7.10 "Values of quantities expressed simply as numbers:
--   the unit one, symbol 1" of <a>[1]</a> the unit one generally does not
--   appear in expressions. However, for us it is necessary to use
--   <a>one</a> as we would any other unit to perform the "boxing" of
--   dimensionless values.
one :: Num a => Unit NonMetric DOne a

-- | Forms a new atomic <a>Unit</a> by specifying its <a>UnitName</a> and
--   its definition as a multiple of another <a>Unit</a>.
--   
--   Use this variant when the scale factor of the resulting unit is
--   irrational or <a>Approximate</a>. See <a>mkUnitQ</a> for when it is
--   rational and <a>mkUnitZ</a> for when it is an integer.
--   
--   Note that supplying zero as a definining quantity is invalid, as the
--   library relies upon units forming a group under multiplication.
--   
--   Supplying negative defining quantities is allowed and handled
--   gracefully, but is discouraged on the grounds that it may be
--   unexpected by other readers.
mkUnitR :: Floating a => UnitName m -> ExactPi -> Unit m1 d a -> Unit m d a

-- | Forms a new atomic <a>Unit</a> by specifying its <a>UnitName</a> and
--   its definition as a multiple of another <a>Unit</a>.
--   
--   Use this variant when the scale factor of the resulting unit is
--   rational. See <a>mkUnitZ</a> for when it is an integer and
--   <a>mkUnitR</a> for the general case.
--   
--   For more information see <a>mkUnitR</a>.
mkUnitQ :: Fractional a => UnitName m -> Rational -> Unit m1 d a -> Unit m d a

-- | Forms a new atomic <a>Unit</a> by specifying its <a>UnitName</a> and
--   its definition as a multiple of another <a>Unit</a>.
--   
--   Use this variant when the scale factor of the resulting unit is an
--   integer. See <a>mkUnitQ</a> for when it is rational and <a>mkUnitR</a>
--   for the general case.
--   
--   For more information see <a>mkUnitR</a>.
mkUnitZ :: Num a => UnitName m -> Integer -> Unit m1 d a -> Unit m d a

-- | Extracts the <a>UnitName</a> of a <a>Unit</a>.
name :: Unit m d a -> UnitName m

-- | Extracts the exact value of a <a>Unit</a>, expressed in terms of the
--   SI coherent derived unit (see <a>siUnit</a>) of the same
--   <a>Dimension</a>.
--   
--   Note that the actual value may in some cases be approximate, for
--   example if the unit is defined by experiment.
exactValue :: Unit m d a -> ExactPi

-- | Discards potentially unwanted type level information about a
--   <a>Unit</a>.
weaken :: Unit m d a -> Unit NonMetric d a

-- | Attempts to convert a <a>Unit</a> which may or may not be
--   <a>Metric</a> to one which is certainly <a>Metric</a>.
strengthen :: Unit m d a -> Maybe (Unit Metric d a)

-- | Forms the exact version of a <a>Unit</a>.
exactify :: Unit m d a -> Unit m d ExactPi

-- | Shows the value of a <a>Quantity</a> expressed in a specified
--   <a>Unit</a> of the same <a>Dimension</a>.
showIn :: (KnownDimension d, Show a, Fractional a) => Unit m d a -> Quantity d a -> String

-- | A physical quantity or unit.
--   
--   We call this data type <a>Dimensional</a> to capture the notion that
--   the units and quantities it represents have physical dimensions.
--   
--   The type variable <tt>a</tt> is the only non-phantom type variable and
--   represents the numerical value of a quantity or the scale (w.r.t. SI
--   units) of a unit. For SI units the scale will always be 1. For non-SI
--   units the scale is the ratio of the unit to the SI unit with the same
--   physical dimension.
--   
--   Since <tt>a</tt> is the only non-phantom type we were able to define
--   <a>Dimensional</a> as a newtype, avoiding boxing at runtime.
class KnownVariant (v :: Variant) where data Dimensional v :: Dimension -> * -> * where {
    data family Dimensional v :: Dimension -> * -> *;
}

-- | Maps over the underlying representation of a dimensional value. The
--   caller is responsible for ensuring that the supplied function respects
--   the dimensional abstraction. This means that the function must
--   preserve numerical values, or linearly scale them while preserving the
--   origin.
dmap :: KnownVariant v => (a1 -> a2) -> Dimensional v d a1 -> Dimensional v d a2

-- | Convenient conversion between numerical types while retaining
--   dimensional information.
changeRep :: (KnownVariant v, Real a, Fractional b) => Dimensional v d a -> Dimensional v d b

-- | Convenient conversion from exactly represented values while retaining
--   dimensional information.
changeRepApproximate :: (KnownVariant v, Floating b) => Dimensional v d ExactPi -> Dimensional v d b


-- | Provides a <a>Functor</a> instance for <a>Dimensional</a>.
--   
--   Note that this instance is dubious, because it allows you to break the
--   dimensional abstraction. See <a>dmap</a> for more information.
--   
--   Note that, while this instance overlaps with that given for
--   <a>Dimensionless</a>, it is confluent with that instance.
--   
--   Note that this is an orphan instance.
module Numeric.Units.Dimensional.Functor

-- | A <a>Functor</a> instance for <a>Dimensional</a>.
--   
--   Note that this instance is dubious, because it allows you to break the
--   dimensional abstraction. See <a>dmap</a> for more information.
--   
--   Note that, while this instance overlaps with that given for
--   <a>Dimensionless</a>, it is confluent with that instance.
--   
--   Note that this is an orphan instance.
instance Numeric.Units.Dimensional.Internal.KnownVariant v => GHC.Base.Functor (Numeric.Units.Dimensional.Internal.Dimensional v d)


-- | <h1>Summary</h1>
--   
--   This module defines type synonyms for common dimensionalities and the
--   associated quantity types. Additional dimensionalities and quantity
--   types will be added on an as-needed basis.
--   
--   The definitions in this module are grouped so that a type synonym for
--   the dimensionality is defined first in terms of base dimension
--   exponents. Then a type synonym for the corresponding quantity type is
--   defined. If there are several quantity types with the same
--   dimensionality type synonyms are provided for each quantity type.
--   
--   <h1>References</h1>
--   
--   <ol>
--   <li><a>http://physics.nist.gov/Pubs/SP811/</a></li>
--   </ol>
module Numeric.Units.Dimensional.Quantities
type Area = Quantity DArea
type Volume = Quantity DVolume
type Velocity = Quantity DVelocity
type Acceleration = Quantity DAcceleration
type WaveNumber = Quantity DWaveNumber
type MassDensity = Quantity DMassDensity
type Density = MassDensity
type SpecificVolume = Quantity DSpecificVolume
type CurrentDensity = Quantity DCurrentDensity
type MagneticFieldStrength = Quantity DMagneticFieldStrength
type AmountOfSubstanceConcentration = Quantity DAmountOfSubstanceConcentration
type Concentration = AmountOfSubstanceConcentration
type Luminance = Quantity DLuminance
type PlaneAngle = Dimensionless
type SolidAngle = Dimensionless
type Frequency = Quantity DFrequency
type Force = Quantity DForce
type Pressure = Quantity DPressure
type Stress = Quantity DStress
type Energy = Quantity DEnergy
type Work = Quantity DWork
type QuantityOfHeat = Quantity DQuantityOfHeat
type Power = Quantity DPower
type RadiantFlux = Quantity DRadiantFlux
type ElectricCharge = Quantity DElectricCharge
type QuantityOfElectricity = Quantity DQuantityOfElectricity
type ElectricPotential = Quantity DElectricPotential
type PotentialDifference = Quantity DPotentialDifference
type ElectromotiveForce = Quantity DElectromotiveForce
type Capacitance = Quantity DCapacitance
type ElectricResistance = Quantity DElectricResistance
type ElectricConductance = Quantity DElectricConductance
type MagneticFlux = Quantity DMagneticFlux
type MagneticFluxDensity = Quantity DMagneticFluxDensity
type Inductance = Quantity DInductance
type LuminousFlux = Quantity DLuminousFlux
type Illuminance = Quantity DIlluminance
type CelsiusTemperature = Quantity DCelsiusTemperature
type Activity = Quantity DActivity
type AbsorbedDose = Quantity DAbsorbedDose
type SpecificEnergy = Quantity DSpecificEnergy
type Kerma = Quantity DKerma
type DoseEquivalent = Quantity DDoseEquivalent
type AmbientDoseEquivalent = DoseEquivalent
type DirectionalDoseEquivalent = DoseEquivalent
type PersonalDoseEquivalent = DoseEquivalent
type EquivalentDose = DoseEquivalent
type CatalyticActivity = Quantity DCatalyticActivity
type AngularVelocity = Quantity DAngularVelocity
type AngularAcceleration = Quantity DAngularAcceleration
type DynamicViscosity = Quantity DDynamicViscosity
type MomentOfForce = Quantity DMomentOfForce
type SurfaceTension = Quantity DSurfaceTension
type HeatFluxDensity = Quantity DHeatFluxDensity
type Irradiance = Quantity DIrradiance
type RadiantIntensity = Quantity DRadiantIntensity
type Radiance = Quantity DRadiance
type HeatCapacity = Quantity DHeatCapacity
type Entropy = Quantity DEntropy
type SpecificHeatCapacity = Quantity DSpecificHeatCapacity
type SpecificEntropy = Quantity DSpecificEntropy
type ThermalConductivity = Quantity DThermalConductivity
type EnergyDensity = Quantity DEnergyDensity
type ElectricFieldStrength = Quantity DElectricFieldStrength
type ElectricChargeDensity = Quantity DElectricChargeDensity
type ElectricFluxDensity = Quantity DElectricFluxDensity
type Permittivity = Quantity DPermittivity
type Permeability = Quantity DPermeability
type MolarEnergy = Quantity DMolarEnergy
type MolarEntropy = Quantity DMolarEntropy
type MolarHeatCapacity = Quantity DMolarHeatCapacity
type Exposure = Quantity DExposure
type AbsorbedDoseRate = Quantity DAbsorbedDoseRate
type Impulse = Quantity DImpulse
type Momentum = Quantity DMomentum
type MassFlow = Quantity DMassFlow
type VolumeFlow = Quantity DVolumeFlow
type GravitationalParameter = Quantity DGravitationalParameter
type KinematicViscosity = Quantity DKinematicViscosity
type FirstMassMoment = Quantity DFirstMassMoment
type MomentOfInertia = Quantity DMomentOfInertia
type AngularMomentum = Quantity DAngularMomentum
type ThermalResistivity = Quantity DThermalResistivity
type ThermalConductance = Quantity DThermalConductance
type ThermalResistance = Quantity DThermalResistance
type HeatTransferCoefficient = Quantity DHeatTransferCoefficient
type ThermalAdmittance = HeatTransferCoefficient
type ThermalInsulance = Quantity DThermalInsulance
type Jerk = Quantity DJerk
type Angle = PlaneAngle
type Thrust = Force
type Torque = MomentOfForce
type EnergyPerUnitMass = SpecificEnergy

-- | Constructs a unit of area from a unit of length, taking the area of a
--   square whose sides are that length.
square :: (Fractional a, Typeable m) => Unit m DLength a -> Unit NonMetric DArea a

-- | Constructs a unit of volume from a unit of length, taking the volume
--   of a cube whose sides are that length.
cubic :: (Fractional a, Typeable m) => Unit m DLength a -> Unit NonMetric DVolume a
type DArea = Dim Pos2 Zero Zero Zero Zero Zero Zero
type DVolume = Dim Pos3 Zero Zero Zero Zero Zero Zero
type DVelocity = Dim Pos1 Zero Neg1 Zero Zero Zero Zero
type DAcceleration = Dim Pos1 Zero Neg2 Zero Zero Zero Zero
type DWaveNumber = Dim Neg1 Zero Zero Zero Zero Zero Zero
type DMassDensity = Dim Neg3 Pos1 Zero Zero Zero Zero Zero
type DDensity = DMassDensity
type DSpecificVolume = Dim Pos3 Neg1 Zero Zero Zero Zero Zero
type DCurrentDensity = Dim Neg2 Zero Zero Pos1 Zero Zero Zero
type DMagneticFieldStrength = Dim Neg1 Zero Zero Pos1 Zero Zero Zero
type DAmountOfSubstanceConcentration = Dim Neg3 Zero Zero Zero Zero Pos1 Zero
type DConcentration = DAmountOfSubstanceConcentration
type DLuminance = Dim Neg2 Zero Zero Zero Zero Zero Pos1
type DPlaneAngle = DOne
type DSolidAngle = DOne
type DFrequency = Dim Zero Zero Neg1 Zero Zero Zero Zero
type DForce = Dim Pos1 Pos1 Neg2 Zero Zero Zero Zero
type DPressure = Dim Neg1 Pos1 Neg2 Zero Zero Zero Zero
type DStress = DPressure
type DEnergy = Dim Pos2 Pos1 Neg2 Zero Zero Zero Zero
type DWork = DEnergy
type DQuantityOfHeat = DEnergy
type DPower = Dim Pos2 Pos1 Neg3 Zero Zero Zero Zero
type DRadiantFlux = DPower
type DElectricCharge = Dim Zero Zero Pos1 Pos1 Zero Zero Zero
type DQuantityOfElectricity = DElectricCharge
type DElectricPotential = Dim Pos2 Pos1 Neg3 Neg1 Zero Zero Zero
type DPotentialDifference = DElectricPotential
type DElectromotiveForce = DElectricPotential
type DCapacitance = Dim Neg2 Neg1 Pos4 Pos2 Zero Zero Zero
type DElectricResistance = Dim Pos2 Pos1 Neg3 Neg2 Zero Zero Zero
type DElectricConductance = Dim Neg2 Neg1 Pos3 Pos2 Zero Zero Zero
type DMagneticFlux = Dim Pos2 Pos1 Neg2 Neg1 Zero Zero Zero
type DMagneticFluxDensity = Dim Zero Pos1 Neg2 Neg1 Zero Zero Zero
type DInductance = Dim Pos2 Pos1 Neg2 Neg2 Zero Zero Zero
type DLuminousFlux = DLuminousIntensity
type DIlluminance = Dim Neg2 Zero Zero Zero Zero Zero Pos1
type DCelsiusTemperature = DThermodynamicTemperature
type DActivity = DFrequency
type DAbsorbedDose = Dim Pos2 Zero Neg2 Zero Zero Zero Zero
type DSpecificEnergy = DAbsorbedDose
type DKerma = DAbsorbedDose
type DDoseEquivalent = DAbsorbedDose
type DAmbientDoseEquivalent = DDoseEquivalent
type DDirectionalDoseEquivalent = DDoseEquivalent
type DPersonalDoseEquivalent = DDoseEquivalent
type DEquivalentDose = DDoseEquivalent
type DCatalyticActivity = Dim Zero Zero Neg1 Zero Zero Pos1 Zero
type DAngularVelocity = DFrequency
type DAngularAcceleration = Dim Zero Zero Neg2 Zero Zero Zero Zero
type DDynamicViscosity = Dim Neg1 Pos1 Neg1 Zero Zero Zero Zero
type DMomentOfForce = DEnergy
type DSurfaceTension = Dim Zero Pos1 Neg2 Zero Zero Zero Zero
type DHeatFluxDensity = Dim Zero Pos1 Neg3 Zero Zero Zero Zero
type DIrradiance = DHeatFluxDensity
type DRadiantIntensity = DPower
type DRadiance = DIrradiance
type DHeatCapacity = Dim Pos2 Pos1 Neg2 Zero Neg1 Zero Zero
type DEntropy = DHeatCapacity
type DSpecificHeatCapacity = Dim Pos2 Zero Neg2 Zero Neg1 Zero Zero
type DSpecificEntropy = DSpecificHeatCapacity
type DThermalConductivity = Dim Pos1 Pos1 Neg3 Zero Neg1 Zero Zero
type DEnergyDensity = DPressure
type DElectricFieldStrength = Dim Pos1 Pos1 Neg3 Neg1 Zero Zero Zero
type DElectricChargeDensity = Dim Neg3 Zero Pos1 Pos1 Zero Zero Zero
type DElectricFluxDensity = Dim Neg2 Zero Pos1 Pos1 Zero Zero Zero
type DPermittivity = Dim Neg3 Neg1 Pos4 Pos2 Zero Zero Zero
type DPermeability = Dim Pos1 Pos1 Neg2 Neg2 Zero Zero Zero
type DMolarEnergy = Dim Pos2 Pos1 Neg2 Zero Zero Neg1 Zero
type DMolarEntropy = Dim Pos2 Pos1 Neg2 Zero Neg1 Neg1 Zero
type DMolarHeatCapacity = DMolarEntropy
type DExposure = Dim Zero Neg1 Pos1 Pos1 Zero Zero Zero
type DAbsorbedDoseRate = Dim Pos2 Zero Neg3 Zero Zero Zero Zero
type DImpulse = Dim Pos1 Pos1 Neg1 Zero Zero Zero Zero
type DMomentum = DImpulse
type DMassFlow = Dim Zero Pos1 Neg1 Zero Zero Zero Zero
type DVolumeFlow = Dim Pos3 Zero Neg1 Zero Zero Zero Zero
type DGravitationalParameter = Dim Pos3 Zero Neg2 Zero Zero Zero Zero
type DKinematicViscosity = Dim Pos2 Zero Neg1 Zero Zero Zero Zero
type DFirstMassMoment = Dim Pos1 Pos1 Zero Zero Zero Zero Zero
type DMomentOfInertia = Dim Pos2 Pos1 Zero Zero Zero Zero Zero
type DAngularMomentum = Dim Pos2 Pos1 Neg1 Zero Zero Zero Zero
type DThermalResistivity = Dim Neg1 Neg1 Pos3 Zero Pos1 Zero Zero
type DThermalConductance = Dim Pos2 Pos1 Neg3 Zero Neg1 Zero Zero
type DThermalResistance = Dim Neg2 Neg1 Pos3 Zero Pos1 Zero Zero
type DHeatTransferCoefficient = Dim Zero Pos1 Neg3 Zero Neg1 Zero Zero
type DThermalAdmittance = DHeatTransferCoefficient
type DThermalInsulance = Dim Zero Neg1 Pos3 Zero Pos1 Zero Zero
type DJerk = Dim Pos1 Zero Neg3 Zero Zero Zero Zero
type DAngle = DPlaneAngle
type DThrust = DForce
type DTorque = DMomentOfForce
type DEnergyPerUnitMass = DSpecificEnergy


-- | <h1>Summary</h1>
--   
--   This module defines the SI prefixes, the SI base units and the SI
--   derived units. It also defines the units outside of the SI that are
--   accepted for use with the SI. Any chapters, sections or tables
--   referenced are from <a>[1]</a> unless otherwise specified.
--   
--   <h1>References</h1>
--   
--   <ol>
--   <li><a>http://physics.nist.gov/Pubs/SP811/</a></li>
--   <li><a>http://en.wikipedia.org/wiki/Minute_of_arc</a></li>
--   <li><a>http://en.wikipedia.org/wiki/Astronomical_unit</a></li>
--   </ol>
module Numeric.Units.Dimensional.SIUnits
metre :: Num a => Unit Metric DLength a
meter :: Num a => Unit Metric DLength a
gram :: Fractional a => Unit Metric DMass a
second :: Num a => Unit Metric DTime a
ampere :: Num a => Unit Metric DElectricCurrent a
kelvin :: Num a => Unit Metric DThermodynamicTemperature a
mole :: Num a => Unit Metric DAmountOfSubstance a
candela :: Num a => Unit Metric DLuminousIntensity a
radian :: Num a => Unit Metric DPlaneAngle a
steradian :: Num a => Unit Metric DSolidAngle a
hertz :: Num a => Unit Metric DFrequency a
newton :: Num a => Unit Metric DForce a
pascal :: Num a => Unit Metric DPressure a
joule :: Num a => Unit Metric DEnergy a
watt :: Num a => Unit Metric DPower a
coulomb :: Num a => Unit Metric DElectricCharge a
volt :: Num a => Unit Metric DElectricPotential a
farad :: Num a => Unit Metric DCapacitance a
ohm :: Num a => Unit Metric DElectricResistance a
siemens :: Num a => Unit Metric DElectricConductance a
weber :: Num a => Unit Metric DMagneticFlux a
tesla :: Num a => Unit Metric DMagneticFluxDensity a
henry :: Num a => Unit Metric DInductance a
lumen :: Num a => Unit Metric DLuminousFlux a
lux :: Num a => Unit Metric DIlluminance a
degreeCelsius :: Num a => Unit Metric DCelsiusTemperature a
fromDegreeCelsiusAbsolute :: Floating a => a -> ThermodynamicTemperature a
toDegreeCelsiusAbsolute :: Floating a => ThermodynamicTemperature a -> a
becquerel :: Num a => Unit Metric DActivity a
gray :: Num a => Unit Metric DAbsorbedDose a
sievert :: Num a => Unit Metric DDoseEquivalent a
katal :: Num a => Unit Metric DCatalyticActivity a
minute :: Num a => Unit NonMetric DTime a
hour :: Num a => Unit NonMetric DTime a
day :: Num a => Unit NonMetric DTime a
hectare :: Fractional a => Unit NonMetric DArea a
litre :: Fractional a => Unit Metric DVolume a
liter :: Fractional a => Unit Metric DVolume a
tonne :: Num a => Unit Metric DMass a
metricTon :: Num a => Unit Metric DMass a
degree :: Floating a => Unit NonMetric DPlaneAngle a
arcminute :: Floating a => Unit NonMetric DPlaneAngle a
arcsecond :: Floating a => Unit NonMetric DPlaneAngle a
degreeOfArc :: Floating a => Unit NonMetric DPlaneAngle a
minuteOfArc :: Floating a => Unit NonMetric DPlaneAngle a
secondOfArc :: Floating a => Unit NonMetric DPlaneAngle a
astronomicalUnit :: Num a => Unit NonMetric DLength a
deka :: Num a => Unit Metric d a -> Unit NonMetric d a
deca :: Num a => Unit Metric d a -> Unit NonMetric d a
hecto :: Num a => Unit Metric d a -> Unit NonMetric d a
kilo :: Num a => Unit Metric d a -> Unit NonMetric d a
mega :: Num a => Unit Metric d a -> Unit NonMetric d a
giga :: Num a => Unit Metric d a -> Unit NonMetric d a
tera :: Num a => Unit Metric d a -> Unit NonMetric d a
peta :: Num a => Unit Metric d a -> Unit NonMetric d a
exa :: Num a => Unit Metric d a -> Unit NonMetric d a
zetta :: Num a => Unit Metric d a -> Unit NonMetric d a
yotta :: Num a => Unit Metric d a -> Unit NonMetric d a
deci :: Fractional a => Unit Metric d a -> Unit NonMetric d a
centi :: Fractional a => Unit Metric d a -> Unit NonMetric d a
milli :: Fractional a => Unit Metric d a -> Unit NonMetric d a
micro :: Fractional a => Unit Metric d a -> Unit NonMetric d a
nano :: Fractional a => Unit Metric d a -> Unit NonMetric d a
pico :: Fractional a => Unit Metric d a -> Unit NonMetric d a
femto :: Fractional a => Unit Metric d a -> Unit NonMetric d a
atto :: Fractional a => Unit Metric d a -> Unit NonMetric d a
zepto :: Fractional a => Unit Metric d a -> Unit NonMetric d a
yocto :: Fractional a => Unit Metric d a -> Unit NonMetric d a


-- | <h1>Summary</h1>
--   
--   This module supplies a convenient set of imports for working with the
--   dimensional package, including aliases for common <a>Quantity</a>s and
--   <a>Dimension</a>s, and a comprehensive set of SI units and units
--   accepted for use with the SI.
--   
--   It re-exports the <a>Prelude</a>, hiding arithmetic functions whose
--   names collide with the dimensionally-typed versions supplied by this
--   package.
module Numeric.Units.Dimensional.Prelude


-- | Defines types for manipulation of units and quantities without phantom
--   types for their dimensions.
module Numeric.Units.Dimensional.Dynamic

-- | A <a>Quantity</a> whose <a>Dimension</a> is only known dynamically.
data AnyQuantity v

-- | Converts a <a>Quantity</a> of statically known <a>Dimension</a> into
--   an <a>AnyQuantity</a>.
demoteQuantity :: forall d v. (KnownDimension d) => Quantity d v -> AnyQuantity v

-- | Converts an <a>AnyQuantity</a> into a <a>Quantity</a> of statically
--   known <a>Dimension</a>, or <a>Nothing</a> if the dimension does not
--   match.
promoteQuantity :: forall d v. (KnownDimension d) => AnyQuantity v -> Maybe (Quantity d v)

-- | A <a>Unit</a> whose <a>Dimension</a> is only known dynamically.
data AnyUnit

-- | Converts a <a>Unit</a> of statically known <a>Dimension</a> into an
--   <a>AnyUnit</a>.
demoteUnit :: forall a d v. (KnownDimension d) => Unit a d v -> AnyUnit

-- | Converts an <a>AnyUnit</a> into a <a>Unit</a> of statically known
--   <a>Dimension</a>, or <a>Nothing</a> if the dimension does not match.
--   
--   The result is represented in <a>ExactPi</a>, conversion to other
--   representations is possible using <a>changeRepApproximate</a>.
promoteUnit :: forall d. (KnownDimension d) => AnyUnit -> Maybe (Unit NonMetric d ExactPi)
instance GHC.Classes.Eq v => GHC.Classes.Eq (Numeric.Units.Dimensional.Dynamic.AnyQuantity v)
instance GHC.Show.Show v => GHC.Show.Show (Numeric.Units.Dimensional.Dynamic.AnyQuantity v)
instance Numeric.Units.Dimensional.Dimensions.TermLevel.HasDimension (Numeric.Units.Dimensional.Dynamic.AnyQuantity v)
instance GHC.Show.Show Numeric.Units.Dimensional.Dynamic.AnyUnit
instance Numeric.Units.Dimensional.Dimensions.TermLevel.HasDimension Numeric.Units.Dimensional.Dynamic.AnyUnit


-- | <h1>Summary</h1>
--   
--   This module defines units that are not part of the SI, with the
--   exception of those defined in the
--   <a>Numeric.Units.Dimensional.SIUnits</a> module (units outside of the
--   SI accepted for use with the SI).
--   
--   Any chapters, sections or tables referenced are from <a>[1]</a> unless
--   otherwise specified.
--   
--   <h2>Neper, bel, shannon and the like</h2>
--   
--   The units of section 5.1.2 are purposefully (but not permanently)
--   omitted. In fact the logarithmic units (see section 8.7) are
--   problematic and it is not clear how to implement them. Perhaps with a
--   conversion function similar to for degrees Celsius.
--   
--   <h1>References</h1>
--   
--   <ol>
--   <li><a>http://physics.nist.gov/Pubs/SP811/</a></li>
--   
--   <li><a>http://www.iau.org/science/publications/proceedings_rules/units/</a></li>
--   <li><a>http://en.m.wikipedia.org/wiki/Pressure</a></li>
--   <li><a>http://en.m.wikipedia.org/wiki/Torr</a></li>
--   </ol>
module Numeric.Units.Dimensional.NonSI
electronVolt :: Floating a => Unit Metric DEnergy a
unifiedAtomicMassUnit :: Floating a => Unit Metric DMass a
dalton :: Floating a => Unit Metric DMass a
gee :: Fractional a => Unit Metric DAcceleration a
inch :: Fractional a => Unit NonMetric DLength a
foot :: Fractional a => Unit NonMetric DLength a
mil :: Fractional a => Unit NonMetric DLength a
poundMass :: Fractional a => Unit NonMetric DMass a
ounce :: Fractional a => Unit NonMetric DMass a
poundForce :: Fractional a => Unit NonMetric DForce a
slug :: Fractional a => Unit NonMetric DMass a
psi :: Fractional a => Unit NonMetric DPressure a
yard :: (Fractional a) => Unit NonMetric DLength a
mile :: (Fractional a) => Unit NonMetric DLength a
nauticalMile :: (Num a) => Unit NonMetric DLength a
knot :: (Fractional a) => Unit NonMetric DVelocity a
revolution :: (Floating a) => Unit NonMetric DOne a
solid :: (Floating a) => Unit NonMetric DOne a
teaspoon :: (Fractional a) => Unit NonMetric DVolume a
acre :: (Fractional a) => Unit NonMetric DArea a
year :: Num a => Unit NonMetric DTime a
century :: Num a => Unit NonMetric DTime a

-- | The bar is exactly 100,000 <a>pascal</a>.
--   
--   From Wikipedia:
--   
--   It is about equal to the atmospheric pressure on Earth at sea level.
bar :: (Num a) => Unit Metric DPressure a

-- | The "standard atmosphere".
--   
--   From Wikipedia <a>[3]</a>:
--   
--   The standard atmosphere (atm) is an established constant. It is
--   approximately equal to typical air pressure at earth mean sea level.
atmosphere :: (Num a) => Unit NonMetric DPressure a

-- | The "technical atmosphere"
--   
--   From Wikipedia:
--   
--   A technical atmosphere (symbol: at) is a non-SI unit of pressure equal
--   to one kilogram-force per square centimeter.
technicalAtmosphere :: (Fractional a) => Unit NonMetric DPressure a

-- | The conventional value for the pressure exerted by a 1 mm high column
--   of mercury.
--   
--   Per Wikipedia <a>[4]</a>, one mmHg (millimeter of mercury) is defined
--   as:
--   
--   The pressure exerted at the base of a column of fluid exactly 1 mm
--   high, when the density of the fluid is exactly 13.5951 g/cm^3, at a
--   place where the acceleration of gravity is exactly 9.80665 m/s^2.
mmHg :: (Floating a) => Unit NonMetric DPressure a

-- | The conventional value for the pressure exerted by a 1 inch high
--   column of mercury.
--   
--   Column inches of mercury are also used to measure pressure, especially
--   in meteorological or aeronautical contexts in the United States.
--   
--   This is the value defined by UCUM. For the value defined by NIST, see
--   <a>inHg_NIST</a>.
inHg :: (Floating a) => Unit NonMetric DPressure a

-- | The conventional value for the pressure exerted by a 1 inch high
--   column of mercury.
--   
--   Column inches of mercury are also used to measure pressure, especially
--   in meteorological or aeronautical contexts in the United States.
--   
--   This is the value defined by UCUM. For the value defined by NIST, see
--   <a>inHg_NIST</a>.
inHg_UCUM :: (Floating a) => Unit NonMetric DPressure a

-- | The conventional value for the pressure exerted by a 1 inch high
--   column of mercury.
--   
--   Column inches of mercury are also used to measure pressure, especially
--   in meteorological or aeronautical contexts in the United States.
--   
--   This is the value defined by NIST. For the value defined by UCUM, see
--   <a>inHg_UCUM</a>.
inHg_NIST :: (Floating a) => Unit NonMetric DPressure a

-- | One torr (symbol: Torr) is defined as 1/760 atm, which is
--   approximately equal to 1 <a>mmHg</a>.
torr :: (Fractional a) => Unit NonMetric DPressure a
rad :: (Fractional a) => Unit Metric DAbsorbedDose a
stokes :: (Fractional a) => Unit Metric DKinematicViscosity a
degreeFahrenheit :: (Fractional a) => Unit NonMetric DThermodynamicTemperature a
degreeRankine :: (Fractional a) => Unit NonMetric DThermodynamicTemperature a
imperialGallon :: (Fractional a) => Unit NonMetric DVolume a
imperialQuart :: (Fractional a) => Unit NonMetric DVolume a
imperialPint :: (Fractional a) => Unit NonMetric DVolume a
imperialCup :: (Fractional a) => Unit NonMetric DVolume a
imperialGill :: (Fractional a) => Unit NonMetric DVolume a
imperialFluidOunce :: (Fractional a) => Unit NonMetric DVolume a
usGallon :: (Fractional a) => Unit NonMetric DVolume a
usQuart :: (Fractional a) => Unit NonMetric DVolume a
usPint :: (Fractional a) => Unit NonMetric DVolume a
usCup :: (Fractional a) => Unit NonMetric DVolume a
usGill :: (Fractional a) => Unit NonMetric DVolume a
usFluidOunce :: (Fractional a) => Unit NonMetric DVolume a
