    {- |
        Copyright  : Copyright (C) 2006-2018 Bjorn Buckwalter
        License    : BSD3

        Maintainer : bjorn@buckwalter.se
        Stability  : Stable
        Portability: GHC only?

    Defines types for manipulation of units and quantities without phantom types for their dimensions.
    -}

    {-# LANGUAGE CPP #-}
    {-# LANGUAGE DataKinds #-}
    {-# LANGUAGE DeriveDataTypeable #-}
    {-# LANGUAGE DeriveGeneric #-}
    {-# LANGUAGE FlexibleContexts #-}
    {-# LANGUAGE FlexibleInstances #-}
    {-# LANGUAGE KindSignatures #-}
    {-# LANGUAGE ScopedTypeVariables #-}

    module Numeric.Units.Dimensional.Dynamic
    (
      -- * Dynamic Quantities
      AnyQuantity
    , DynQuantity
    , Demotable
    , Promotable
    , HasDynamicDimension(..), DynamicDimension(..)
    , promoteQuantity, demoteQuantity
    , (*~), (/~), invalidQuantity, polydimensionalZero
      -- * Dynamic Units
    , AnyUnit
    , demoteUnit, promoteUnit, demoteUnit'
    , siUnit, anyUnitName
      -- ** Arithmetic on Dynamic Units
    , (*), (/), (^), recip, applyPrefix
    ) where

    import Control.DeepSeq (NFData)
    import Control.Monad
    #if USE_BINARY
    import qualified Data.Binary
    #endif
    import Data.Data
    import Data.ExactPi
    import Data.Kind
    import Data.Semigroup (Semigroup(..))
    import Data.Monoid (Monoid(..))
    import GHC.Generics
    import Prelude (Eq(..), Num, Fractional, Floating, Show(..), Bool(..), Maybe(..), (.), ($), (++), (&&), id, otherwise, error)
    import qualified Prelude as P
    import Numeric.Units.Dimensional hiding ((*~), (/~), (*), (/), (^), recip, nroot, siUnit)
    import qualified Numeric.Units.Dimensional as Dim
    import Numeric.Units.Dimensional.Coercion
    import Numeric.Units.Dimensional.UnitNames (UnitName, baseUnitName)
    import qualified Numeric.Units.Dimensional.UnitNames.InterchangeNames as I
    import qualified Numeric.Units.Dimensional.UnitNames as N
    import Numeric.Units.Dimensional.Dimensions.TermLevel (HasDynamicDimension(..), DynamicDimension(..), matchDimensions, isCompatibleWith)
    import qualified Numeric.Units.Dimensional.Dimensions.TermLevel as D

    -- | The class of types that can be used to model 'Quantity's that are certain to have a value with
    -- some dimension.
    class Demotable (q :: Type -> Type) where
      demotableOut :: q a -> AnyQuantity a

    -- | The class of types that can be used to model 'Quantity's whose 'Dimension's are
    -- only known dynamically.
    class Promotable (q :: Type -> Type) where
      promotableIn :: AnyQuantity a -> q a
      promotableOut :: q a -> DynQuantity a

    -- | Forgets information about a 'Quantity' or 'AnyQuantity', yielding an 'AnyQuantity' or a 'DynQuantity'.
    demoteQuantity :: (Demotable q, Promotable d) => q a -> d a
    demoteQuantity :: forall (q :: Type -> Type) (d :: Type -> Type) a.
    (Demotable q, Promotable d) =>
    q a -> d a
    demoteQuantity = AnyQuantity a -> d a
    forall a. AnyQuantity a -> d a
    forall (q :: Type -> Type) a. Promotable q => AnyQuantity a -> q a
    promotableIn (AnyQuantity a -> d a) -> (q a -> AnyQuantity a) -> q a -> d a
    forall b c a. (b -> c) -> (a -> b) -> a -> c
    . q a -> AnyQuantity a
    forall a. q a -> AnyQuantity a
    forall (q :: Type -> Type) a. Demotable q => q a -> AnyQuantity a
    demotableOut

    -- | Converts a dynamic quantity such as an 'AnyQuantity' or a 'DynQuantity' into a
    -- 'Quantity', or to 'Nothing' if the dynamic quantity cannot be represented in the
    -- narrower result type.
    promoteQuantity :: forall a d q.(Promotable q, KnownDimension d) => q a -> Maybe (Quantity d a)
    promoteQuantity :: forall a (d :: Dimension) (q :: Type -> Type).
    (Promotable q, KnownDimension d) =>
    q a -> Maybe (Quantity d a)
    promoteQuantity = DynQuantity a -> Maybe (Dimensional ('DQuantity One) d a)
    forall {a} {s :: ExactPi'} {d :: Dimension}.
    DynQuantity a -> Maybe (Dimensional ('DQuantity s) d a)
    promoteQ (DynQuantity a -> Maybe (Dimensional ('DQuantity One) d a))
    -> (q a -> DynQuantity a)
    -> q a
    -> Maybe (Dimensional ('DQuantity One) d a)
    forall b c a. (b -> c) -> (a -> b) -> a -> c
    . q a -> DynQuantity a
    forall a. q a -> DynQuantity a
    forall (q :: Type -> Type) a. Promotable q => q a -> DynQuantity a
    promotableOut
      where
        dim' :: Dimension'
    dim' = Proxy d -> Dimension'
    forall a. HasDimension a => a -> Dimension'
    dimension (Proxy d
    forall {k} (t :: k). Proxy t
    Proxy :: Proxy d)
        promoteQ :: DynQuantity a -> Maybe (Dimensional ('DQuantity s) d a)
    promoteQ (DynQuantity DynamicDimension
    d a
    v) | DynamicDimension
    d DynamicDimension -> Dimension' -> Bool
    forall a. HasDynamicDimension a => a -> Dimension' -> Bool
    `isCompatibleWith` Dimension'
    dim' = Dimensional ('DQuantity s) d a
    -> Maybe (Dimensional ('DQuantity s) d a)
    forall a. a -> Maybe a
    Just (Dimensional ('DQuantity s) d a
     -> Maybe (Dimensional ('DQuantity s) d a))
    -> (a -> Dimensional ('DQuantity s) d a)
    -> a
    -> Maybe (Dimensional ('DQuantity s) d a)
    forall b c a. (b -> c) -> (a -> b) -> a -> c
    . a -> Dimensional ('DQuantity s) d a
    forall (s :: ExactPi') (d :: Dimension) a.
    a -> Dimensional ('DQuantity s) d a
    Quantity (a -> Maybe (Dimensional ('DQuantity s) d a))
    -> a -> Maybe (Dimensional ('DQuantity s) d a)
    forall a b. (a -> b) -> a -> b
    $ a
    v
                                   | Bool
    otherwise                 = Maybe (Dimensional ('DQuantity s) d a)
    forall a. Maybe a
    Nothing

    instance (KnownDimension d) => Demotable (Quantity d) where
      demotableOut :: forall a. Quantity d a -> AnyQuantity a
    demotableOut q :: Quantity d a
    q@(Quantity a
    x) = Dimension' -> a -> AnyQuantity a
    forall a. Dimension' -> a -> AnyQuantity a
    AnyQuantity (Quantity d a -> Dimension'
    forall a. HasDimension a => a -> Dimension'
    dimension Quantity d a
    q) a
    x

    -- | A 'Quantity' whose 'Dimension' is only known dynamically.
    data AnyQuantity a = AnyQuantity !Dimension' !a
      deriving (AnyQuantity a -> AnyQuantity a -> Bool
    (AnyQuantity a -> AnyQuantity a -> Bool)
    -> (AnyQuantity a -> AnyQuantity a -> Bool) -> Eq (AnyQuantity a)
    forall a. Eq a => AnyQuantity a -> AnyQuantity a -> Bool
    forall a. (a -> a -> Bool) -> (a -> a -> Bool) -> Eq a
    $c== :: forall a. Eq a => AnyQuantity a -> AnyQuantity a -> Bool
    == :: AnyQuantity a -> AnyQuantity a -> Bool
    $c/= :: forall a. Eq a => AnyQuantity a -> AnyQuantity a -> Bool
    /= :: AnyQuantity a -> AnyQuantity a -> Bool
    Eq, Typeable (AnyQuantity a)
    Typeable (AnyQuantity a) =>
    (forall (c :: Type -> Type).
     (forall d b. Data d => c (d -> b) -> d -> c b)
     -> (forall g. g -> c g) -> AnyQuantity a -> c (AnyQuantity a))
    -> (forall (c :: Type -> Type).
        (forall b r. Data b => c (b -> r) -> c r)
        -> (forall r. r -> c r) -> Constr -> c (AnyQuantity a))
    -> (AnyQuantity a -> Constr)
    -> (AnyQuantity a -> DataType)
    -> (forall (t :: Type -> Type) (c :: Type -> Type).
        Typeable t =>
        (forall d. Data d => c (t d)) -> Maybe (c (AnyQuantity a)))
    -> (forall (t :: Type -> Type -> Type) (c :: Type -> Type).
        Typeable t =>
        (forall d e. (Data d, Data e) => c (t d e))
        -> Maybe (c (AnyQuantity a)))
    -> ((forall b. Data b => b -> b) -> AnyQuantity a -> AnyQuantity a)
    -> (forall r r'.
        (r -> r' -> r)
        -> r -> (forall d. Data d => d -> r') -> AnyQuantity a -> r)
    -> (forall r r'.
        (r' -> r -> r)
        -> r -> (forall d. Data d => d -> r') -> AnyQuantity a -> r)
    -> (forall u. (forall d. Data d => d -> u) -> AnyQuantity a -> [u])
    -> (forall u.
        Int -> (forall d. Data d => d -> u) -> AnyQuantity a -> u)
    -> (forall (m :: Type -> Type).
        Monad m =>
        (forall d. Data d => d -> m d)
        -> AnyQuantity a -> m (AnyQuantity a))
    -> (forall (m :: Type -> Type).
        MonadPlus m =>
        (forall d. Data d => d -> m d)
        -> AnyQuantity a -> m (AnyQuantity a))
    -> (forall (m :: Type -> Type).
        MonadPlus m =>
        (forall d. Data d => d -> m d)
        -> AnyQuantity a -> m (AnyQuantity a))
    -> Data (AnyQuantity a)
    AnyQuantity a -> Constr
    AnyQuantity a -> DataType
    (forall b. Data b => b -> b) -> AnyQuantity a -> AnyQuantity a
    forall a. Data a => Typeable (AnyQuantity a)
    forall a. Data a => AnyQuantity a -> Constr
    forall a. Data a => AnyQuantity a -> DataType
    forall a.
    Data a =>
    (forall b. Data b => b -> b) -> AnyQuantity a -> AnyQuantity a
    forall a u.
    Data a =>
    Int -> (forall d. Data d => d -> u) -> AnyQuantity a -> u
    forall a u.
    Data a =>
    (forall d. Data d => d -> u) -> AnyQuantity a -> [u]
    forall a r r'.
    Data a =>
    (r -> r' -> r)
    -> r -> (forall d. Data d => d -> r') -> AnyQuantity a -> r
    forall a r r'.
    Data a =>
    (r' -> r -> r)
    -> r -> (forall d. Data d => d -> r') -> AnyQuantity a -> r
    forall a (m :: Type -> Type).
    (Data a, Monad m) =>
    (forall d. Data d => d -> m d)
    -> AnyQuantity a -> m (AnyQuantity a)
    forall a (m :: Type -> Type).
    (Data a, MonadPlus m) =>
    (forall d. Data d => d -> m d)
    -> AnyQuantity a -> m (AnyQuantity a)
    forall a (c :: Type -> Type).
    Data a =>
    (forall b r. Data b => c (b -> r) -> c r)
    -> (forall r. r -> c r) -> Constr -> c (AnyQuantity a)
    forall a (c :: Type -> Type).
    Data a =>
    (forall d b. Data d => c (d -> b) -> d -> c b)
    -> (forall g. g -> c g) -> AnyQuantity a -> c (AnyQuantity a)
    forall a (t :: Type -> Type) (c :: Type -> Type).
    (Data a, Typeable t) =>
    (forall d. Data d => c (t d)) -> Maybe (c (AnyQuantity a))
    forall a (t :: Type -> Type -> Type) (c :: Type -> Type).
    (Data a, Typeable t) =>
    (forall d e. (Data d, Data e) => c (t d e))
    -> Maybe (c (AnyQuantity a))
    forall a.
    Typeable a =>
    (forall (c :: Type -> Type).
     (forall d b. Data d => c (d -> b) -> d -> c b)
     -> (forall g. g -> c g) -> a -> c a)
    -> (forall (c :: Type -> Type).
        (forall b r. Data b => c (b -> r) -> c r)
        -> (forall r. r -> c r) -> Constr -> c a)
    -> (a -> Constr)
    -> (a -> DataType)
    -> (forall (t :: Type -> Type) (c :: Type -> Type).
        Typeable t =>
        (forall d. Data d => c (t d)) -> Maybe (c a))
    -> (forall (t :: Type -> Type -> Type) (c :: Type -> Type).
        Typeable t =>
        (forall d e. (Data d, Data e) => c (t d e)) -> Maybe (c a))
    -> ((forall b. Data b => b -> b) -> a -> a)
    -> (forall r r'.
        (r -> r' -> r) -> r -> (forall d. Data d => d -> r') -> a -> r)
    -> (forall r r'.
        (r' -> r -> r) -> r -> (forall d. Data d => d -> r') -> a -> r)
    -> (forall u. (forall d. Data d => d -> u) -> a -> [u])
    -> (forall u. Int -> (forall d. Data d => d -> u) -> a -> u)
    -> (forall (m :: Type -> Type).
        Monad m =>
        (forall d. Data d => d -> m d) -> a -> m a)
    -> (forall (m :: Type -> Type).
        MonadPlus m =>
        (forall d. Data d => d -> m d) -> a -> m a)
    -> (forall (m :: Type -> Type).
        MonadPlus m =>
        (forall d. Data d => d -> m d) -> a -> m a)
    -> Data a
    forall u. Int -> (forall d. Data d => d -> u) -> AnyQuantity a -> u
    forall u. (forall d. Data d => d -> u) -> AnyQuantity a -> [u]
    forall r r'.
    (r -> r' -> r)
    -> r -> (forall d. Data d => d -> r') -> AnyQuantity a -> r
    forall r r'.
    (r' -> r -> r)
    -> r -> (forall d. Data d => d -> r') -> AnyQuantity a -> r
    forall (m :: Type -> Type).
    Monad m =>
    (forall d. Data d => d -> m d)
    -> AnyQuantity a -> m (AnyQuantity a)
    forall (m :: Type -> Type).
    MonadPlus m =>
    (forall d. Data d => d -> m d)
    -> AnyQuantity a -> m (AnyQuantity a)
    forall (c :: Type -> Type).
    (forall b r. Data b => c (b -> r) -> c r)
    -> (forall r. r -> c r) -> Constr -> c (AnyQuantity a)
    forall (c :: Type -> Type).
    (forall d b. Data d => c (d -> b) -> d -> c b)
    -> (forall g. g -> c g) -> AnyQuantity a -> c (AnyQuantity a)
    forall (t :: Type -> Type) (c :: Type -> Type).
    Typeable t =>
    (forall d. Data d => c (t d)) -> Maybe (c (AnyQuantity a))
    forall (t :: Type -> Type -> Type) (c :: Type -> Type).
    Typeable t =>
    (forall d e. (Data d, Data e) => c (t d e))
    -> Maybe (c (AnyQuantity a))
    $cgfoldl :: forall a (c :: Type -> Type).
    Data a =>
    (forall d b. Data d => c (d -> b) -> d -> c b)
    -> (forall g. g -> c g) -> AnyQuantity a -> c (AnyQuantity a)
    gfoldl :: forall (c :: Type -> Type).
    (forall d b. Data d => c (d -> b) -> d -> c b)
    -> (forall g. g -> c g) -> AnyQuantity a -> c (AnyQuantity a)
    $cgunfold :: forall a (c :: Type -> Type).
    Data a =>
    (forall b r. Data b => c (b -> r) -> c r)
    -> (forall r. r -> c r) -> Constr -> c (AnyQuantity a)
    gunfold :: forall (c :: Type -> Type).
    (forall b r. Data b => c (b -> r) -> c r)
    -> (forall r. r -> c r) -> Constr -> c (AnyQuantity a)
    $ctoConstr :: forall a. Data a => AnyQuantity a -> Constr
    toConstr :: AnyQuantity a -> Constr
    $cdataTypeOf :: forall a. Data a => AnyQuantity a -> DataType
    dataTypeOf :: AnyQuantity a -> DataType
    $cdataCast1 :: forall a (t :: Type -> Type) (c :: Type -> Type).
    (Data a, Typeable t) =>
    (forall d. Data d => c (t d)) -> Maybe (c (AnyQuantity a))
    dataCast1 :: forall (t :: Type -> Type) (c :: Type -> Type).
    Typeable t =>
    (forall d. Data d => c (t d)) -> Maybe (c (AnyQuantity a))
    $cdataCast2 :: forall a (t :: Type -> Type -> Type) (c :: Type -> Type).
    (Data a, Typeable t) =>
    (forall d e. (Data d, Data e) => c (t d e))
    -> Maybe (c (AnyQuantity a))
    dataCast2 :: forall (t :: Type -> Type -> Type) (c :: Type -> Type).
    Typeable t =>
    (forall d e. (Data d, Data e) => c (t d e))
    -> Maybe (c (AnyQuantity a))
    $cgmapT :: forall a.
    Data a =>
    (forall b. Data b => b -> b) -> AnyQuantity a -> AnyQuantity a
    gmapT :: (forall b. Data b => b -> b) -> AnyQuantity a -> AnyQuantity a
    $cgmapQl :: forall a r r'.
    Data a =>
    (r -> r' -> r)
    -> r -> (forall d. Data d => d -> r') -> AnyQuantity a -> r
    gmapQl :: forall r r'.
    (r -> r' -> r)
    -> r -> (forall d. Data d => d -> r') -> AnyQuantity a -> r
    $cgmapQr :: forall a r r'.
    Data a =>
    (r' -> r -> r)
    -> r -> (forall d. Data d => d -> r') -> AnyQuantity a -> r
    gmapQr :: forall r r'.
    (r' -> r -> r)
    -> r -> (forall d. Data d => d -> r') -> AnyQuantity a -> r
    $cgmapQ :: forall a u.
    Data a =>
    (forall d. Data d => d -> u) -> AnyQuantity a -> [u]
    gmapQ :: forall u. (forall d. Data d => d -> u) -> AnyQuantity a -> [u]
    $cgmapQi :: forall a u.
    Data a =>
    Int -> (forall d. Data d => d -> u) -> AnyQuantity a -> u
    gmapQi :: forall u. Int -> (forall d. Data d => d -> u) -> AnyQuantity a -> u
    $cgmapM :: forall a (m :: Type -> Type).
    (Data a, Monad m) =>
    (forall d. Data d => d -> m d)
    -> AnyQuantity a -> m (AnyQuantity a)
    gmapM :: forall (m :: Type -> Type).
    Monad m =>
    (forall d. Data d => d -> m d)
    -> AnyQuantity a -> m (AnyQuantity a)
    $cgmapMp :: forall a (m :: Type -> Type).
    (Data a, MonadPlus m) =>
    (forall d. Data d => d -> m d)
    -> AnyQuantity a -> m (AnyQuantity a)
    gmapMp :: forall (m :: Type -> Type).
    MonadPlus m =>
    (forall d. Data d => d -> m d)
    -> AnyQuantity a -> m (AnyQuantity a)
    $cgmapMo :: forall a (m :: Type -> Type).
    (Data a, MonadPlus m) =>
    (forall d. Data d => d -> m d)
    -> AnyQuantity a -> m (AnyQuantity a)
    gmapMo :: forall (m :: Type -> Type).
    MonadPlus m =>
    (forall d. Data d => d -> m d)
    -> AnyQuantity a -> m (AnyQuantity a)
    Data, (forall x. AnyQuantity a -> Rep (AnyQuantity a) x)
    -> (forall x. Rep (AnyQuantity a) x -> AnyQuantity a)
    -> Generic (AnyQuantity a)
    forall x. Rep (AnyQuantity a) x -> AnyQuantity a
    forall x. AnyQuantity a -> Rep (AnyQuantity a) x
    forall a.
    (forall x. a -> Rep a x) -> (forall x. Rep a x -> a) -> Generic a
    forall a x. Rep (AnyQuantity a) x -> AnyQuantity a
    forall a x. AnyQuantity a -> Rep (AnyQuantity a) x
    $cfrom :: forall a x. AnyQuantity a -> Rep (AnyQuantity a) x
    from :: forall x. AnyQuantity a -> Rep (AnyQuantity a) x
    $cto :: forall a x. Rep (AnyQuantity a) x -> AnyQuantity a
    to :: forall x. Rep (AnyQuantity a) x -> AnyQuantity a
    Generic, (forall a. AnyQuantity a -> Rep1 AnyQuantity a)
    -> (forall a. Rep1 AnyQuantity a -> AnyQuantity a)
    -> Generic1 AnyQuantity
    forall a. Rep1 AnyQuantity a -> AnyQuantity a
    forall a. AnyQuantity a -> Rep1 AnyQuantity a
    forall k (f :: k -> Type).
    (forall (a :: k). f a -> Rep1 f a)
    -> (forall (a :: k). Rep1 f a -> f a) -> Generic1 f
    $cfrom1 :: forall a. AnyQuantity a -> Rep1 AnyQuantity a
    from1 :: forall a. AnyQuantity a -> Rep1 AnyQuantity a
    $cto1 :: forall a. Rep1 AnyQuantity a -> AnyQuantity a
    to1 :: forall a. Rep1 AnyQuantity a -> AnyQuantity a
    Generic1, Typeable)

    instance (Show a) => Show (AnyQuantity a) where
      show :: AnyQuantity a -> String
    show (AnyQuantity Dimension'
    d a
    a) | Dimension'
    d Dimension' -> Dimension' -> Bool
    forall a. Eq a => a -> a -> Bool
    == Dimension'
    D.dOne = a -> String
    forall a. Show a => a -> String
    show a
    a
                             | Bool
    otherwise   = a -> String
    forall a. Show a => a -> String
    show a
    a String -> ShowS
    forall a. [a] -> [a] -> [a]
    ++ String
    " " String -> ShowS
    forall a. [a] -> [a] -> [a]
    ++ (UnitName 'NonMetric -> String
    forall a. Show a => a -> String
    show (UnitName 'NonMetric -> String)
    -> (Dimension' -> UnitName 'NonMetric) -> Dimension' -> String
    forall b c a. (b -> c) -> (a -> b) -> a -> c
    . Dimension' -> UnitName 'NonMetric
    baseUnitName (Dimension' -> String) -> Dimension' -> String
    forall a b. (a -> b) -> a -> b
    $ Dimension'
    d)

    instance HasDynamicDimension (AnyQuantity a) where

    instance HasDimension (AnyQuantity a) where
      dimension :: AnyQuantity a -> Dimension'
    dimension (AnyQuantity Dimension'
    d a
    _) = Dimension'
    d

    instance NFData a => NFData (AnyQuantity a) -- instance is derived from Generic instance

    instance Promotable AnyQuantity where
      promotableIn :: forall a. AnyQuantity a -> AnyQuantity a
    promotableIn = AnyQuantity a -> AnyQuantity a
    forall a. a -> a
    id
      promotableOut :: forall a. AnyQuantity a -> DynQuantity a
    promotableOut (AnyQuantity Dimension'
    d a
    a) = DynamicDimension -> a -> DynQuantity a
    forall a. DynamicDimension -> a -> DynQuantity a
    DynQuantity (Dimension' -> DynamicDimension
    SomeDimension Dimension'
    d) a
    a

    instance Demotable AnyQuantity where
      demotableOut :: forall a. AnyQuantity a -> AnyQuantity a
    demotableOut = AnyQuantity a -> AnyQuantity a
    forall a. a -> a
    id

    -- | 'AnyQuantity's form a 'Semigroup' under multiplication, but not under addition because
    -- they may not be added together if their dimensions do not match.
    instance Num a => Semigroup (AnyQuantity a) where
      (AnyQuantity Dimension'
    d1 a
    a1) <> :: AnyQuantity a -> AnyQuantity a -> AnyQuantity a
    <> (AnyQuantity Dimension'
    d2 a
    a2) = Dimension' -> a -> AnyQuantity a
    forall a. Dimension' -> a -> AnyQuantity a
    AnyQuantity (Dimension'
    d1 Dimension' -> Dimension' -> Dimension'
    D.* Dimension'
    d2) (a
    a1 a -> a -> a
    forall a. Num a => a -> a -> a
    P.* a
    a2)

    -- | 'AnyQuantity's form a 'Monoid' under multiplication, but not under addition because
    -- they may not be added together if their dimensions do not match.
    instance Num a => Monoid (AnyQuantity a) where
      mempty :: AnyQuantity a
    mempty = Dimensional ('DQuantity One) DOne a -> AnyQuantity a
    forall (q :: Type -> Type) (d :: Type -> Type) a.
    (Demotable q, Promotable d) =>
    q a -> d a
    demoteQuantity (a
    1 a -> Unit 'NonMetric DOne a -> Dimensional ('DQuantity One) DOne a
    forall a (m :: Metricality) (d :: Dimension).
    Num a =>
    a -> Unit m d a -> Quantity d a
    Dim.*~ Unit 'NonMetric DOne a
    forall a. Num a => Unit 'NonMetric DOne a
    one)
      mappend :: AnyQuantity a -> AnyQuantity a -> AnyQuantity a
    mappend = AnyQuantity a -> AnyQuantity a -> AnyQuantity a
    forall a. Semigroup a => a -> a -> a
    (<>)

    #if USE_BINARY
    instance (Data.Binary.Binary a) => Data.Binary.Binary (AnyQuantity a)
    #endif

    -- | Possibly a 'Quantity' whose 'Dimension' is only known dynamically.
    --
    -- By modeling the absence of a value, this type differs from 'AnyQuantity' in that it may
    -- not be a 'Quantity' of any 'Dimension' whatsoever, but in exchange it gains instances
    -- for the common numeric classes. It's therefore useful for manipulating, and not merely storing,
    -- quantities of unknown dimension.
    --
    -- This type also contains a 'polydimensionalZero', representing zero value of any dimension.
    --
    -- Note that the 'Eq' instance for 'DynQuantity' equates all representations of an invalid value,
    -- and also does not equate polydimensional zero with zero of any specific dimension.
    data DynQuantity a = DynQuantity !DynamicDimension a -- we can't have strictness annotation on a as it is sometimes undefined
      deriving (Typeable (DynQuantity a)
    Typeable (DynQuantity a) =>
    (forall (c :: Type -> Type).
     (forall d b. Data d => c (d -> b) -> d -> c b)
     -> (forall g. g -> c g) -> DynQuantity a -> c (DynQuantity a))
    -> (forall (c :: Type -> Type).
        (forall b r. Data b => c (b -> r) -> c r)
        -> (forall r. r -> c r) -> Constr -> c (DynQuantity a))
    -> (DynQuantity a -> Constr)
    -> (DynQuantity a -> DataType)
    -> (forall (t :: Type -> Type) (c :: Type -> Type).
        Typeable t =>
        (forall d. Data d => c (t d)) -> Maybe (c (DynQuantity a)))
    -> (forall (t :: Type -> Type -> Type) (c :: Type -> Type).
        Typeable t =>
        (forall d e. (Data d, Data e) => c (t d e))
        -> Maybe (c (DynQuantity a)))
    -> ((forall b. Data b => b -> b) -> DynQuantity a -> DynQuantity a)
    -> (forall r r'.
        (r -> r' -> r)
        -> r -> (forall d. Data d => d -> r') -> DynQuantity a -> r)
    -> (forall r r'.
        (r' -> r -> r)
        -> r -> (forall d. Data d => d -> r') -> DynQuantity a -> r)
    -> (forall u. (forall d. Data d => d -> u) -> DynQuantity a -> [u])
    -> (forall u.
        Int -> (forall d. Data d => d -> u) -> DynQuantity a -> u)
    -> (forall (m :: Type -> Type).
        Monad m =>
        (forall d. Data d => d -> m d)
        -> DynQuantity a -> m (DynQuantity a))
    -> (forall (m :: Type -> Type).
        MonadPlus m =>
        (forall d. Data d => d -> m d)
        -> DynQuantity a -> m (DynQuantity a))
    -> (forall (m :: Type -> Type).
        MonadPlus m =>
        (forall d. Data d => d -> m d)
        -> DynQuantity a -> m (DynQuantity a))
    -> Data (DynQuantity a)
    DynQuantity a -> Constr
    DynQuantity a -> DataType
    (forall b. Data b => b -> b) -> DynQuantity a -> DynQuantity a
    forall a. Data a => Typeable (DynQuantity a)
    forall a. Data a => DynQuantity a -> Constr
    forall a. Data a => DynQuantity a -> DataType
    forall a.
    Data a =>
    (forall b. Data b => b -> b) -> DynQuantity a -> DynQuantity a
    forall a u.
    Data a =>
    Int -> (forall d. Data d => d -> u) -> DynQuantity a -> u
    forall a u.
    Data a =>
    (forall d. Data d => d -> u) -> DynQuantity a -> [u]
    forall a r r'.
    Data a =>
    (r -> r' -> r)
    -> r -> (forall d. Data d => d -> r') -> DynQuantity a -> r
    forall a r r'.
    Data a =>
    (r' -> r -> r)
    -> r -> (forall d. Data d => d -> r') -> DynQuantity a -> r
    forall a (m :: Type -> Type).
    (Data a, Monad m) =>
    (forall d. Data d => d -> m d)
    -> DynQuantity a -> m (DynQuantity a)
    forall a (m :: Type -> Type).
    (Data a, MonadPlus m) =>
    (forall d. Data d => d -> m d)
    -> DynQuantity a -> m (DynQuantity a)
    forall a (c :: Type -> Type).
    Data a =>
    (forall b r. Data b => c (b -> r) -> c r)
    -> (forall r. r -> c r) -> Constr -> c (DynQuantity a)
    forall a (c :: Type -> Type).
    Data a =>
    (forall d b. Data d => c (d -> b) -> d -> c b)
    -> (forall g. g -> c g) -> DynQuantity a -> c (DynQuantity a)
    forall a (t :: Type -> Type) (c :: Type -> Type).
    (Data a, Typeable t) =>
    (forall d. Data d => c (t d)) -> Maybe (c (DynQuantity a))
    forall a (t :: Type -> Type -> Type) (c :: Type -> Type).
    (Data a, Typeable t) =>
    (forall d e. (Data d, Data e) => c (t d e))
    -> Maybe (c (DynQuantity a))
    forall a.
    Typeable a =>
    (forall (c :: Type -> Type).
     (forall d b. Data d => c (d -> b) -> d -> c b)
     -> (forall g. g -> c g) -> a -> c a)
    -> (forall (c :: Type -> Type).
        (forall b r. Data b => c (b -> r) -> c r)
        -> (forall r. r -> c r) -> Constr -> c a)
    -> (a -> Constr)
    -> (a -> DataType)
    -> (forall (t :: Type -> Type) (c :: Type -> Type).
        Typeable t =>
        (forall d. Data d => c (t d)) -> Maybe (c a))
    -> (forall (t :: Type -> Type -> Type) (c :: Type -> Type).
        Typeable t =>
        (forall d e. (Data d, Data e) => c (t d e)) -> Maybe (c a))
    -> ((forall b. Data b => b -> b) -> a -> a)
    -> (forall r r'.
        (r -> r' -> r) -> r -> (forall d. Data d => d -> r') -> a -> r)
    -> (forall r r'.
        (r' -> r -> r) -> r -> (forall d. Data d => d -> r') -> a -> r)
    -> (forall u. (forall d. Data d => d -> u) -> a -> [u])
    -> (forall u. Int -> (forall d. Data d => d -> u) -> a -> u)
    -> (forall (m :: Type -> Type).
        Monad m =>
        (forall d. Data d => d -> m d) -> a -> m a)
    -> (forall (m :: Type -> Type).
        MonadPlus m =>
        (forall d. Data d => d -> m d) -> a -> m a)
    -> (forall (m :: Type -> Type).
        MonadPlus m =>
        (forall d. Data d => d -> m d) -> a -> m a)
    -> Data a
    forall u. Int -> (forall d. Data d => d -> u) -> DynQuantity a -> u
    forall u. (forall d. Data d => d -> u) -> DynQuantity a -> [u]
    forall r r'.
    (r -> r' -> r)
    -> r -> (forall d. Data d => d -> r') -> DynQuantity a -> r
    forall r r'.
    (r' -> r -> r)
    -> r -> (forall d. Data d => d -> r') -> DynQuantity a -> r
    forall (m :: Type -> Type).
    Monad m =>
    (forall d. Data d => d -> m d)
    -> DynQuantity a -> m (DynQuantity a)
    forall (m :: Type -> Type).
    MonadPlus m =>
    (forall d. Data d => d -> m d)
    -> DynQuantity a -> m (DynQuantity a)
    forall (c :: Type -> Type).
    (forall b r. Data b => c (b -> r) -> c r)
    -> (forall r. r -> c r) -> Constr -> c (DynQuantity a)
    forall (c :: Type -> Type).
    (forall d b. Data d => c (d -> b) -> d -> c b)
    -> (forall g. g -> c g) -> DynQuantity a -> c (DynQuantity a)
    forall (t :: Type -> Type) (c :: Type -> Type).
    Typeable t =>
    (forall d. Data d => c (t d)) -> Maybe (c (DynQuantity a))
    forall (t :: Type -> Type -> Type) (c :: Type -> Type).
    Typeable t =>
    (forall d e. (Data d, Data e) => c (t d e))
    -> Maybe (c (DynQuantity a))
    $cgfoldl :: forall a (c :: Type -> Type).
    Data a =>
    (forall d b. Data d => c (d -> b) -> d -> c b)
    -> (forall g. g -> c g) -> DynQuantity a -> c (DynQuantity a)
    gfoldl :: forall (c :: Type -> Type).
    (forall d b. Data d => c (d -> b) -> d -> c b)
    -> (forall g. g -> c g) -> DynQuantity a -> c (DynQuantity a)
    $cgunfold :: forall a (c :: Type -> Type).
    Data a =>
    (forall b r. Data b => c (b -> r) -> c r)
    -> (forall r. r -> c r) -> Constr -> c (DynQuantity a)
    gunfold :: forall (c :: Type -> Type).
    (forall b r. Data b => c (b -> r) -> c r)
    -> (forall r. r -> c r) -> Constr -> c (DynQuantity a)
    $ctoConstr :: forall a. Data a => DynQuantity a -> Constr
    toConstr :: DynQuantity a -> Constr
    $cdataTypeOf :: forall a. Data a => DynQuantity a -> DataType
    dataTypeOf :: DynQuantity a -> DataType
    $cdataCast1 :: forall a (t :: Type -> Type) (c :: Type -> Type).
    (Data a, Typeable t) =>
    (forall d. Data d => c (t d)) -> Maybe (c (DynQuantity a))
    dataCast1 :: forall (t :: Type -> Type) (c :: Type -> Type).
    Typeable t =>
    (forall d. Data d => c (t d)) -> Maybe (c (DynQuantity a))
    $cdataCast2 :: forall a (t :: Type -> Type -> Type) (c :: Type -> Type).
    (Data a, Typeable t) =>
    (forall d e. (Data d, Data e) => c (t d e))
    -> Maybe (c (DynQuantity a))
    dataCast2 :: forall (t :: Type -> Type -> Type) (c :: Type -> Type).
    Typeable t =>
    (forall d e. (Data d, Data e) => c (t d e))
    -> Maybe (c (DynQuantity a))
    $cgmapT :: forall a.
    Data a =>
    (forall b. Data b => b -> b) -> DynQuantity a -> DynQuantity a
    gmapT :: (forall b. Data b => b -> b) -> DynQuantity a -> DynQuantity a
    $cgmapQl :: forall a r r'.
    Data a =>
    (r -> r' -> r)
    -> r -> (forall d. Data d => d -> r') -> DynQuantity a -> r
    gmapQl :: forall r r'.
    (r -> r' -> r)
    -> r -> (forall d. Data d => d -> r') -> DynQuantity a -> r
    $cgmapQr :: forall a r r'.
    Data a =>
    (r' -> r -> r)
    -> r -> (forall d. Data d => d -> r') -> DynQuantity a -> r
    gmapQr :: forall r r'.
    (r' -> r -> r)
    -> r -> (forall d. Data d => d -> r') -> DynQuantity a -> r
    $cgmapQ :: forall a u.
    Data a =>
    (forall d. Data d => d -> u) -> DynQuantity a -> [u]
    gmapQ :: forall u. (forall d. Data d => d -> u) -> DynQuantity a -> [u]
    $cgmapQi :: forall a u.
    Data a =>
    Int -> (forall d. Data d => d -> u) -> DynQuantity a -> u
    gmapQi :: forall u. Int -> (forall d. Data d => d -> u) -> DynQuantity a -> u
    $cgmapM :: forall a (m :: Type -> Type).
    (Data a, Monad m) =>
    (forall d. Data d => d -> m d)
    -> DynQuantity a -> m (DynQuantity a)
    gmapM :: forall (m :: Type -> Type).
    Monad m =>
    (forall d. Data d => d -> m d)
    -> DynQuantity a -> m (DynQuantity a)
    $cgmapMp :: forall a (m :: Type -> Type).
    (Data a, MonadPlus m) =>
    (forall d. Data d => d -> m d)
    -> DynQuantity a -> m (DynQuantity a)
    gmapMp :: forall (m :: Type -> Type).
    MonadPlus m =>
    (forall d. Data d => d -> m d)
    -> DynQuantity a -> m (DynQuantity a)
    $cgmapMo :: forall a (m :: Type -> Type).
    (Data a, MonadPlus m) =>
    (forall d. Data d => d -> m d)
    -> DynQuantity a -> m (DynQuantity a)
    gmapMo :: forall (m :: Type -> Type).
    MonadPlus m =>
    (forall d. Data d => d -> m d)
    -> DynQuantity a -> m (DynQuantity a)
    Data, (forall x. DynQuantity a -> Rep (DynQuantity a) x)
    -> (forall x. Rep (DynQuantity a) x -> DynQuantity a)
    -> Generic (DynQuantity a)
    forall x. Rep (DynQuantity a) x -> DynQuantity a
    forall x. DynQuantity a -> Rep (DynQuantity a) x
    forall a.
    (forall x. a -> Rep a x) -> (forall x. Rep a x -> a) -> Generic a
    forall a x. Rep (DynQuantity a) x -> DynQuantity a
    forall a x. DynQuantity a -> Rep (DynQuantity a) x
    $cfrom :: forall a x. DynQuantity a -> Rep (DynQuantity a) x
    from :: forall x. DynQuantity a -> Rep (DynQuantity a) x
    $cto :: forall a x. Rep (DynQuantity a) x -> DynQuantity a
    to :: forall x. Rep (DynQuantity a) x -> DynQuantity a
    Generic, (forall a. DynQuantity a -> Rep1 DynQuantity a)
    -> (forall a. Rep1 DynQuantity a -> DynQuantity a)
    -> Generic1 DynQuantity
    forall a. Rep1 DynQuantity a -> DynQuantity a
    forall a. DynQuantity a -> Rep1 DynQuantity a
    forall k (f :: k -> Type).
    (forall (a :: k). f a -> Rep1 f a)
    -> (forall (a :: k). Rep1 f a -> f a) -> Generic1 f
    $cfrom1 :: forall a. DynQuantity a -> Rep1 DynQuantity a
    from1 :: forall a. DynQuantity a -> Rep1 DynQuantity a
    $cto1 :: forall a. Rep1 DynQuantity a -> DynQuantity a
    to1 :: forall a. Rep1 DynQuantity a -> DynQuantity a
    Generic1, Typeable)

    instance Eq a => Eq (DynQuantity a) where
      (DynQuantity DynamicDimension
    NoDimension a
    _) == :: DynQuantity a -> DynQuantity a -> Bool
    == (DynQuantity DynamicDimension
    NoDimension a
    _) = Bool
    True -- all invalid quantities are equal
      (DynQuantity DynamicDimension
    NoDimension a
    _) == DynQuantity a
    _                           = Bool
    False -- invalid quanties are not equal to any other quantity
      DynQuantity a
    _                           == (DynQuantity DynamicDimension
    NoDimension a
    _) = Bool
    False
      (DynQuantity DynamicDimension
    d1 a
    v1)         == (DynQuantity DynamicDimension
    d2 a
    v2)         = DynamicDimension
    d1 DynamicDimension -> DynamicDimension -> Bool
    forall a. Eq a => a -> a -> Bool
    == DynamicDimension
    d2 Bool -> Bool -> Bool
    && a
    v1 a -> a -> Bool
    forall a. Eq a => a -> a -> Bool
    == a
    v2

    instance NFData a => NFData (DynQuantity a) -- instance is derived from Generic instance

    instance Show a => Show (DynQuantity a) where
      show :: DynQuantity a -> String
    show (DynQuantity DynamicDimension
    NoDimension a
    _) = String
    "invalidQuantity"
      show (DynQuantity DynamicDimension
    AnyDimension a
    v) = a -> String
    forall a. Show a => a -> String
    show a
    v
      show (DynQuantity (SomeDimension Dimension'
    d) a
    v) = AnyQuantity a -> String
    forall a. Show a => a -> String
    show (AnyQuantity a -> String) -> AnyQuantity a -> String
    forall a b. (a -> b) -> a -> b
    $ Dimension' -> a -> AnyQuantity a
    forall a. Dimension' -> a -> AnyQuantity a
    AnyQuantity Dimension'
    d a
    v

    instance Promotable DynQuantity where
      promotableIn :: forall a. AnyQuantity a -> DynQuantity a
    promotableIn (AnyQuantity Dimension'
    d a
    a) = DynamicDimension -> a -> DynQuantity a
    forall a. DynamicDimension -> a -> DynQuantity a
    DynQuantity (Dimension' -> DynamicDimension
    SomeDimension Dimension'
    d) a
    a
      promotableOut :: forall a. DynQuantity a -> DynQuantity a
    promotableOut = DynQuantity a -> DynQuantity a
    forall a. a -> a
    id

    instance HasDynamicDimension (DynQuantity a) where
      dynamicDimension :: DynQuantity a -> DynamicDimension
    dynamicDimension (DynQuantity DynamicDimension
    d a
    _) = DynamicDimension
    d

    instance Num a => Num (DynQuantity a) where
      DynQuantity a
    x + :: DynQuantity a -> DynQuantity a -> DynQuantity a
    + DynQuantity a
    y = (DynamicDimension -> DynamicDimension -> DynamicDimension)
    -> (a -> a -> a) -> DynQuantity a -> DynQuantity a -> DynQuantity a
    forall a.
    (DynamicDimension -> DynamicDimension -> DynamicDimension)
    -> (a -> a -> a) -> DynQuantity a -> DynQuantity a -> DynQuantity a
    liftDQ2 DynamicDimension -> DynamicDimension -> DynamicDimension
    matchDimensions a -> a -> a
    forall a. Num a => a -> a -> a
    (P.+) DynQuantity a
    x DynQuantity a
    y
      DynQuantity a
    x - :: DynQuantity a -> DynQuantity a -> DynQuantity a
    - DynQuantity a
    y = (DynamicDimension -> DynamicDimension -> DynamicDimension)
    -> (a -> a -> a) -> DynQuantity a -> DynQuantity a -> DynQuantity a
    forall a.
    (DynamicDimension -> DynamicDimension -> DynamicDimension)
    -> (a -> a -> a) -> DynQuantity a -> DynQuantity a -> DynQuantity a
    liftDQ2 DynamicDimension -> DynamicDimension -> DynamicDimension
    matchDimensions a -> a -> a
    forall a. Num a => a -> a -> a
    (P.-) DynQuantity a
    x DynQuantity a
    y
      DynQuantity a
    x * :: DynQuantity a -> DynQuantity a -> DynQuantity a
    * DynQuantity a
    y = (DynamicDimension -> DynamicDimension -> DynamicDimension)
    -> (a -> a -> a) -> DynQuantity a -> DynQuantity a -> DynQuantity a
    forall a.
    (DynamicDimension -> DynamicDimension -> DynamicDimension)
    -> (a -> a -> a) -> DynQuantity a -> DynQuantity a -> DynQuantity a
    liftDQ2 ((Dimension' -> Dimension' -> Dimension')
    -> DynamicDimension -> DynamicDimension -> DynamicDimension
    valid2 Dimension' -> Dimension' -> Dimension'
    (D.*)) a -> a -> a
    forall a. Num a => a -> a -> a
    (P.*) DynQuantity a
    x DynQuantity a
    y
      negate :: DynQuantity a -> DynQuantity a
    negate = (DynamicDimension -> DynamicDimension)
    -> (a -> a) -> DynQuantity a -> DynQuantity a
    forall a.
    (DynamicDimension -> DynamicDimension)
    -> (a -> a) -> DynQuantity a -> DynQuantity a
    liftDQ DynamicDimension -> DynamicDimension
    forall a. a -> a
    id a -> a
    forall a. Num a => a -> a
    P.negate
      abs :: DynQuantity a -> DynQuantity a
    abs = (DynamicDimension -> DynamicDimension)
    -> (a -> a) -> DynQuantity a -> DynQuantity a
    forall a.
    (DynamicDimension -> DynamicDimension)
    -> (a -> a) -> DynQuantity a -> DynQuantity a
    liftDQ DynamicDimension -> DynamicDimension
    forall a. a -> a
    id a -> a
    forall a. Num a => a -> a
    P.abs
      signum :: DynQuantity a -> DynQuantity a
    signum = (DynamicDimension -> DynamicDimension)
    -> (a -> a) -> DynQuantity a -> DynQuantity a
    forall a.
    (DynamicDimension -> DynamicDimension)
    -> (a -> a) -> DynQuantity a -> DynQuantity a
    liftDQ (Dimension' -> DynamicDimension -> DynamicDimension
    constant Dimension'
    D.dOne) a -> a
    forall a. Num a => a -> a
    P.signum
      fromInteger :: Integer -> DynQuantity a
    fromInteger = Dimensional ('DQuantity One) DOne a -> DynQuantity a
    forall (q :: Type -> Type) (d :: Type -> Type) a.
    (Demotable q, Promotable d) =>
    q a -> d a
    demoteQuantity (Dimensional ('DQuantity One) DOne a -> DynQuantity a)
    -> (Integer -> Dimensional ('DQuantity One) DOne a)
    -> Integer
    -> DynQuantity a
    forall b c a. (b -> c) -> (a -> b) -> a -> c
    . (a -> Unit 'NonMetric DOne a -> Dimensional ('DQuantity One) DOne a
    forall a (m :: Metricality) (d :: Dimension).
    Num a =>
    a -> Unit m d a -> Quantity d a
    Dim.*~ Unit 'NonMetric DOne a
    forall a. Num a => Unit 'NonMetric DOne a
    one) (a -> Dimensional ('DQuantity One) DOne a)
    -> (Integer -> a) -> Integer -> Dimensional ('DQuantity One) DOne a
    forall b c a. (b -> c) -> (a -> b) -> a -> c
    . Integer -> a
    forall a. Num a => Integer -> a
    P.fromInteger

    instance Fractional a => Fractional (DynQuantity a) where
      DynQuantity a
    x / :: DynQuantity a -> DynQuantity a -> DynQuantity a
    / DynQuantity a
    y = (DynamicDimension -> DynamicDimension -> DynamicDimension)
    -> (a -> a -> a) -> DynQuantity a -> DynQuantity a -> DynQuantity a
    forall a.
    (DynamicDimension -> DynamicDimension -> DynamicDimension)
    -> (a -> a -> a) -> DynQuantity a -> DynQuantity a -> DynQuantity a
    liftDQ2 ((Dimension' -> Dimension' -> Dimension')
    -> DynamicDimension -> DynamicDimension -> DynamicDimension
    valid2 Dimension' -> Dimension' -> Dimension'
    (D./)) a -> a -> a
    forall a. Fractional a => a -> a -> a
    (P./) DynQuantity a
    x DynQuantity a
    y
      recip :: DynQuantity a -> DynQuantity a
    recip = (DynamicDimension -> DynamicDimension)
    -> (a -> a) -> DynQuantity a -> DynQuantity a
    forall a.
    (DynamicDimension -> DynamicDimension)
    -> (a -> a) -> DynQuantity a -> DynQuantity a
    liftDQ ((Dimension' -> Dimension') -> DynamicDimension -> DynamicDimension
    valid Dimension' -> Dimension'
    D.recip) a -> a
    forall a. Fractional a => a -> a
    P.recip
      fromRational :: Rational -> DynQuantity a
    fromRational = Dimensional ('DQuantity One) DOne a -> DynQuantity a
    forall (q :: Type -> Type) (d :: Type -> Type) a.
    (Demotable q, Promotable d) =>
    q a -> d a
    demoteQuantity (Dimensional ('DQuantity One) DOne a -> DynQuantity a)
    -> (Rational -> Dimensional ('DQuantity One) DOne a)
    -> Rational
    -> DynQuantity a
    forall b c a. (b -> c) -> (a -> b) -> a -> c
    . (a -> Unit 'NonMetric DOne a -> Dimensional ('DQuantity One) DOne a
    forall a (m :: Metricality) (d :: Dimension).
    Num a =>
    a -> Unit m d a -> Quantity d a
    Dim.*~ Unit 'NonMetric DOne a
    forall a. Num a => Unit 'NonMetric DOne a
    one) (a -> Dimensional ('DQuantity One) DOne a)
    -> (Rational -> a)
    -> Rational
    -> Dimensional ('DQuantity One) DOne a
    forall b c a. (b -> c) -> (a -> b) -> a -> c
    . Rational -> a
    forall a. Fractional a => Rational -> a
    P.fromRational

    instance Floating a => Floating (DynQuantity a) where
      pi :: DynQuantity a
    pi = Dimensional ('DQuantity One) DOne a -> DynQuantity a
    forall (q :: Type -> Type) (d :: Type -> Type) a.
    (Demotable q, Promotable d) =>
    q a -> d a
    demoteQuantity Dimensional ('DQuantity One) DOne a
    forall a. Floating a => Dimensionless a
    pi
      exp :: DynQuantity a -> DynQuantity a
    exp = (a -> a) -> DynQuantity a -> DynQuantity a
    forall a. (a -> a) -> DynQuantity a -> DynQuantity a
    liftDimensionless a -> a
    forall a. Floating a => a -> a
    P.exp
      log :: DynQuantity a -> DynQuantity a
    log = (a -> a) -> DynQuantity a -> DynQuantity a
    forall a. (a -> a) -> DynQuantity a -> DynQuantity a
    liftDimensionless a -> a
    forall a. Floating a => a -> a
    P.log
      sqrt :: DynQuantity a -> DynQuantity a
    sqrt = (DynamicDimension -> DynamicDimension)
    -> (a -> a) -> DynQuantity a -> DynQuantity a
    forall a.
    (DynamicDimension -> DynamicDimension)
    -> (a -> a) -> DynQuantity a -> DynQuantity a
    liftDQ ((Dimension' -> Maybe Dimension')
    -> DynamicDimension -> DynamicDimension
    whenValid ((Dimension' -> Maybe Dimension')
     -> DynamicDimension -> DynamicDimension)
    -> (Dimension' -> Maybe Dimension')
    -> DynamicDimension
    -> DynamicDimension
    forall a b. (a -> b) -> a -> b
    $ Int -> Dimension' -> Maybe Dimension'
    D.nroot Int
    2) a -> a
    forall a. Floating a => a -> a
    P.sqrt
      ** :: DynQuantity a -> DynQuantity a -> DynQuantity a
    (**) = (DynamicDimension -> DynamicDimension -> DynamicDimension)
    -> (a -> a -> a) -> DynQuantity a -> DynQuantity a -> DynQuantity a
    forall a.
    (DynamicDimension -> DynamicDimension -> DynamicDimension)
    -> (a -> a -> a) -> DynQuantity a -> DynQuantity a -> DynQuantity a
    liftDQ2 (DynamicDimension
    -> DynamicDimension -> DynamicDimension -> DynamicDimension
    matchDimensions3 (DynamicDimension
     -> DynamicDimension -> DynamicDimension -> DynamicDimension)
    -> DynamicDimension
    -> DynamicDimension
    -> DynamicDimension
    -> DynamicDimension
    forall a b. (a -> b) -> a -> b
    $ Dimension' -> DynamicDimension
    SomeDimension Dimension'
    D.dOne) a -> a -> a
    forall a. Floating a => a -> a -> a
    (P.**)
      logBase :: DynQuantity a -> DynQuantity a -> DynQuantity a
    logBase = (DynamicDimension -> DynamicDimension -> DynamicDimension)
    -> (a -> a -> a) -> DynQuantity a -> DynQuantity a -> DynQuantity a
    forall a.
    (DynamicDimension -> DynamicDimension -> DynamicDimension)
    -> (a -> a -> a) -> DynQuantity a -> DynQuantity a -> DynQuantity a
    liftDQ2 (DynamicDimension
    -> DynamicDimension -> DynamicDimension -> DynamicDimension
    matchDimensions3 (DynamicDimension
     -> DynamicDimension -> DynamicDimension -> DynamicDimension)
    -> DynamicDimension
    -> DynamicDimension
    -> DynamicDimension
    -> DynamicDimension
    forall a b. (a -> b) -> a -> b
    $ Dimension' -> DynamicDimension
    SomeDimension Dimension'
    D.dOne) a -> a -> a
    forall a. Floating a => a -> a -> a
    P.logBase
      sin :: DynQuantity a -> DynQuantity a
    sin = (a -> a) -> DynQuantity a -> DynQuantity a
    forall a. (a -> a) -> DynQuantity a -> DynQuantity a
    liftDimensionless a -> a
    forall a. Floating a => a -> a
    P.sin
      cos :: DynQuantity a -> DynQuantity a
    cos = (a -> a) -> DynQuantity a -> DynQuantity a
    forall a. (a -> a) -> DynQuantity a -> DynQuantity a
    liftDimensionless a -> a
    forall a. Floating a => a -> a
    P.cos
      tan :: DynQuantity a -> DynQuantity a
    tan = (a -> a) -> DynQuantity a -> DynQuantity a
    forall a. (a -> a) -> DynQuantity a -> DynQuantity a
    liftDimensionless a -> a
    forall a. Floating a => a -> a
    P.tan
      asin :: DynQuantity a -> DynQuantity a
    asin = (a -> a) -> DynQuantity a -> DynQuantity a
    forall a. (a -> a) -> DynQuantity a -> DynQuantity a
    liftDimensionless a -> a
    forall a. Floating a => a -> a
    P.asin
      acos :: DynQuantity a -> DynQuantity a
    acos = (a -> a) -> DynQuantity a -> DynQuantity a
    forall a. (a -> a) -> DynQuantity a -> DynQuantity a
    liftDimensionless a -> a
    forall a. Floating a => a -> a
    P.acos
      atan :: DynQuantity a -> DynQuantity a
    atan = (a -> a) -> DynQuantity a -> DynQuantity a
    forall a. (a -> a) -> DynQuantity a -> DynQuantity a
    liftDimensionless a -> a
    forall a. Floating a => a -> a
    P.atan
      sinh :: DynQuantity a -> DynQuantity a
    sinh = (a -> a) -> DynQuantity a -> DynQuantity a
    forall a. (a -> a) -> DynQuantity a -> DynQuantity a
    liftDimensionless a -> a
    forall a. Floating a => a -> a
    P.sinh
      cosh :: DynQuantity a -> DynQuantity a
    cosh = (a -> a) -> DynQuantity a -> DynQuantity a
    forall a. (a -> a) -> DynQuantity a -> DynQuantity a
    liftDimensionless a -> a
    forall a. Floating a => a -> a
    P.cosh
      tanh :: DynQuantity a -> DynQuantity a
    tanh = (a -> a) -> DynQuantity a -> DynQuantity a
    forall a. (a -> a) -> DynQuantity a -> DynQuantity a
    liftDimensionless a -> a
    forall a. Floating a => a -> a
    P.tanh
      asinh :: DynQuantity a -> DynQuantity a
    asinh = (a -> a) -> DynQuantity a -> DynQuantity a
    forall a. (a -> a) -> DynQuantity a -> DynQuantity a
    liftDimensionless a -> a
    forall a. Floating a => a -> a
    P.asinh
      acosh :: DynQuantity a -> DynQuantity a
    acosh = (a -> a) -> DynQuantity a -> DynQuantity a
    forall a. (a -> a) -> DynQuantity a -> DynQuantity a
    liftDimensionless a -> a
    forall a. Floating a => a -> a
    P.acosh
      atanh :: DynQuantity a -> DynQuantity a
    atanh = (a -> a) -> DynQuantity a -> DynQuantity a
    forall a. (a -> a) -> DynQuantity a -> DynQuantity a
    liftDimensionless a -> a
    forall a. Floating a => a -> a
    P.atanh

    -- | 'DynQuantity's form a 'Semigroup' under multiplication, but not under addition because
    -- they may not be added together if their dimensions do not match.
    instance Num a => Semigroup (DynQuantity a) where
        <> :: DynQuantity a -> DynQuantity a -> DynQuantity a
    (<>) = DynQuantity a -> DynQuantity a -> DynQuantity a
    forall a. Num a => a -> a -> a
    (P.*)

    -- | 'DynQuantity's form a 'Monoid' under multiplication, but not under addition because
    -- they may not be added together if their dimensions do not match.
    instance Num a => Monoid (DynQuantity a) where
      mempty :: DynQuantity a
    mempty = Dimensional ('DQuantity One) DOne a -> DynQuantity a
    forall (q :: Type -> Type) (d :: Type -> Type) a.
    (Demotable q, Promotable d) =>
    q a -> d a
    demoteQuantity (a
    1 a -> Unit 'NonMetric DOne a -> Dimensional ('DQuantity One) DOne a
    forall a (m :: Metricality) (d :: Dimension).
    Num a =>
    a -> Unit m d a -> Quantity d a
    Dim.*~ Unit 'NonMetric DOne a
    forall a. Num a => Unit 'NonMetric DOne a
    one)
      mappend :: DynQuantity a -> DynQuantity a -> DynQuantity a
    mappend = DynQuantity a -> DynQuantity a -> DynQuantity a
    forall a. Semigroup a => a -> a -> a
    (<>)

    #if USE_BINARY
    instance (Data.Binary.Binary a) => Data.Binary.Binary (DynQuantity a)
    #endif

    -- | A 'DynQuantity' which does not correspond to a value of any dimension.
    invalidQuantity :: DynQuantity a
    invalidQuantity :: forall a. DynQuantity a
    invalidQuantity = DynamicDimension -> a -> DynQuantity a
    forall a. DynamicDimension -> a -> DynQuantity a
    DynQuantity DynamicDimension
    NoDimension (a -> DynQuantity a) -> a -> DynQuantity a
    forall a b. (a -> b) -> a -> b
    $ String -> a
    forall a. HasCallStack => String -> a
    error String
    "Attempt to evaluate the value of an invalid quantity."

    -- | A 'DynQuantity' which corresponds to zero value of any dimension.
    --
    -- When combined through arithmetic with other 'DynQuantity's, inference is performed. For example,
    -- adding a length to polydimensional zero produces that length. Adding two polydimensional zeros produces another.
    -- Taking the sine of a polydimensional zero interprets it as a dimensionless zero and produces a dimensionless result.
    --
    -- Note that division by 'polydimensionalZero' produces a polydimensional result, which may be an error or some representation
    -- of infinity, as determined by the underlying arithmetic type. This behavior was chosen for consistency with the behavior of division
    -- by zero 'DynQuantity's of a specific dimension.
    polydimensionalZero :: (Num a) => DynQuantity a
    polydimensionalZero :: forall a. Num a => DynQuantity a
    polydimensionalZero = DynamicDimension -> a -> DynQuantity a
    forall a. DynamicDimension -> a -> DynQuantity a
    DynQuantity DynamicDimension
    AnyDimension a
    0

    -- | Lifts a function which is only valid on dimensionless quantities into a function on 'DynQuantity's.
    liftDimensionless :: (a -> a) -> DynQuantity a -> DynQuantity a
    liftDimensionless :: forall a. (a -> a) -> DynQuantity a -> DynQuantity a
    liftDimensionless = (DynamicDimension -> DynamicDimension)
    -> (a -> a) -> DynQuantity a -> DynQuantity a
    forall a.
    (DynamicDimension -> DynamicDimension)
    -> (a -> a) -> DynQuantity a -> DynQuantity a
    liftDQ (DynamicDimension -> DynamicDimension -> DynamicDimension
    matchDimensions (DynamicDimension -> DynamicDimension -> DynamicDimension)
    -> DynamicDimension -> DynamicDimension -> DynamicDimension
    forall a b. (a -> b) -> a -> b
    $ Dimension' -> DynamicDimension
    SomeDimension Dimension'
    D.dOne)

    -- | Lifts a function on values into a function on 'DynQuantity's.
    liftDQ :: (DynamicDimension -> DynamicDimension) -- ^ How the function operates on dimensions.
           -> (a -> a) -- ^ How the function operates on values.
           -> DynQuantity a -> DynQuantity a
    liftDQ :: forall a.
    (DynamicDimension -> DynamicDimension)
    -> (a -> a) -> DynQuantity a -> DynQuantity a
    liftDQ DynamicDimension -> DynamicDimension
    fd a -> a
    fv (DynQuantity DynamicDimension
    d a
    v) = case DynamicDimension -> DynamicDimension
    fd DynamicDimension
    d of
                                       DynamicDimension
    NoDimension -> DynQuantity a
    forall a. DynQuantity a
    invalidQuantity
                                       DynamicDimension
    d' -> DynamicDimension -> a -> DynQuantity a
    forall a. DynamicDimension -> a -> DynQuantity a
    DynQuantity DynamicDimension
    d' (a -> DynQuantity a) -> a -> DynQuantity a
    forall a b. (a -> b) -> a -> b
    $ a -> a
    fv a
    v

    -- | Lifts a function on values into a function on 'DynQuantity's.
    --
    -- This works by treating polydimensional zeros as dimensionless zeros. If that is not the desired behavior,
    -- handle polydimensional zeros first and then call this function.
    liftDQ2 :: (DynamicDimension -> DynamicDimension -> DynamicDimension)
            -> (a -> a -> a)
            -> DynQuantity a -> DynQuantity a -> DynQuantity a
    liftDQ2 :: forall a.
    (DynamicDimension -> DynamicDimension -> DynamicDimension)
    -> (a -> a -> a) -> DynQuantity a -> DynQuantity a -> DynQuantity a
    liftDQ2 DynamicDimension -> DynamicDimension -> DynamicDimension
    fd a -> a -> a
    fv (DynQuantity DynamicDimension
    d1 a
    v1) (DynQuantity DynamicDimension
    d2 a
    v2) = case DynamicDimension -> DynamicDimension -> DynamicDimension
    fd DynamicDimension
    d1 DynamicDimension
    d2 of
                                                              DynamicDimension
    NoDimension -> DynQuantity a
    forall a. DynQuantity a
    invalidQuantity
                                                              DynamicDimension
    d' -> DynamicDimension -> a -> DynQuantity a
    forall a. DynamicDimension -> a -> DynQuantity a
    DynQuantity DynamicDimension
    d' (a -> DynQuantity a) -> a -> DynQuantity a
    forall a b. (a -> b) -> a -> b
    $ a -> a -> a
    fv a
    v1 a
    v2

    -- | Transforms a dynamic dimension in a way which is always valid.
    valid :: (Dimension' -> Dimension') -> DynamicDimension -> DynamicDimension
    valid :: (Dimension' -> Dimension') -> DynamicDimension -> DynamicDimension
    valid Dimension' -> Dimension'
    _ DynamicDimension
    AnyDimension      = DynamicDimension
    AnyDimension
    valid Dimension' -> Dimension'
    f (SomeDimension Dimension'
    d) = Dimension' -> DynamicDimension
    SomeDimension (Dimension' -> Dimension'
    f Dimension'
    d)
    valid Dimension' -> Dimension'
    _ DynamicDimension
    NoDimension       = DynamicDimension
    NoDimension

    whenValid :: (Dimension' -> Maybe Dimension') -> DynamicDimension -> DynamicDimension
    whenValid :: (Dimension' -> Maybe Dimension')
    -> DynamicDimension -> DynamicDimension
    whenValid Dimension' -> Maybe Dimension'
    _ DynamicDimension
    AnyDimension = DynamicDimension
    AnyDimension
    whenValid Dimension' -> Maybe Dimension'
    f (SomeDimension Dimension'
    d) | Just Dimension'
    d' <- Dimension' -> Maybe Dimension'
    f Dimension'
    d = Dimension' -> DynamicDimension
    SomeDimension Dimension'
    d'
    whenValid Dimension' -> Maybe Dimension'
    _ DynamicDimension
    _ = DynamicDimension
    NoDimension

    constant :: Dimension' -> DynamicDimension -> DynamicDimension
    constant :: Dimension' -> DynamicDimension -> DynamicDimension
    constant Dimension'
    d DynamicDimension
    AnyDimension = Dimension' -> DynamicDimension
    SomeDimension Dimension'
    d
    constant Dimension'
    d (SomeDimension Dimension'
    _) = Dimension' -> DynamicDimension
    SomeDimension Dimension'
    d
    constant Dimension'
    _ DynamicDimension
    _ = DynamicDimension
    NoDimension

    -- | Transforms two dynamic dimensions in a way which is always valid.
    valid2 :: (Dimension' -> Dimension' -> Dimension') -> DynamicDimension -> DynamicDimension -> DynamicDimension
    valid2 :: (Dimension' -> Dimension' -> Dimension')
    -> DynamicDimension -> DynamicDimension -> DynamicDimension
    valid2 Dimension' -> Dimension' -> Dimension'
    _ DynamicDimension
    AnyDimension       (SomeDimension Dimension'
    _)  = DynamicDimension
    AnyDimension
    valid2 Dimension' -> Dimension' -> Dimension'
    _ (SomeDimension Dimension'
    _)  DynamicDimension
    AnyDimension       = DynamicDimension
    AnyDimension
    valid2 Dimension' -> Dimension' -> Dimension'
    _ DynamicDimension
    AnyDimension       DynamicDimension
    AnyDimension       = DynamicDimension
    AnyDimension
    valid2 Dimension' -> Dimension' -> Dimension'
    f (SomeDimension Dimension'
    d1) (SomeDimension Dimension'
    d2) = Dimension' -> DynamicDimension
    SomeDimension (Dimension' -> Dimension' -> Dimension'
    f Dimension'
    d1 Dimension'
    d2)
    valid2 Dimension' -> Dimension' -> Dimension'
    _ DynamicDimension
    _                  DynamicDimension
    _                  = DynamicDimension
    NoDimension

    matchDimensions3 :: DynamicDimension -> DynamicDimension -> DynamicDimension -> DynamicDimension
    matchDimensions3 :: DynamicDimension
    -> DynamicDimension -> DynamicDimension -> DynamicDimension
    matchDimensions3 DynamicDimension
    x DynamicDimension
    y DynamicDimension
    z = DynamicDimension -> DynamicDimension -> DynamicDimension
    matchDimensions DynamicDimension
    x (DynamicDimension -> DynamicDimension -> DynamicDimension
    matchDimensions DynamicDimension
    y DynamicDimension
    z)

    -- | A 'Unit' whose 'Dimension' is only known dynamically.
    data AnyUnit = AnyUnit Dimension' (UnitName 'NonMetric) ExactPi
      deriving ((forall x. AnyUnit -> Rep AnyUnit x)
    -> (forall x. Rep AnyUnit x -> AnyUnit) -> Generic AnyUnit
    forall x. Rep AnyUnit x -> AnyUnit
    forall x. AnyUnit -> Rep AnyUnit x
    forall a.
    (forall x. a -> Rep a x) -> (forall x. Rep a x -> a) -> Generic a
    $cfrom :: forall x. AnyUnit -> Rep AnyUnit x
    from :: forall x. AnyUnit -> Rep AnyUnit x
    $cto :: forall x. Rep AnyUnit x -> AnyUnit
    to :: forall x. Rep AnyUnit x -> AnyUnit
    Generic, Typeable)

    instance Show AnyUnit where
      show :: AnyUnit -> String
    show (AnyUnit Dimension'
    _ UnitName 'NonMetric
    n ExactPi
    e) = UnitName 'NonMetric -> String
    forall a. Show a => a -> String
    show UnitName 'NonMetric
    n String -> ShowS
    forall a. [a] -> [a] -> [a]
    ++ String
    " =def= " String -> ShowS
    forall a. [a] -> [a] -> [a]
    ++ ExactPi -> String
    forall a. Show a => a -> String
    show ExactPi
    e String -> ShowS
    forall a. [a] -> [a] -> [a]
    ++ String
    " of the SI base unit"

    instance HasDynamicDimension AnyUnit where

    instance HasDimension AnyUnit where
      dimension :: AnyUnit -> Dimension'
    dimension (AnyUnit Dimension'
    d UnitName 'NonMetric
    _ ExactPi
    _) = Dimension'
    d

    instance I.HasInterchangeName AnyUnit where
      interchangeName :: AnyUnit -> InterchangeName
    interchangeName (AnyUnit Dimension'
    _ UnitName 'NonMetric
    n ExactPi
    _) = UnitName 'NonMetric -> InterchangeName
    forall a. HasInterchangeName a => a -> InterchangeName
    I.interchangeName UnitName 'NonMetric
    n

    -- | 'AnyUnit's form a 'Semigroup' under multiplication.
    instance Semigroup AnyUnit where
      <> :: AnyUnit -> AnyUnit -> AnyUnit
    (<>) = AnyUnit -> AnyUnit -> AnyUnit
    (Numeric.Units.Dimensional.Dynamic.*)

    -- | 'AnyUnit's form a 'Monoid' under multiplication.
    instance Monoid AnyUnit where
      mempty :: AnyUnit
    mempty = Unit 'NonMetric DOne ExactPi -> AnyUnit
    forall (d :: Dimension) (m :: Metricality).
    KnownDimension d =>
    Unit m d ExactPi -> AnyUnit
    demoteUnit' Unit 'NonMetric DOne ExactPi
    forall a. Num a => Unit 'NonMetric DOne a
    one
      mappend :: AnyUnit -> AnyUnit -> AnyUnit
    mappend = AnyUnit -> AnyUnit -> AnyUnit
    forall a. Semigroup a => a -> a -> a
    (<>)

    -- | Extracts the 'UnitName' of an 'AnyUnit'.
    anyUnitName :: AnyUnit -> UnitName 'NonMetric
    anyUnitName :: AnyUnit -> UnitName 'NonMetric
    anyUnitName (AnyUnit Dimension'
    _ UnitName 'NonMetric
    n ExactPi
    _) = UnitName 'NonMetric
    n

    -- | The dynamic SI coherent unit of a given dimension.
    siUnit :: Dimension' -> AnyUnit
    siUnit :: Dimension' -> AnyUnit
    siUnit Dimension'
    d = Dimension' -> UnitName 'NonMetric -> ExactPi -> AnyUnit
    AnyUnit Dimension'
    d (Dimension' -> UnitName 'NonMetric
    baseUnitName Dimension'
    d) ExactPi
    1

    -- | Converts a 'Unit' of statically known 'Dimension' into an 'AnyUnit'.
    demoteUnit :: forall m d a.(KnownDimension d) => Unit m d a -> AnyUnit
    demoteUnit :: forall (m :: Metricality) (d :: Dimension) a.
    KnownDimension d =>
    Unit m d a -> AnyUnit
    demoteUnit Unit m d a
    u = Dimension' -> UnitName 'NonMetric -> ExactPi -> AnyUnit
    AnyUnit Dimension'
    dim (Unit 'NonMetric d a -> UnitName 'NonMetric
    forall (m :: Metricality) (d :: Dimension) a.
    Unit m d a -> UnitName m
    name (Unit 'NonMetric d a -> UnitName 'NonMetric)
    -> Unit 'NonMetric d a -> UnitName 'NonMetric
    forall a b. (a -> b) -> a -> b
    $ Unit m d a -> Unit 'NonMetric d a
    forall (m :: Metricality) (d :: Dimension) a.
    Unit m d a -> Unit 'NonMetric d a
    weaken Unit m d a
    u) (Unit m d a -> ExactPi
    forall (m :: Metricality) (d :: Dimension) a. Unit m d a -> ExactPi
    exactValue Unit m d a
    u)
      where
        dim :: Dimension'
    dim = Proxy d -> Dimension'
    forall a. HasDimension a => a -> Dimension'
    dimension (Proxy d
    forall {k} (t :: k). Proxy t
    Proxy :: Proxy d)

    -- | Converts a 'Unit' of statically known 'Dimension' into an 'AnyUnit'.
    --
    -- This is the same as the more general 'demoteUnit' but is useful in certain circumstances to avoid
    -- needlessly introducing an ambiguous type variable.
    demoteUnit' :: (KnownDimension d) => Unit m d ExactPi -> AnyUnit
    demoteUnit' :: forall (d :: Dimension) (m :: Metricality).
    KnownDimension d =>
    Unit m d ExactPi -> AnyUnit
    demoteUnit' = Unit m d ExactPi -> AnyUnit
    forall (m :: Metricality) (d :: Dimension) a.
    KnownDimension d =>
    Unit m d a -> AnyUnit
    demoteUnit

    -- | Converts an 'AnyUnit' into a 'Unit' of statically known 'Dimension', or 'Nothing' if the dimension does not match.
    --
    -- The result is represented in 'ExactPi', conversion to other representations is possible using 'changeRepApproximate'.
    --
    -- The result is always tagged as 'NonMetric', conversion to a 'Metric' unit can be attempted using 'strengthen'.
    promoteUnit :: forall d.(KnownDimension d) => AnyUnit -> Maybe (Unit 'NonMetric d ExactPi)
    promoteUnit :: forall (d :: Dimension).
    KnownDimension d =>
    AnyUnit -> Maybe (Unit 'NonMetric d ExactPi)
    promoteUnit (AnyUnit Dimension'
    dim UnitName 'NonMetric
    n ExactPi
    e) | Dimension'
    dim Dimension' -> Dimension' -> Bool
    forall a. Eq a => a -> a -> Bool
    == Dimension'
    dim' = Unit 'NonMetric d ExactPi -> Maybe (Unit 'NonMetric d ExactPi)
    forall a. a -> Maybe a
    Just (Unit 'NonMetric d ExactPi -> Maybe (Unit 'NonMetric d ExactPi))
    -> Unit 'NonMetric d ExactPi -> Maybe (Unit 'NonMetric d ExactPi)
    forall a b. (a -> b) -> a -> b
    $ UnitName 'NonMetric
    -> ExactPi
    -> Unit 'NonMetric d ExactPi
    -> Unit 'NonMetric d ExactPi
    forall a (m :: Metricality) (m1 :: Metricality) (d :: Dimension).
    Floating a =>
    UnitName m -> ExactPi -> Unit m1 d a -> Unit m d a
    mkUnitR UnitName 'NonMetric
    n ExactPi
    e Unit 'NonMetric d ExactPi
    forall (d :: Dimension) a.
    (KnownDimension d, Num a) =>
    Unit 'NonMetric d a
    Dim.siUnit
                                  | Bool
    otherwise   = Maybe (Unit 'NonMetric d ExactPi)
    forall a. Maybe a
    Nothing
      where
        dim' :: Dimension'
    dim' = Proxy d -> Dimension'
    forall a. HasDimension a => a -> Dimension'
    dimension (Proxy d
    forall {k} (t :: k). Proxy t
    Proxy :: Proxy d)

    -- | Forms the reciprocal of a dynamic unit.
    recip :: AnyUnit -> AnyUnit
    recip :: AnyUnit -> AnyUnit
    recip (AnyUnit Dimension'
    d UnitName 'NonMetric
    n ExactPi
    e) = Dimension' -> UnitName 'NonMetric -> ExactPi -> AnyUnit
    AnyUnit (Dimension' -> Dimension'
    D.recip Dimension'
    d) (UnitName 'NonMetric
    N.nOne UnitName 'NonMetric -> UnitName 'NonMetric -> UnitName 'NonMetric
    forall (m1 :: Metricality) (m2 :: Metricality).
    UnitName m1 -> UnitName m2 -> UnitName 'NonMetric
    N./ UnitName 'NonMetric
    n) (ExactPi -> ExactPi
    forall a. Fractional a => a -> a
    P.recip ExactPi
    e)

    -- | Forms the product of two dynamic units.
    (*) :: AnyUnit -> AnyUnit -> AnyUnit
    (AnyUnit Dimension'
    d1 UnitName 'NonMetric
    n1 ExactPi
    e1) * :: AnyUnit -> AnyUnit -> AnyUnit
    * (AnyUnit Dimension'
    d2 UnitName 'NonMetric
    n2 ExactPi
    e2) = Dimension' -> UnitName 'NonMetric -> ExactPi -> AnyUnit
    AnyUnit (Dimension'
    d1 Dimension' -> Dimension' -> Dimension'
    D.* Dimension'
    d2) (UnitName 'NonMetric
    n1 UnitName 'NonMetric -> UnitName 'NonMetric -> UnitName 'NonMetric
    forall (m1 :: Metricality) (m2 :: Metricality).
    UnitName m1 -> UnitName m2 -> UnitName 'NonMetric
    N.* UnitName 'NonMetric
    n2) (ExactPi
    e1 ExactPi -> ExactPi -> ExactPi
    forall a. Num a => a -> a -> a
    P.* ExactPi
    e2)

    -- | Forms the quotient of two dynamic units.
    (/) :: AnyUnit -> AnyUnit -> AnyUnit
    (AnyUnit Dimension'
    d1 UnitName 'NonMetric
    n1 ExactPi
    e1) / :: AnyUnit -> AnyUnit -> AnyUnit
    / (AnyUnit Dimension'
    d2 UnitName 'NonMetric
    n2 ExactPi
    e2) = Dimension' -> UnitName 'NonMetric -> ExactPi -> AnyUnit
    AnyUnit (Dimension'
    d1 Dimension' -> Dimension' -> Dimension'
    D./ Dimension'
    d2) (UnitName 'NonMetric
    n1 UnitName 'NonMetric -> UnitName 'NonMetric -> UnitName 'NonMetric
    forall (m1 :: Metricality) (m2 :: Metricality).
    UnitName m1 -> UnitName m2 -> UnitName 'NonMetric
    N./ UnitName 'NonMetric
    n2) (ExactPi
    e1 ExactPi -> ExactPi -> ExactPi
    forall a. Fractional a => a -> a -> a
    P./ ExactPi
    e2)

    -- | Raises a dynamic unit to an integer power.
    (^) :: (P.Integral a) => AnyUnit -> a -> AnyUnit
    (AnyUnit Dimension'
    d UnitName 'NonMetric
    n ExactPi
    e) ^ :: forall a. Integral a => AnyUnit -> a -> AnyUnit
    ^ a
    x = Dimension' -> UnitName 'NonMetric -> ExactPi -> AnyUnit
    AnyUnit (Dimension'
    d Dimension' -> Int -> Dimension'
    D.^ a -> Int
    forall a b. (Integral a, Num b) => a -> b
    P.fromIntegral a
    x) (UnitName 'NonMetric
    n UnitName 'NonMetric -> Int -> UnitName 'NonMetric
    forall (m :: Metricality). UnitName m -> Int -> UnitName 'NonMetric
    N.^ a -> Int
    forall a b. (Integral a, Num b) => a -> b
    P.fromIntegral a
    x) (ExactPi
    e ExactPi -> a -> ExactPi
    forall a b. (Fractional a, Integral b) => a -> b -> a
    P.^^ a
    x)

    -- | Applies a prefix to a dynamic unit.
    -- Returns 'Nothing' if the 'Unit' was 'NonMetric' and thus could not accept a prefix.
    applyPrefix :: N.Prefix -> AnyUnit -> Maybe AnyUnit
    applyPrefix :: Prefix -> AnyUnit -> Maybe AnyUnit
    applyPrefix Prefix
    p (AnyUnit Dimension'
    d UnitName 'NonMetric
    n ExactPi
    e) = do
                                      n' <- UnitName 'NonMetric -> Maybe (UnitName 'Metric)
    forall (m :: Metricality). UnitName m -> Maybe (UnitName 'Metric)
    N.strengthen UnitName 'NonMetric
    n
                                      let n'' = Prefix -> UnitName 'Metric -> UnitName 'NonMetric
    N.applyPrefix Prefix
    p UnitName 'Metric
    n'
                                      let e' = (Rational -> ExactPi
    forall a. Fractional a => Rational -> a
    P.fromRational (Rational -> ExactPi) -> Rational -> ExactPi
    forall a b. (a -> b) -> a -> b
    $ Prefix -> Rational
    N.scaleFactor Prefix
    p) ExactPi -> ExactPi -> ExactPi
    forall a. Num a => a -> a -> a
    P.* ExactPi
    e
                                      return $ AnyUnit d n'' e'

    -- | Forms a dynamic quantity by multipliying a number and a dynamic unit.
    (*~) :: (Floating a, Promotable q) => a -> AnyUnit -> q a
    a
    x *~ :: forall a (q :: Type -> Type).
    (Floating a, Promotable q) =>
    a -> AnyUnit -> q a
    *~ (AnyUnit Dimension'
    d UnitName 'NonMetric
    _ ExactPi
    e) = AnyQuantity a -> q a
    forall a. AnyQuantity a -> q a
    forall (q :: Type -> Type) a. Promotable q => AnyQuantity a -> q a
    promotableIn (AnyQuantity a -> q a) -> AnyQuantity a -> q a
    forall a b. (a -> b) -> a -> b
    $ Dimension' -> a -> AnyQuantity a
    forall a. Dimension' -> a -> AnyQuantity a
    AnyQuantity Dimension'
    d (a
    x a -> a -> a
    forall a. Num a => a -> a -> a
    P.* ExactPi -> a
    forall a. Floating a => ExactPi -> a
    approximateValue ExactPi
    e)

    -- | Divides a dynamic quantity by a dynamic unit, obtaining the numerical value of the quantity
    -- expressed in that unit if they are of the same physical dimension, or 'Nothing' otherwise.
    (/~) :: (Floating a, Promotable q) => q a -> AnyUnit -> Maybe a
    q a
    x /~ :: forall a (q :: Type -> Type).
    (Floating a, Promotable q) =>
    q a -> AnyUnit -> Maybe a
    /~ (AnyUnit Dimension'
    d UnitName 'NonMetric
    _ ExactPi
    e) = case q a -> DynQuantity a
    forall a. q a -> DynQuantity a
    forall (q :: Type -> Type) a. Promotable q => q a -> DynQuantity a
    promotableOut q a
    x of
                             DynQuantity DynamicDimension
    d' a
    x' | DynamicDimension
    d' DynamicDimension -> Dimension' -> Bool
    forall a. HasDynamicDimension a => a -> Dimension' -> Bool
    `isCompatibleWith` Dimension'
    d -> a -> Maybe a
    forall a. a -> Maybe a
    Just (a -> Maybe a) -> a -> Maybe a
    forall a b. (a -> b) -> a -> b
    $ a
    x' a -> a -> a
    forall a. Fractional a => a -> a -> a
    P./ ExactPi -> a
    forall a. Floating a => ExactPi -> a
    approximateValue ExactPi
    e
                                               | Bool
    otherwise -> Maybe a
    forall a. Maybe a
    Nothing