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


-- | Units of measure as a GHC typechecker plugin
--   
--   The <tt>uom-plugin</tt> library adds support for units of measure to
--   GHC using the new experimental facility for typechecker plugins, which
--   is available in GHC 7.10 and later. See
--   <a>Data.UnitsOfMeasure.Tutorial</a> for an introduction to the
--   library.
@package uom-plugin
@version 0.3.0.0


-- | This module defines the core types used in the <tt>uom-plugin</tt>
--   library. Note that importing this module may allow you to violate
--   invariants, so you should generally work with the safe interface in
--   <a>Data.UnitsOfMeasure</a> instead.
module Data.UnitsOfMeasure.Internal

-- | (Kind) Units of measure
data Unit

-- | Dimensionless unit (identity element)

-- | Base unit

-- | Multiplication for units of measure

-- | Division for units of measure

-- | Exponentiation (to a positive power) for units of measure; negative
--   exponents are not yet supported (they require an Integer kind)

-- | A <tt>Quantity a u</tt> is represented identically to a value of
--   underlying numeric type <tt>a</tt>, but with units <tt>u</tt>.
newtype Quantity a (u :: Unit)

-- | Warning: the <a>MkQuantity</a> constructor allows module invariants to
--   be violated, so use it with caution!
MkQuantity :: a -> Quantity a

-- | Extract the underlying value of a quantity
unQuantity :: Quantity a u -> a

-- | Zero is polymorphic in its units: this is required because the
--   <a>Num</a> instance constrains the quantity to be dimensionless, so
--   <tt>0 :: Quantity a u</tt> is not well typed.
zero :: Num a => Quantity a u

-- | Construct a <a>Quantity</a> from a dimensionless value. Note that for
--   numeric literals, the <a>Num</a> and <a>Fractional</a> instances allow
--   them to be treated as quantities directly.
mk :: a -> Quantity a One

-- | Addition (<a>+</a>) of quantities requires the units to match.
(+:) :: Num a => Quantity a u -> Quantity a u -> Quantity a u
infixl 6 +:

-- | Multiplication (<a>*</a>) of quantities multiplies the units.
(*:) :: (Num a, w ~~ (u *: v)) => Quantity a u -> Quantity a v -> Quantity a w
infixl 7 *:

-- | Subtraction (<a>-</a>) of quantities requires the units to match.
(-:) :: Num a => Quantity a u -> Quantity a u -> Quantity a u
infixl 6 -:

-- | Negation (<a>negate</a>) of quantities is polymorphic in the units.
negate' :: Num a => Quantity a u -> Quantity a u

-- | Absolute value (<a>abs</a>) of quantities is polymorphic in the units.
abs' :: Num a => Quantity a u -> Quantity a u

-- | The sign (<a>signum</a>) of a quantity gives a dimensionless result.
signum' :: Num a => Quantity a u -> Quantity a One

-- | Convert an <a>Integer</a> quantity into any <a>Integral</a> type
--   (<a>fromInteger</a>).
fromInteger' :: Integral a => Quantity Integer u -> Quantity a u

-- | Division (<a>/</a>) of quantities divides the units.
(/:) :: (Fractional a, w ~~ (u /: v)) => Quantity a u -> Quantity a v -> Quantity a w
infixl 7 /:

-- | Reciprocal (<a>recip</a>) of quantities reciprocates the units.
recip' :: (Fractional a, w ~~ (One /: u)) => Quantity a u -> Quantity a w

-- | Convert a <a>Rational</a> quantity into any <a>Fractional</a> type
--   (<a>fromRational</a>).
fromRational' :: Fractional a => Quantity Rational u -> Quantity a u

-- | Convert any <a>Real</a> quantity into a <a>Rational</a> type
--   (<a>toRational</a>).
toRational' :: Real a => Quantity a u -> Quantity Rational u

-- | Taking the square root (<a>sqrt</a>) of a quantity requires its units
--   to be a square. Fractional units are not currently supported.
sqrt' :: (Floating a, w ~~ (u ^: 2)) => Quantity a w -> Quantity a u

-- | Syntactic representation of a unit as a pair of lists of base units,
--   for example <a>One</a> is represented as <tt>[] <a>:/</a> []</tt> and
--   <tt><a>Base</a> "m" <a>/:</a> <a>Base</a> "s" ^: 2</tt> is represented
--   as <tt>["m"] <a>:/</a> ["s","s"]</tt>.
data UnitSyntax s
(:/) :: [s] -> [s] -> UnitSyntax s

-- | Unpack a unit as a syntactic representation, where the order of units
--   is deterministic. For example:
--   
--   <pre>
--   <a>Unpack</a> <a>One</a> = [] <a>:/</a> []
--   </pre>
--   
--   <pre>
--   <a>Unpack</a> (<a>Base</a> "s" <a>*:</a> <a>Base</a> "m") = ["m","s"] <a>:/</a> []
--   </pre>
--   
--   This does not break type soundness because <a>Unpack</a> will reduce
--   only when the unit is entirely constant, and it does not allow the
--   structure of the unit to be observed. The reduction behaviour is
--   implemented by the plugin, because we cannot define it otherwise.

-- | Pack up a syntactic representation of a unit as a unit. For example:
--   
--   <pre>
--   <a>Pack</a> ([] <a>:/</a> []) = <a>One</a>
--   </pre>
--   
--   <pre>
--   <a>Pack</a> (["m"] <a>:/</a> ["s","s"]) = <a>Base</a> "m" <a>/:</a> <a>Base</a> "s" ^: 2
--   </pre>
--   
--   This is a perfectly ordinary closed type family. <a>Pack</a> is a left
--   inverse of <a>Unpack</a> up to the equational theory of units, but it
--   is not a right inverse (because there are multiple list
--   representations of the same unit).

-- | Take the product of a list of base units.

-- | This is a bit of a hack, honestly, but a good hack. Constraints <tt>u
--   ~~ v</tt> are just like equalities <tt>u ~ v</tt>, except solving them
--   will be delayed until the plugin. This may lead to better inferred
--   types.

-- | This type family is used for translating unit names (as type-level
--   strings) into units. It will be <a>Base</a> for base units or expand
--   the definition for derived units.
--   
--   The instances displayed by Haddock are available only if
--   <a>Data.UnitsOfMeasure.Defs</a> is imported.
instance GHC.Show.Show s => GHC.Show.Show (Data.UnitsOfMeasure.Internal.UnitSyntax s)
instance GHC.Classes.Eq s => GHC.Classes.Eq (Data.UnitsOfMeasure.Internal.UnitSyntax s)
instance GHC.Enum.Bounded a => GHC.Enum.Bounded (Data.UnitsOfMeasure.Internal.Quantity a u)
instance GHC.Classes.Eq a => GHC.Classes.Eq (Data.UnitsOfMeasure.Internal.Quantity a u)
instance GHC.Classes.Ord a => GHC.Classes.Ord (Data.UnitsOfMeasure.Internal.Quantity a u)
instance (GHC.Enum.Enum a, u ~ Data.UnitsOfMeasure.Internal.One) => GHC.Enum.Enum (Data.UnitsOfMeasure.Internal.Quantity a u)
instance (GHC.Float.Floating a, u ~ Data.UnitsOfMeasure.Internal.One) => GHC.Float.Floating (Data.UnitsOfMeasure.Internal.Quantity a u)
instance (GHC.Real.Fractional a, u ~ Data.UnitsOfMeasure.Internal.One) => GHC.Real.Fractional (Data.UnitsOfMeasure.Internal.Quantity a u)
instance (GHC.Real.Integral a, u ~ Data.UnitsOfMeasure.Internal.One) => GHC.Real.Integral (Data.UnitsOfMeasure.Internal.Quantity a u)
instance (GHC.Num.Num a, u ~ Data.UnitsOfMeasure.Internal.One) => GHC.Num.Num (Data.UnitsOfMeasure.Internal.Quantity a u)
instance (GHC.Real.Real a, u ~ Data.UnitsOfMeasure.Internal.One) => GHC.Real.Real (Data.UnitsOfMeasure.Internal.Quantity a u)
instance (GHC.Float.RealFloat a, u ~ Data.UnitsOfMeasure.Internal.One) => GHC.Float.RealFloat (Data.UnitsOfMeasure.Internal.Quantity a u)
instance (GHC.Real.RealFrac a, u ~ Data.UnitsOfMeasure.Internal.One) => GHC.Real.RealFrac (Data.UnitsOfMeasure.Internal.Quantity a u)
instance Foreign.Storable.Storable a => Foreign.Storable.Storable (Data.UnitsOfMeasure.Internal.Quantity a u)
instance Control.DeepSeq.NFData a => Control.DeepSeq.NFData (Data.UnitsOfMeasure.Internal.Quantity a u)


-- | This module defines singleton types for integers and concrete units.
module Data.UnitsOfMeasure.Singleton

-- | Singleton type for concrete units of measure represented as lists of
--   base units
data SUnit (u :: UnitSyntax Symbol)
[SUnit] :: SList xs -> SList ys -> SUnit (xs :/ ys)

-- | Extract the runtime syntactic representation from a singleton unit
forgetSUnit :: SUnit u -> UnitSyntax String

-- | A constraint <tt><a>KnownUnit</a> u</tt> means that <tt>u</tt> must be
--   a concrete unit that is statically known but passed at runtime
class KnownUnit (u :: UnitSyntax Symbol)
unitSing :: KnownUnit u => SUnit u

-- | Extract the runtime syntactic representation of a <a>KnownUnit</a>
unitVal :: forall proxy u. KnownUnit u => proxy u -> UnitSyntax String

-- | Test whether two <a>SUnit</a>s represent the same units, up to the
--   equivalence relation. TODO: this currently uses <a>unsafeCoerce</a>,
--   but in principle it should be possible to avoid it.
testEquivalentSUnit :: SUnit u -> SUnit v -> Maybe (Pack u :~: Pack v)

-- | Singleton type for lists of base units
data SList (xs :: [Symbol])
[SNil] :: SList '[]
[SCons] :: KnownSymbol x => proxy x -> SList xs -> SList (x : xs)

-- | A constraint <tt><a>KnownList</a> xs</tt> means that <tt>xs</tt> must
--   be a list of base units that is statically known but passed at runtime
class KnownList (xs :: [Symbol])
listSing :: KnownList xs => SList xs
instance (Data.UnitsOfMeasure.Singleton.KnownList xs, Data.UnitsOfMeasure.Singleton.KnownList ys) => Data.UnitsOfMeasure.Singleton.KnownUnit (xs 'Data.UnitsOfMeasure.Internal.:/ ys)
instance Data.UnitsOfMeasure.Singleton.KnownList '[]
instance (GHC.TypeLits.KnownSymbol x, Data.UnitsOfMeasure.Singleton.KnownList xs) => Data.UnitsOfMeasure.Singleton.KnownList (x : xs)
instance Data.Type.Equality.TestEquality Data.UnitsOfMeasure.Singleton.SUnit
instance Data.Type.Equality.TestEquality Data.UnitsOfMeasure.Singleton.SList


-- | Experimental support for showing units of measure in a pretty syntax.
--   This requires the units to be fully determined.
--   
--   Apart from the definitions below, this module also exports a
--   <a>Show</a> instance for <tt><a>Quantity</a> a u</tt>, which is
--   re-exported by <a>Data.UnitsOfMeasure</a>.
module Data.UnitsOfMeasure.Show

-- | Render a quantity nicely, followed by its units:
--   
--   <pre>
--   &gt;&gt;&gt; showQuantity (1 /: [u| 0.1 s / m kg |])
--   "10.0 kg m / s"
--   </pre>
showQuantity :: forall a u. (Show a, KnownUnit (Unpack u)) => Quantity a u -> String

-- | Render a unit nicely:
--   
--   <pre>
--   &gt;&gt;&gt; showUnit (undefined :: proxy [u| 1 / s |])
--   "s^-1"
--   </pre>
showUnit :: forall proxy u. KnownUnit (Unpack u) => proxy u -> String
instance (GHC.Show.Show a, Data.UnitsOfMeasure.Singleton.KnownUnit (Data.UnitsOfMeasure.Internal.Unpack u)) => GHC.Show.Show (Data.UnitsOfMeasure.Internal.Quantity a u)


-- | Very very rough support for reading units of measure in the syntax
--   used by <a>Data.UnitsOfMeasure.Show</a>.
module Data.UnitsOfMeasure.Read

-- | Parse a quantity along with its units.
readQuantity :: Read a => String -> Either String (Some (QuantityWithUnit a))

-- | Parse a unit.
readUnit :: String -> Either String (Some SUnit)

-- | Parse a quantity and check that it has the expected units.
readWithUnit :: forall proxy a u. (Read a, KnownUnit u) => proxy u -> String -> Either String (Quantity a (Pack u))

-- | An existential wrapper type: <tt><a>Some</a> p</tt> is essentially
--   <tt>exists x . p x</tt>.
data Some p
[Some] :: p x -> Some p

-- | Represents a quantity whose units have a syntactic representation that
--   is known statically and at runtime.
data QuantityWithUnit a u
[QuantityWithUnit] :: Quantity a (Pack u) -> SUnit u -> QuantityWithUnit a u
instance (Data.UnitsOfMeasure.Singleton.KnownUnit (Data.UnitsOfMeasure.Internal.Unpack u), u ~ Data.UnitsOfMeasure.Internal.Pack (Data.UnitsOfMeasure.Internal.Unpack u), GHC.Read.Read a) => GHC.Read.Read (Data.UnitsOfMeasure.Internal.Quantity a u)


-- | This module defines a typechecker plugin that solves equations
--   involving units of measure. To use it, add
--   
--   <pre>
--   {-# OPTIONS_GHC -fplugin Data.UnitsOfMeasure.Plugin #-}
--   </pre>
--   
--   above the module header of your source files, or in the
--   <tt>ghc-options</tt> field of your <tt>.cabal</tt> file. You do not
--   need to import this module.
module Data.UnitsOfMeasure.Plugin

-- | The plugin that GHC will load when this module is used with the
--   <tt>-fplugin</tt> option.
plugin :: Plugin


-- | Experimental support for conversions between units with the same
--   dimension, for example feet and metres. This interface is not
--   necessarily stable!
--   
--   Rather than defining dimensions explicitly, we pick a "canonical" base
--   unit for each dimension, and record the conversion ratio between each
--   base unit and the canonical base unit for its dimension. This means we
--   can automatically calculate the conversion ratio between a unit and
--   its canonical representation, and hence between any two units that
--   share a dimension (i.e. have the same canonical representation).
--   
--   For example, to declare <tt>m</tt> as a canonical base unit, write:
--   
--   <pre>
--   instance HasCanonicalBaseUnit "m"
--   </pre>
--   
--   To declare <tt>ft</tt> as a derived unit, write:
--   
--   <pre>
--   instance HasCanonicalBaseUnit "ft" where
--     type CanonicalBaseUnit "ft" = "m"
--     conversionBase _ = [u| 3.28 ft/m |]
--   </pre>
--   
--   The above declarations can be written using the <tt>u</tt> declaration
--   quasiquoter as <tt>[<tt>u</tt>| m, ft = 1 % 3.28 ft/m |]</tt>, or
--   generated automatically using <tt>declareConvertibleUnit</tt>.
--   
--   Now it is possible to <a>convert</a> between quantities whose units
--   involve feet or metres. For example:
--   
--   <pre>
--   &gt;&gt;&gt; convert [u| 10m |] :: Quantity Double [u| ft |]
--   [u| 32.8 ft |]
--   
--   &gt;&gt;&gt; convert [u| 3ft^2 |] :: Quantity Double [u| m^2 |]
--   [u| 0.27885187388459254 m^2 |]
--   </pre>
--   
--   You are likely to get unpleasant compiler error messages if you
--   attempt to convert without the units being fully determined by type
--   inference, or if the units do not have the same dimension.
--   
--   If you wish to define a dimensionless unit that requires explicit
--   conversion to <tt>1</tt>, such as radians, write <tt>[<tt>u</tt>| rad
--   = 1 1 |]</tt>. The syntax <tt>[<tt>u</tt>| dimensionless = 1 |]</tt>
--   defines <tt>dimensionless</tt> as a unit synonym for <tt>1</tt> that
--   does not require conversion.
module Data.UnitsOfMeasure.Convert

-- | Automatically convert a quantity with units <tt>u</tt> so that its
--   units are <tt>v</tt>, provided <tt>u</tt> and <tt>v</tt> have the same
--   dimension.
convert :: forall a u v. (Fractional a, Convertible u v) => Quantity a u -> Quantity a v

-- | Calculate the conversion ratio between two units with the same
--   dimension. The slightly unusual proxy arguments allow this to be
--   called using quasiquoters to specify the units, for example
--   <tt><a>ratio</a> [u| ft |] [u| m |]</tt>.
ratio :: forall a u v (proxy :: Unit -> *) proxy'. (Fractional a, Convertible u v) => proxy' (proxy u) -> proxy' (proxy v) -> Quantity a (u /: v)

-- | Class to capture the dimensions to which base units belong. For a
--   canonical base unit, the class instance can be left empty.
class IsCanonical (Unpack (CanonicalBaseUnit b)) => HasCanonicalBaseUnit (b :: Symbol) where {
    type family CanonicalBaseUnit b :: Unit;
    type CanonicalBaseUnit b = Base b;
}

-- | The conversion ratio between this base unit and its canonical base
--   unit. If <tt>b</tt> is canonical then this ratio is <tt>1</tt>.
conversionBase :: HasCanonicalBaseUnit b => proxy b -> Quantity Rational (Base b /: CanonicalBaseUnit b)

-- | The conversion ratio between this base unit and its canonical base
--   unit. If <tt>b</tt> is canonical then this ratio is <tt>1</tt>.
conversionBase :: (HasCanonicalBaseUnit b, (Base b ~ CanonicalBaseUnit b)) => proxy b -> Quantity Rational (Base b /: CanonicalBaseUnit b)

-- | A unit is "good" if all its base units have been defined, and have
--   associated canonical base units.
type Good u = (u ~ Pack (Unpack u), KnownUnit (Unpack u), HasCanonical (Unpack u))

-- | This constraint will be satisfied if all the base units in a
--   syntactically represented unit are in their canonical form.

-- | This constraint will be satisfied if all the base units in a
--   syntactically represented unit have associated canonical
--   representations.

-- | Two units are convertible if they are both <a>Good</a> and they have
--   the same canonical units (and hence the same dimension).
type Convertible u v = (Good u, Good v, ToCanonicalUnit u ~ ToCanonicalUnit v)

-- | Converts a unit to the corresponding canonical representation.
type ToCanonicalUnit u = ToCBU (Unpack u)


-- | See <a>Data.UnitsOfMeasure.Tutorial</a> for how to use this module.
module Data.UnitsOfMeasure

-- | (Kind) Units of measure
data Unit

-- | Base unit

-- | Dimensionless unit (identity element)

-- | Multiplication for units of measure

-- | Division for units of measure

-- | Exponentiation (to a positive power) for units of measure; negative
--   exponents are not yet supported (they require an Integer kind)

-- | A <tt>Quantity a u</tt> is represented identically to a value of
--   underlying numeric type <tt>a</tt>, but with units <tt>u</tt>.
data Quantity a (u :: Unit)

-- | Extract the underlying value of a quantity
unQuantity :: Quantity a u -> a

-- | Zero is polymorphic in its units: this is required because the
--   <a>Num</a> instance constrains the quantity to be dimensionless, so
--   <tt>0 :: Quantity a u</tt> is not well typed.
zero :: Num a => Quantity a u

-- | Construct a <a>Quantity</a> from a dimensionless value. Note that for
--   numeric literals, the <a>Num</a> and <a>Fractional</a> instances allow
--   them to be treated as quantities directly.
mk :: a -> Quantity a One

-- | Addition (<a>+</a>) of quantities requires the units to match.
(+:) :: Num a => Quantity a u -> Quantity a u -> Quantity a u
infixl 6 +:

-- | Multiplication (<a>*</a>) of quantities multiplies the units.
(*:) :: (Num a, w ~~ (u *: v)) => Quantity a u -> Quantity a v -> Quantity a w
infixl 7 *:

-- | Subtraction (<a>-</a>) of quantities requires the units to match.
(-:) :: Num a => Quantity a u -> Quantity a u -> Quantity a u
infixl 6 -:

-- | Negation (<a>negate</a>) of quantities is polymorphic in the units.
negate' :: Num a => Quantity a u -> Quantity a u

-- | Absolute value (<a>abs</a>) of quantities is polymorphic in the units.
abs' :: Num a => Quantity a u -> Quantity a u

-- | The sign (<a>signum</a>) of a quantity gives a dimensionless result.
signum' :: Num a => Quantity a u -> Quantity a One

-- | Convert an <a>Integer</a> quantity into any <a>Integral</a> type
--   (<a>fromInteger</a>).
fromInteger' :: Integral a => Quantity Integer u -> Quantity a u

-- | Division (<a>/</a>) of quantities divides the units.
(/:) :: (Fractional a, w ~~ (u /: v)) => Quantity a u -> Quantity a v -> Quantity a w
infixl 7 /:

-- | Reciprocal (<a>recip</a>) of quantities reciprocates the units.
recip' :: (Fractional a, w ~~ (One /: u)) => Quantity a u -> Quantity a w

-- | Convert a <a>Rational</a> quantity into any <a>Fractional</a> type
--   (<a>fromRational</a>).
fromRational' :: Fractional a => Quantity Rational u -> Quantity a u

-- | Convert any <a>Real</a> quantity into a <a>Rational</a> type
--   (<a>toRational</a>).
toRational' :: Real a => Quantity a u -> Quantity Rational u

-- | Taking the square root (<a>sqrt</a>) of a quantity requires its units
--   to be a square. Fractional units are not currently supported.
sqrt' :: (Floating a, w ~~ (u ^: 2)) => Quantity a w -> Quantity a u

-- | The <a>u</a> quasiquoter may be used to create units or quantities;
--   its meaning depends on the context:
--   
--   <ul>
--   <li>in a declaration context, it creates new base and derived units
--   from a comma-separated list of names with optional definitions, for
--   example <tt>[<a>u</a>|kg, m, s, N = kg * m/s^2|]</tt>;</li>
--   <li>in a type context, it parses a single unit and converts it into
--   the corresponding type, so <tt>[<a>u</a>|m/s|]</tt> becomes the type
--   <tt><a>Base</a> "m" /: <a>Base</a> "s"</tt> of kind <a>Unit</a>;</li>
--   <li>in an expression context, it can be used to create a
--   <a>Quantity</a> corresponding to a numeric literal, for example
--   <tt>[<a>u</a>|42 m|]</tt> is an expression of type <tt><a>Quantity</a>
--   <a>Integer</a> (<a>Base</a> "m")</tt>, <tt>[<a>u</a>|-2.2 m|]</tt> is
--   an expression of type <tt><a>Quantity</a> <a>Double</a> (<a>Base</a>
--   "m")</tt>, and <tt>[<a>u</a>|m|]</tt> alone is a function of type
--   <tt>a -&gt; <a>Quantity</a> a (<a>Base</a> "m")</tt>;</li>
--   <li>in a pattern context, it can be used to match on a particular
--   value of a quantity with an <a>Integer</a> or <a>Rational</a>
--   representation type, for example <tt>f [<a>u</a>| 42 m |] =
--   <a>True</a></tt> is a (partial) function of type <tt><a>Quantity</a>
--   <a>Integer</a> [u|m|] -&gt; Bool</tt>.</li>
--   </ul>
u :: QuasiQuoter

-- | Declare a canonical base unit of the given name, which must not
--   contain any spaces, e.g.
--   
--   <pre>
--   declareBaseUnit "m"
--   </pre>
--   
--   produces
--   
--   <pre>
--   type instance MkUnit "m" = Base "m"
--   instance HasCanonicalBaseUnit "m"
--   </pre>
--   
--   This can also be written <tt>[<a>u</a>| m |]</tt>.
declareBaseUnit :: String -> Q [Dec]

-- | Declare a derived unit with the given name and definition, e.g.
--   
--   <pre>
--   declareDerivedUnit "N" "kg m / s^2"
--   </pre>
--   
--   produces
--   
--   <pre>
--   type instance MkUnit "N" = Base "kg" *: Base "m" /: Base "s" ^: 2
--   </pre>
--   
--   This can also be written <tt>[<a>u</a>| N = kg m / s^2 |]</tt>.
declareDerivedUnit :: String -> String -> Q [Dec]

-- | Declare a base unit of the given name, which is convertible to the
--   canonical base unit, e.g.
--   
--   <pre>
--   declareConvertibleUnit "kilobyte" 1024 "byte"
--   </pre>
--   
--   produces
--   
--   <pre>
--   type instance MkUnit "kilobyte" = Base "kilobyte"
--   instance HasCanonicalBaseUnit "kilobyte" where
--     type CanonicalBaseUnit "kilobyte" = Base "byte"
--     conversionBase _ = [u| 1 % 1024 kilobyte/byte |]
--   </pre>
--   
--   This can also be written <tt>[<a>u</a>| kilobyte = 1024 byte |]</tt>.
--   See <a>Data.UnitsOfMeasure.Convert</a> for more information about
--   conversions.
declareConvertibleUnit :: String -> Rational -> String -> Q [Dec]

-- | Automatically convert a quantity with units <tt>u</tt> so that its
--   units are <tt>v</tt>, provided <tt>u</tt> and <tt>v</tt> have the same
--   dimension.
convert :: forall a u v. (Fractional a, Convertible u v) => Quantity a u -> Quantity a v

-- | This type family is used for translating unit names (as type-level
--   strings) into units. It will be <a>Base</a> for base units or expand
--   the definition for derived units.
--   
--   The instances displayed by Haddock are available only if
--   <a>Data.UnitsOfMeasure.Defs</a> is imported.

-- | Pack up a syntactic representation of a unit as a unit. For example:
--   
--   <pre>
--   <a>Pack</a> ([] <a>:/</a> []) = <a>One</a>
--   </pre>
--   
--   <pre>
--   <a>Pack</a> (["m"] <a>:/</a> ["s","s"]) = <a>Base</a> "m" <a>/:</a> <a>Base</a> "s" ^: 2
--   </pre>
--   
--   This is a perfectly ordinary closed type family. <a>Pack</a> is a left
--   inverse of <a>Unpack</a> up to the equational theory of units, but it
--   is not a right inverse (because there are multiple list
--   representations of the same unit).

-- | Unpack a unit as a syntactic representation, where the order of units
--   is deterministic. For example:
--   
--   <pre>
--   <a>Unpack</a> <a>One</a> = [] <a>:/</a> []
--   </pre>
--   
--   <pre>
--   <a>Unpack</a> (<a>Base</a> "s" <a>*:</a> <a>Base</a> "m") = ["m","s"] <a>:/</a> []
--   </pre>
--   
--   This does not break type soundness because <a>Unpack</a> will reduce
--   only when the unit is entirely constant, and it does not allow the
--   structure of the unit to be observed. The reduction behaviour is
--   implemented by the plugin, because we cannot define it otherwise.

-- | A constraint <tt><a>KnownUnit</a> u</tt> means that <tt>u</tt> must be
--   a concrete unit that is statically known but passed at runtime
class KnownUnit (u :: UnitSyntax Symbol)


-- | This module gives a brief introduction to the <tt>uom-plugin</tt>
--   library.
module Data.UnitsOfMeasure.Tutorial


-- | This module exports some example definitions of base and derived
--   units, for demonstration purposes. In the future, this is likely to
--   change or be moved to a separate package.
module Data.UnitsOfMeasure.Defs

-- | This type family is used for translating unit names (as type-level
--   strings) into units. It will be <a>Base</a> for base units or expand
--   the definition for derived units.
--   
--   The instances displayed by Haddock are available only if
--   <a>Data.UnitsOfMeasure.Defs</a> is imported.
instance Data.UnitsOfMeasure.Convert.HasCanonicalBaseUnit "m"
instance Data.UnitsOfMeasure.Convert.HasCanonicalBaseUnit "kg"
instance Data.UnitsOfMeasure.Convert.HasCanonicalBaseUnit "s"
instance Data.UnitsOfMeasure.Convert.HasCanonicalBaseUnit "A"
instance Data.UnitsOfMeasure.Convert.HasCanonicalBaseUnit "K"
instance Data.UnitsOfMeasure.Convert.HasCanonicalBaseUnit "mol"
instance Data.UnitsOfMeasure.Convert.HasCanonicalBaseUnit "cd"
instance Data.UnitsOfMeasure.Convert.HasCanonicalBaseUnit "km"
instance Data.UnitsOfMeasure.Convert.HasCanonicalBaseUnit "g"
instance Data.UnitsOfMeasure.Convert.HasCanonicalBaseUnit "rad"
instance Data.UnitsOfMeasure.Convert.HasCanonicalBaseUnit "sr"
instance Data.UnitsOfMeasure.Convert.HasCanonicalBaseUnit "min"
instance Data.UnitsOfMeasure.Convert.HasCanonicalBaseUnit "h"
instance Data.UnitsOfMeasure.Convert.HasCanonicalBaseUnit "d"
instance Data.UnitsOfMeasure.Convert.HasCanonicalBaseUnit "ha"
instance Data.UnitsOfMeasure.Convert.HasCanonicalBaseUnit "l"
instance Data.UnitsOfMeasure.Convert.HasCanonicalBaseUnit "t"
instance Data.UnitsOfMeasure.Convert.HasCanonicalBaseUnit "au"
instance Data.UnitsOfMeasure.Convert.HasCanonicalBaseUnit "ft"
instance Data.UnitsOfMeasure.Convert.HasCanonicalBaseUnit "in"
instance Data.UnitsOfMeasure.Convert.HasCanonicalBaseUnit "mi"
