    {-# LANGUAGE ConstraintKinds #-}
    {-# LANGUAGE DataKinds #-}
    {-# LANGUAGE FlexibleContexts #-}
    {-# LANGUAGE GADTs #-}
    {-# LANGUAGE RankNTypes #-}
    {-# LANGUAGE ScopedTypeVariables #-}
    {-# LANGUAGE TypeOperators #-}

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

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

    Defines types for manipulation of quantities with fixed point representations.
    -}
    module Numeric.Units.Dimensional.FixedPoint
    (
      -- * Types
      -- $types
      Dimensional,
      Unit, Quantity, SQuantity,
      Metricality(..),
      -- * Physical Dimensions
      Dimension (Dim),
      -- ** Dimension Arithmetic
      type (*), type (/), type (^), NRoot, Recip,
      -- ** Term Level Representation of Dimensions
      Dimension' (Dim'), HasDimension(..), KnownDimension,
      -- * Dimensional Arithmetic
      (*~), (/~),
      (*), (/), (+), (-),
      negate, abs,
      -- ** Transcendental Functions
      -- *** Via 'Double'
      expD, logD, sinD, cosD, tanD, asinD, acosD, atanD, sinhD, coshD, tanhD, asinhD, acoshD, atanhD, atan2D,
      -- *** Via arbitary 'Floating' type
      expVia, logVia, sinVia, cosVia, tanVia, asinVia, acosVia, atanVia, sinhVia, coshVia, tanhVia, asinhVia, acoshVia, atanhVia, atan2Via,
      -- ** Operations on Collections
      (*~~), (/~~), sum, mean, -- dimensionlessLength, nFromTo,
      -- ** Conversion Between Representations
      rescale, rescaleFinite, rescaleD, rescaleVia, KnownVariant(dmap), changeRep, changeRepRound, changeRepApproximate,
      -- * Dimension Synonyms
      DOne, DLength, DMass, DTime, DElectricCurrent, DThermodynamicTemperature, DAmountOfSubstance, DLuminousIntensity,
      -- * Quantity Synonyms
      Dimensionless, Length, Mass, Time, ElectricCurrent, ThermodynamicTemperature, AmountOfSubstance, LuminousIntensity,
      -- * Constants
      _0, epsilon,
      -- $possibly-imprecise-constants
      _1, _2, _3, _4, _5, _6, _7, _8, _9, pi, tau,
      -- * Constructing Units
      siUnit, one, mkUnitR, mkUnitQ, mkUnitZ,
      -- * Unit Metadata
      name, exactValue, weaken, strengthen, exactify,
      -- * Commonly Used Type Synonyms
      -- $synonyms
      type Q, type QScale, type Angle8, type Angle16, type Angle32
    )
    where

    import Data.Bits
    import Data.ExactPi
    import qualified Data.ExactPi.TypeLevel as E
    import Data.Int
    import Data.Proxy
    import qualified Data.Foldable as F
    import Data.Ratio
    import qualified GHC.TypeLits as N
    import Numeric.Units.Dimensional.Coercion
    import Numeric.Units.Dimensional.Internal
    import Numeric.Units.Dimensional.Prelude hiding ((*~), (/~), (+), (-), recip, negate, abs, (*~~), (/~~), sum, mean, _0, _1, _2, _3, _4, _5, _6, _7, _8, _9, pi, tau, changeRep)
    import Numeric.Units.Dimensional.Variants hiding (type (*), type (/))
    import qualified Numeric.Units.Dimensional.UnitNames as Name
    import qualified Prelude as P

    {- $types

    We provide access to the same 'Dimensional', 'Unit', and 'Quantity' types as are exposed by "Numeric.Units.Dimensional", but additionally
    offer the 'SQuantity' type to represent scaled quantities. Fixed-point quantities are quantities backed by integers, it is frequently
    necessary to scale those integers into a range appropriate for the physical problem at hand.

    -}

    {-

    Arithmetic Operators and Functions

    We will reuse the operators and function names from the Prelude.
    To prevent unpleasant surprises we give operators the same fixity
    as the Prelude.

    -}

    --infixr 8  ^, ^/, **
    infixl 6  +, -

    -- | Adds two possibly scaled 'SQuantity's, preserving any scale factor.
    --
    -- Use in conjunction with 'changeRepRound' to combine quantities with differing scale factors.
    (+) :: (Num a) => SQuantity s d a -> SQuantity s d a -> SQuantity s d a
    + :: forall a (s :: ExactPi') (d :: Dimension).
    Num a =>
    SQuantity s d a -> SQuantity s d a -> SQuantity s d a
    (+) = (a -> a -> a)
    -> SQuantity s d a -> SQuantity s d a -> SQuantity s d a
    forall a (s1 :: ExactPi') (d1 :: Dimension) (s2 :: ExactPi')
           (d2 :: Dimension) (s3 :: ExactPi') (d3 :: Dimension).
    (a -> a -> a)
    -> SQuantity s1 d1 a -> SQuantity s2 d2 a -> SQuantity s3 d3 a
    liftQ2 a -> a -> a
    forall a. Num a => a -> a -> a
    (P.+)

    -- | Subtracts one possibly scaled 'SQuantity' from another, preserving any scale factor.
    --
    -- Use in conjunction with 'changeRepRound' to combine quantities with differing scale factors.
    (-) :: (Num a) => SQuantity s d a -> SQuantity s d a -> SQuantity s d a
    (-) = (a -> a -> a)
    -> SQuantity s d a -> SQuantity s d a -> SQuantity s d a
    forall a (s1 :: ExactPi') (d1 :: Dimension) (s2 :: ExactPi')
           (d2 :: Dimension) (s3 :: ExactPi') (d3 :: Dimension).
    (a -> a -> a)
    -> SQuantity s1 d1 a -> SQuantity s2 d2 a -> SQuantity s3 d3 a
    liftQ2 a -> a -> a
    forall a. Num a => a -> a -> a
    (P.-)

    -- | Takes the absolute value of a possibly scaled 'SQuantity', preserving any scale factor.
    abs :: (Num a) => SQuantity s d a -> SQuantity s d a
    abs :: forall a (s :: ExactPi') (d :: Dimension).
    Num a =>
    SQuantity s d a -> SQuantity s d a
    abs = (a -> a) -> SQuantity s d a -> SQuantity s d a
    forall a (s1 :: ExactPi') (d1 :: Dimension) (s2 :: ExactPi')
           (d2 :: Dimension).
    (a -> a) -> SQuantity s1 d1 a -> SQuantity s2 d2 a
    liftQ (a -> a
    forall a. Num a => a -> a
    P.abs)

    -- | Negates the value of a possibly scaled 'SQuantity', preserving any scale factor.
    negate :: (Num a) => SQuantity s d a -> SQuantity s d a
    negate :: forall a (s :: ExactPi') (d :: Dimension).
    Num a =>
    SQuantity s d a -> SQuantity s d a
    negate = (a -> a) -> SQuantity s d a -> SQuantity s d a
    forall a (s1 :: ExactPi') (d1 :: Dimension) (s2 :: ExactPi')
           (d2 :: Dimension).
    (a -> a) -> SQuantity s1 d1 a -> SQuantity s2 d2 a
    liftQ (a -> a
    forall a. Num a => a -> a
    P.negate)

    infixl 7  *~~, /~~

    -- | Applies '*~' to all values in a functor.
    (*~~) :: (Functor f, RealFrac a, Integral b, E.MinCtxt s a) => f a -> Unit m d a -> f (SQuantity s d b)
    f a
    xs *~~ :: forall (f :: Type -> Type) a b (s :: ExactPi') (m :: Metricality)
           (d :: Dimension).
    (Functor f, RealFrac a, Integral b, MinCtxt s a) =>
    f a -> Unit m d a -> f (SQuantity s d b)
    *~~ Unit m d a
    u = (a -> SQuantity s d b) -> f a -> f (SQuantity s d b)
    forall a b. (a -> b) -> f a -> f b
    forall (f :: Type -> Type) a b. Functor f => (a -> b) -> f a -> f b
    fmap (a -> Unit m d a -> SQuantity s d b
    forall (s :: ExactPi') (m :: Metricality) (d :: Dimension) a b.
    (RealFrac a, Integral b, MinCtxt s a) =>
    a -> Unit m d a -> SQuantity s d b
    *~ Unit m d a
    u) f a
    xs

    -- | Applies '/~' to all values in a functor.
    (/~~) :: (Functor f, Real a, Fractional b, E.MinCtxt s b) => f (SQuantity s d a) -> Unit m d b -> f b
    f (SQuantity s d a)
    xs /~~ :: forall (f :: Type -> Type) a b (s :: ExactPi') (d :: Dimension)
           (m :: Metricality).
    (Functor f, Real a, Fractional b, MinCtxt s b) =>
    f (SQuantity s d a) -> Unit m d b -> f b
    /~~ Unit m d b
    u = (SQuantity s d a -> b) -> f (SQuantity s d a) -> f b
    forall a b. (a -> b) -> f a -> f b
    forall (f :: Type -> Type) a b. Functor f => (a -> b) -> f a -> f b
    fmap (SQuantity s d a -> Unit m d b -> b
    forall (s :: ExactPi') (m :: Metricality) (d :: Dimension) a b.
    (Real a, Fractional b, MinCtxt s b) =>
    SQuantity s d a -> Unit m d b -> b
    /~ Unit m d b
    u) f (SQuantity s d a)
    xs

    -- | The sum of all elements in a list.
    sum :: (Num a, F.Foldable f) => f (SQuantity s d a) -> SQuantity s d a
    sum :: forall a (f :: Type -> Type) (s :: ExactPi') (d :: Dimension).
    (Num a, Foldable f) =>
    f (SQuantity s d a) -> SQuantity s d a
    sum = (SQuantity s d a -> SQuantity s d a -> SQuantity s d a)
    -> SQuantity s d a -> f (SQuantity s d a) -> SQuantity s d a
    forall a b. (a -> b -> b) -> b -> f a -> b
    forall (t :: Type -> Type) a b.
    Foldable t =>
    (a -> b -> b) -> b -> t a -> b
    F.foldr SQuantity s d a -> SQuantity s d a -> SQuantity s d a
    forall a (s :: ExactPi') (d :: Dimension).
    Num a =>
    SQuantity s d a -> SQuantity s d a -> SQuantity s d a
    (+) SQuantity s d a
    forall a (s :: ExactPi') (d :: Dimension). Num a => SQuantity s d a
    _0

    -- | The arithmetic mean of all elements in a list.
    mean :: (Fractional a, F.Foldable f) => f (SQuantity s d a) -> SQuantity s d a
    mean :: forall a (f :: Type -> Type) (s :: ExactPi') (d :: Dimension).
    (Fractional a, Foldable f) =>
    f (SQuantity s d a) -> SQuantity s d a
    mean = (SQuantity s d a, Int) -> SQuantity s d a
    forall {v :: Variant} {a2} {a} {d :: Dimension}.
    (KnownVariant v, Fractional a2, Integral a) =>
    (Dimensional v d a2, a) -> Dimensional v d a2
    reduce ((SQuantity s d a, Int) -> SQuantity s d a)
    -> (f (SQuantity s d a) -> (SQuantity s d a, Int))
    -> f (SQuantity s d a)
    -> SQuantity s d a
    forall b c a. (b -> c) -> (a -> b) -> a -> c
    forall {k} (cat :: k -> k -> Type) (b :: k) (c :: k) (a :: k).
    Category cat =>
    cat b c -> cat a b -> cat a c
    . (SQuantity s d a
     -> (SQuantity s d a, Int) -> (SQuantity s d a, Int))
    -> (SQuantity s d a, Int)
    -> f (SQuantity s d a)
    -> (SQuantity s d a, Int)
    forall a b. (a -> b -> b) -> b -> f a -> b
    forall (t :: Type -> Type) a b.
    Foldable t =>
    (a -> b -> b) -> b -> t a -> b
    F.foldr SQuantity s d a -> (SQuantity s d a, Int) -> (SQuantity s d a, Int)
    forall {a} {b} {s :: ExactPi'} {d :: Dimension}.
    (Num a, Num b) =>
    SQuantity s d a -> (SQuantity s d a, b) -> (SQuantity s d a, b)
    accumulate (SQuantity s d a
    forall a (s :: ExactPi') (d :: Dimension). Num a => SQuantity s d a
    _0, Int
    0 :: Int)
      where
        reduce :: (Dimensional v d a2, a) -> Dimensional v d a2
    reduce (Dimensional v d a2
    s, a
    n) = (a2 -> a2) -> Dimensional v d a2 -> Dimensional v d a2
    forall a1 a2 (d :: Dimension).
    (a1 -> a2) -> Dimensional v d a1 -> Dimensional v d a2
    forall (v :: Variant) a1 a2 (d :: Dimension).
    KnownVariant v =>
    (a1 -> a2) -> Dimensional v d a1 -> Dimensional v d a2
    dmap (a2 -> a2 -> a2
    forall a. Fractional a => a -> a -> a
    P./ a -> a2
    forall a b. (Integral a, Num b) => a -> b
    fromIntegral a
    n) Dimensional v d a2
    s
        accumulate :: SQuantity s d a -> (SQuantity s d a, b) -> (SQuantity s d a, b)
    accumulate SQuantity s d a
    val (SQuantity s d a
    accum, b
    count) = (SQuantity s d a
    accum SQuantity s d a -> SQuantity s d a -> SQuantity s d a
    forall a (s :: ExactPi') (d :: Dimension).
    Num a =>
    SQuantity s d a -> SQuantity s d a -> SQuantity s d a
    + SQuantity s d a
    val, b
    count b -> b -> b
    forall a. Num a => a -> a -> a
    P.+ b
    1)

    expD, logD, sinD, cosD, tanD, asinD, acosD, atanD, sinhD, coshD, tanhD, asinhD, acoshD, atanhD
      :: (Integral a, Integral b, E.MinCtxt s1 Double, E.MinCtxt s2 Double) => SQuantity s1 DOne a -> SQuantity s2 DOne b
    expD :: forall a b (s1 :: ExactPi') (s2 :: ExactPi').
    (Integral a, Integral b, MinCtxt s1 Double, MinCtxt s2 Double) =>
    SQuantity s1 DOne a -> SQuantity s2 DOne b
    expD = Proxy Double -> SQuantity s1 DOne a -> SQuantity s2 DOne b
    forall a b c (s1 :: ExactPi') (s2 :: ExactPi').
    (Integral a, RealFrac b, Floating b, Integral c, MinCtxt s1 b,
     MinCtxt s2 b) =>
    Proxy b -> SQuantity s1 DOne a -> SQuantity s2 DOne c
    expVia (Proxy Double
    forall {k} (t :: k). Proxy t
    Proxy :: Proxy P.Double)
    logD :: forall a b (s1 :: ExactPi') (s2 :: ExactPi').
    (Integral a, Integral b, MinCtxt s1 Double, MinCtxt s2 Double) =>
    SQuantity s1 DOne a -> SQuantity s2 DOne b
    logD = Proxy Double -> SQuantity s1 DOne a -> SQuantity s2 DOne b
    forall a b c (s1 :: ExactPi') (s2 :: ExactPi').
    (Integral a, RealFrac b, Floating b, Integral c, MinCtxt s1 b,
     MinCtxt s2 b) =>
    Proxy b -> SQuantity s1 DOne a -> SQuantity s2 DOne c
    logVia (Proxy Double
    forall {k} (t :: k). Proxy t
    Proxy :: Proxy P.Double)
    sinD :: forall a b (s1 :: ExactPi') (s2 :: ExactPi').
    (Integral a, Integral b, MinCtxt s1 Double, MinCtxt s2 Double) =>
    SQuantity s1 DOne a -> SQuantity s2 DOne b
    sinD = Proxy Double -> SQuantity s1 DOne a -> SQuantity s2 DOne b
    forall a b c (s1 :: ExactPi') (s2 :: ExactPi').
    (Integral a, RealFrac b, Floating b, Integral c, MinCtxt s1 b,
     MinCtxt s2 b) =>
    Proxy b -> SQuantity s1 DOne a -> SQuantity s2 DOne c
    sinVia (Proxy Double
    forall {k} (t :: k). Proxy t
    Proxy :: Proxy P.Double)
    cosD :: forall a b (s1 :: ExactPi') (s2 :: ExactPi').
    (Integral a, Integral b, MinCtxt s1 Double, MinCtxt s2 Double) =>
    SQuantity s1 DOne a -> SQuantity s2 DOne b
    cosD = Proxy Double -> SQuantity s1 DOne a -> SQuantity s2 DOne b
    forall a b c (s1 :: ExactPi') (s2 :: ExactPi').
    (Integral a, RealFrac b, Floating b, Integral c, MinCtxt s1 b,
     MinCtxt s2 b) =>
    Proxy b -> SQuantity s1 DOne a -> SQuantity s2 DOne c
    cosVia (Proxy Double
    forall {k} (t :: k). Proxy t
    Proxy :: Proxy P.Double)
    tanD :: forall a b (s1 :: ExactPi') (s2 :: ExactPi').
    (Integral a, Integral b, MinCtxt s1 Double, MinCtxt s2 Double) =>
    SQuantity s1 DOne a -> SQuantity s2 DOne b
    tanD = Proxy Double -> SQuantity s1 DOne a -> SQuantity s2 DOne b
    forall a b c (s1 :: ExactPi') (s2 :: ExactPi').
    (Integral a, RealFrac b, Floating b, Integral c, MinCtxt s1 b,
     MinCtxt s2 b) =>
    Proxy b -> SQuantity s1 DOne a -> SQuantity s2 DOne c
    tanVia (Proxy Double
    forall {k} (t :: k). Proxy t
    Proxy :: Proxy P.Double)
    asinD :: forall a b (s1 :: ExactPi') (s2 :: ExactPi').
    (Integral a, Integral b, MinCtxt s1 Double, MinCtxt s2 Double) =>
    SQuantity s1 DOne a -> SQuantity s2 DOne b
    asinD = Proxy Double -> SQuantity s1 DOne a -> SQuantity s2 DOne b
    forall a b c (s1 :: ExactPi') (s2 :: ExactPi').
    (Integral a, RealFrac b, Floating b, Integral c, MinCtxt s1 b,
     MinCtxt s2 b) =>
    Proxy b -> SQuantity s1 DOne a -> SQuantity s2 DOne c
    asinVia (Proxy Double
    forall {k} (t :: k). Proxy t
    Proxy :: Proxy P.Double)
    acosD :: forall a b (s1 :: ExactPi') (s2 :: ExactPi').
    (Integral a, Integral b, MinCtxt s1 Double, MinCtxt s2 Double) =>
    SQuantity s1 DOne a -> SQuantity s2 DOne b
    acosD = Proxy Double -> SQuantity s1 DOne a -> SQuantity s2 DOne b
    forall a b c (s1 :: ExactPi') (s2 :: ExactPi').
    (Integral a, RealFrac b, Floating b, Integral c, MinCtxt s1 b,
     MinCtxt s2 b) =>
    Proxy b -> SQuantity s1 DOne a -> SQuantity s2 DOne c
    acosVia (Proxy Double
    forall {k} (t :: k). Proxy t
    Proxy :: Proxy P.Double)
    atanD :: forall a b (s1 :: ExactPi') (s2 :: ExactPi').
    (Integral a, Integral b, MinCtxt s1 Double, MinCtxt s2 Double) =>
    SQuantity s1 DOne a -> SQuantity s2 DOne b
    atanD = Proxy Double -> SQuantity s1 DOne a -> SQuantity s2 DOne b
    forall a b c (s1 :: ExactPi') (s2 :: ExactPi').
    (Integral a, RealFrac b, Floating b, Integral c, MinCtxt s1 b,
     MinCtxt s2 b) =>
    Proxy b -> SQuantity s1 DOne a -> SQuantity s2 DOne c
    atanVia (Proxy Double
    forall {k} (t :: k). Proxy t
    Proxy :: Proxy P.Double)
    sinhD :: forall a b (s1 :: ExactPi') (s2 :: ExactPi').
    (Integral a, Integral b, MinCtxt s1 Double, MinCtxt s2 Double) =>
    SQuantity s1 DOne a -> SQuantity s2 DOne b
    sinhD = Proxy Double -> SQuantity s1 DOne a -> SQuantity s2 DOne b
    forall a b c (s1 :: ExactPi') (s2 :: ExactPi').
    (Integral a, RealFrac b, Floating b, Integral c, MinCtxt s1 b,
     MinCtxt s2 b) =>
    Proxy b -> SQuantity s1 DOne a -> SQuantity s2 DOne c
    sinhVia (Proxy Double
    forall {k} (t :: k). Proxy t
    Proxy :: Proxy P.Double)
    coshD :: forall a b (s1 :: ExactPi') (s2 :: ExactPi').
    (Integral a, Integral b, MinCtxt s1 Double, MinCtxt s2 Double) =>
    SQuantity s1 DOne a -> SQuantity s2 DOne b
    coshD = Proxy Double -> SQuantity s1 DOne a -> SQuantity s2 DOne b
    forall a b c (s1 :: ExactPi') (s2 :: ExactPi').
    (Integral a, RealFrac b, Floating b, Integral c, MinCtxt s1 b,
     MinCtxt s2 b) =>
    Proxy b -> SQuantity s1 DOne a -> SQuantity s2 DOne c
    coshVia (Proxy Double
    forall {k} (t :: k). Proxy t
    Proxy :: Proxy P.Double)
    tanhD :: forall a b (s1 :: ExactPi') (s2 :: ExactPi').
    (Integral a, Integral b, MinCtxt s1 Double, MinCtxt s2 Double) =>
    SQuantity s1 DOne a -> SQuantity s2 DOne b
    tanhD = Proxy Double -> SQuantity s1 DOne a -> SQuantity s2 DOne b
    forall a b c (s1 :: ExactPi') (s2 :: ExactPi').
    (Integral a, RealFrac b, Floating b, Integral c, MinCtxt s1 b,
     MinCtxt s2 b) =>
    Proxy b -> SQuantity s1 DOne a -> SQuantity s2 DOne c
    tanhVia (Proxy Double
    forall {k} (t :: k). Proxy t
    Proxy :: Proxy P.Double)
    asinhD :: forall a b (s1 :: ExactPi') (s2 :: ExactPi').
    (Integral a, Integral b, MinCtxt s1 Double, MinCtxt s2 Double) =>
    SQuantity s1 DOne a -> SQuantity s2 DOne b
    asinhD = Proxy Double -> SQuantity s1 DOne a -> SQuantity s2 DOne b
    forall a b c (s1 :: ExactPi') (s2 :: ExactPi').
    (Integral a, RealFrac b, Floating b, Integral c, MinCtxt s1 b,
     MinCtxt s2 b) =>
    Proxy b -> SQuantity s1 DOne a -> SQuantity s2 DOne c
    asinhVia (Proxy Double
    forall {k} (t :: k). Proxy t
    Proxy :: Proxy P.Double)
    acoshD :: forall a b (s1 :: ExactPi') (s2 :: ExactPi').
    (Integral a, Integral b, MinCtxt s1 Double, MinCtxt s2 Double) =>
    SQuantity s1 DOne a -> SQuantity s2 DOne b
    acoshD = Proxy Double -> SQuantity s1 DOne a -> SQuantity s2 DOne b
    forall a b c (s1 :: ExactPi') (s2 :: ExactPi').
    (Integral a, RealFrac b, Floating b, Integral c, MinCtxt s1 b,
     MinCtxt s2 b) =>
    Proxy b -> SQuantity s1 DOne a -> SQuantity s2 DOne c
    acoshVia (Proxy Double
    forall {k} (t :: k). Proxy t
    Proxy :: Proxy P.Double)
    atanhD :: forall a b (s1 :: ExactPi') (s2 :: ExactPi').
    (Integral a, Integral b, MinCtxt s1 Double, MinCtxt s2 Double) =>
    SQuantity s1 DOne a -> SQuantity s2 DOne b
    atanhD = Proxy Double -> SQuantity s1 DOne a -> SQuantity s2 DOne b
    forall a b c (s1 :: ExactPi') (s2 :: ExactPi').
    (Integral a, RealFrac b, Floating b, Integral c, MinCtxt s1 b,
     MinCtxt s2 b) =>
    Proxy b -> SQuantity s1 DOne a -> SQuantity s2 DOne c
    atanhVia (Proxy Double
    forall {k} (t :: k). Proxy t
    Proxy :: Proxy P.Double)

    -- | The standard two argument arctangent function.
    -- Since it interprets its two arguments in comparison with one another, the input may have any dimension.
    atan2D :: (Integral a, Integral b, E.MinCtxt s1 Double, E.MinCtxt s2 Double, E.MinCtxt s3 Double) => SQuantity s1 DOne a -> SQuantity s2 DOne a -> SQuantity s3 DOne b
    atan2D :: forall a b (s1 :: ExactPi') (s2 :: ExactPi') (s3 :: ExactPi').
    (Integral a, Integral b, MinCtxt s1 Double, MinCtxt s2 Double,
     MinCtxt s3 Double) =>
    SQuantity s1 DOne a -> SQuantity s2 DOne a -> SQuantity s3 DOne b
    atan2D = Proxy Double
    -> SQuantity s1 DOne a
    -> SQuantity s2 DOne a
    -> SQuantity s3 DOne b
    forall (s1 :: ExactPi') (s2 :: ExactPi') (s3 :: ExactPi') a b c
           (d :: Dimension).
    (Integral a, RealFloat b, Integral c, MinCtxt s1 b, MinCtxt s2 b,
     MinCtxt s3 b, KnownDimension d) =>
    Proxy b
    -> SQuantity s1 d a -> SQuantity s2 d a -> SQuantity s3 DOne c
    atan2Via (Proxy Double
    forall {k} (t :: k). Proxy t
    Proxy :: Proxy P.Double)

    expVia, logVia, sinVia, cosVia, tanVia, asinVia, acosVia, atanVia, sinhVia, coshVia, tanhVia, asinhVia, acoshVia, atanhVia
      :: (Integral a, RealFrac b, Floating b, Integral c, E.MinCtxt s1 b, E.MinCtxt s2 b) => Proxy b -> SQuantity s1 DOne a -> SQuantity s2 DOne c
    expVia :: forall a b c (s1 :: ExactPi') (s2 :: ExactPi').
    (Integral a, RealFrac b, Floating b, Integral c, MinCtxt s1 b,
     MinCtxt s2 b) =>
    Proxy b -> SQuantity s1 DOne a -> SQuantity s2 DOne c
    expVia = (b -> b) -> Proxy b -> SQuantity s1 DOne a -> SQuantity s2 DOne c
    forall (s1 :: ExactPi') (s2 :: ExactPi') a b c.
    (Real a, RealFrac b, Integral c, MinCtxt s1 b, MinCtxt s2 b) =>
    (b -> b) -> Proxy b -> SQuantity s1 DOne a -> SQuantity s2 DOne c
    liftDimensionlessVia b -> b
    forall a. Floating a => a -> a
    P.exp
    logVia :: forall a b c (s1 :: ExactPi') (s2 :: ExactPi').
    (Integral a, RealFrac b, Floating b, Integral c, MinCtxt s1 b,
     MinCtxt s2 b) =>
    Proxy b -> SQuantity s1 DOne a -> SQuantity s2 DOne c
    logVia = (b -> b) -> Proxy b -> SQuantity s1 DOne a -> SQuantity s2 DOne c
    forall (s1 :: ExactPi') (s2 :: ExactPi') a b c.
    (Real a, RealFrac b, Integral c, MinCtxt s1 b, MinCtxt s2 b) =>
    (b -> b) -> Proxy b -> SQuantity s1 DOne a -> SQuantity s2 DOne c
    liftDimensionlessVia b -> b
    forall a. Floating a => a -> a
    P.log
    sinVia :: forall a b c (s1 :: ExactPi') (s2 :: ExactPi').
    (Integral a, RealFrac b, Floating b, Integral c, MinCtxt s1 b,
     MinCtxt s2 b) =>
    Proxy b -> SQuantity s1 DOne a -> SQuantity s2 DOne c
    sinVia = ExactPi
    -> (forall a. Floating a => a -> a)
    -> Proxy b
    -> SQuantity s1 DOne a
    -> SQuantity s2 DOne c
    forall (s1 :: ExactPi') (s2 :: ExactPi') a b c.
    (Integral a, RealFrac b, Floating b, Integral c, MinCtxt s1 b,
     MinCtxt s2 b) =>
    ExactPi
    -> (forall a. Floating a => a -> a)
    -> Proxy b
    -> SQuantity s1 DOne a
    -> SQuantity s2 DOne c
    liftDimensionlessPeriodicVia (ExactPi
    2 ExactPi -> ExactPi -> ExactPi
    forall a. Num a => a -> a -> a
    P.* ExactPi
    forall a. Floating a => a
    P.pi) d -> d
    forall a. Floating a => a -> a
    P.sin
    cosVia :: forall a b c (s1 :: ExactPi') (s2 :: ExactPi').
    (Integral a, RealFrac b, Floating b, Integral c, MinCtxt s1 b,
     MinCtxt s2 b) =>
    Proxy b -> SQuantity s1 DOne a -> SQuantity s2 DOne c
    cosVia = ExactPi
    -> (forall a. Floating a => a -> a)
    -> Proxy b
    -> SQuantity s1 DOne a
    -> SQuantity s2 DOne c
    forall (s1 :: ExactPi') (s2 :: ExactPi') a b c.
    (Integral a, RealFrac b, Floating b, Integral c, MinCtxt s1 b,
     MinCtxt s2 b) =>
    ExactPi
    -> (forall a. Floating a => a -> a)
    -> Proxy b
    -> SQuantity s1 DOne a
    -> SQuantity s2 DOne c
    liftDimensionlessPeriodicVia (ExactPi
    2 ExactPi -> ExactPi -> ExactPi
    forall a. Num a => a -> a -> a
    P.* ExactPi
    forall a. Floating a => a
    P.pi) d -> d
    forall a. Floating a => a -> a
    P.cos
    tanVia :: forall a b c (s1 :: ExactPi') (s2 :: ExactPi').
    (Integral a, RealFrac b, Floating b, Integral c, MinCtxt s1 b,
     MinCtxt s2 b) =>
    Proxy b -> SQuantity s1 DOne a -> SQuantity s2 DOne c
    tanVia = ExactPi
    -> (forall a. Floating a => a -> a)
    -> Proxy b
    -> SQuantity s1 DOne a
    -> SQuantity s2 DOne c
    forall (s1 :: ExactPi') (s2 :: ExactPi') a b c.
    (Integral a, RealFrac b, Floating b, Integral c, MinCtxt s1 b,
     MinCtxt s2 b) =>
    ExactPi
    -> (forall a. Floating a => a -> a)
    -> Proxy b
    -> SQuantity s1 DOne a
    -> SQuantity s2 DOne c
    liftDimensionlessPeriodicVia ExactPi
    forall a. Floating a => a
    P.pi d -> d
    forall a. Floating a => a -> a
    P.tan
    asinVia :: forall a b c (s1 :: ExactPi') (s2 :: ExactPi').
    (Integral a, RealFrac b, Floating b, Integral c, MinCtxt s1 b,
     MinCtxt s2 b) =>
    Proxy b -> SQuantity s1 DOne a -> SQuantity s2 DOne c
    asinVia = (b -> b) -> Proxy b -> SQuantity s1 DOne a -> SQuantity s2 DOne c
    forall (s1 :: ExactPi') (s2 :: ExactPi') a b c.
    (Real a, RealFrac b, Integral c, MinCtxt s1 b, MinCtxt s2 b) =>
    (b -> b) -> Proxy b -> SQuantity s1 DOne a -> SQuantity s2 DOne c
    liftDimensionlessVia b -> b
    forall a. Floating a => a -> a
    P.asin
    acosVia :: forall a b c (s1 :: ExactPi') (s2 :: ExactPi').
    (Integral a, RealFrac b, Floating b, Integral c, MinCtxt s1 b,
     MinCtxt s2 b) =>
    Proxy b -> SQuantity s1 DOne a -> SQuantity s2 DOne c
    acosVia = (b -> b) -> Proxy b -> SQuantity s1 DOne a -> SQuantity s2 DOne c
    forall (s1 :: ExactPi') (s2 :: ExactPi') a b c.
    (Real a, RealFrac b, Integral c, MinCtxt s1 b, MinCtxt s2 b) =>
    (b -> b) -> Proxy b -> SQuantity s1 DOne a -> SQuantity s2 DOne c
    liftDimensionlessVia b -> b
    forall a. Floating a => a -> a
    P.acos
    atanVia :: forall a b c (s1 :: ExactPi') (s2 :: ExactPi').
    (Integral a, RealFrac b, Floating b, Integral c, MinCtxt s1 b,
     MinCtxt s2 b) =>
    Proxy b -> SQuantity s1 DOne a -> SQuantity s2 DOne c
    atanVia = (b -> b) -> Proxy b -> SQuantity s1 DOne a -> SQuantity s2 DOne c
    forall (s1 :: ExactPi') (s2 :: ExactPi') a b c.
    (Real a, RealFrac b, Integral c, MinCtxt s1 b, MinCtxt s2 b) =>
    (b -> b) -> Proxy b -> SQuantity s1 DOne a -> SQuantity s2 DOne c
    liftDimensionlessVia b -> b
    forall a. Floating a => a -> a
    P.atan
    sinhVia :: forall a b c (s1 :: ExactPi') (s2 :: ExactPi').
    (Integral a, RealFrac b, Floating b, Integral c, MinCtxt s1 b,
     MinCtxt s2 b) =>
    Proxy b -> SQuantity s1 DOne a -> SQuantity s2 DOne c
    sinhVia = ExactPi
    -> (forall a. Floating a => a -> a)
    -> Proxy b
    -> SQuantity s1 DOne a
    -> SQuantity s2 DOne c
    forall (s1 :: ExactPi') (s2 :: ExactPi') a b c.
    (Integral a, RealFrac b, Floating b, Integral c, MinCtxt s1 b,
     MinCtxt s2 b) =>
    ExactPi
    -> (forall a. Floating a => a -> a)
    -> Proxy b
    -> SQuantity s1 DOne a
    -> SQuantity s2 DOne c
    liftDimensionlessPeriodicVia (ExactPi
    2 ExactPi -> ExactPi -> ExactPi
    forall a. Num a => a -> a -> a
    P.* ExactPi
    forall a. Floating a => a
    P.pi) d -> d
    forall a. Floating a => a -> a
    P.sinh
    coshVia :: forall a b c (s1 :: ExactPi') (s2 :: ExactPi').
    (Integral a, RealFrac b, Floating b, Integral c, MinCtxt s1 b,
     MinCtxt s2 b) =>
    Proxy b -> SQuantity s1 DOne a -> SQuantity s2 DOne c
    coshVia = ExactPi
    -> (forall a. Floating a => a -> a)
    -> Proxy b
    -> SQuantity s1 DOne a
    -> SQuantity s2 DOne c
    forall (s1 :: ExactPi') (s2 :: ExactPi') a b c.
    (Integral a, RealFrac b, Floating b, Integral c, MinCtxt s1 b,
     MinCtxt s2 b) =>
    ExactPi
    -> (forall a. Floating a => a -> a)
    -> Proxy b
    -> SQuantity s1 DOne a
    -> SQuantity s2 DOne c
    liftDimensionlessPeriodicVia (ExactPi
    2 ExactPi -> ExactPi -> ExactPi
    forall a. Num a => a -> a -> a
    P.* ExactPi
    forall a. Floating a => a
    P.pi) d -> d
    forall a. Floating a => a -> a
    P.cosh
    tanhVia :: forall a b c (s1 :: ExactPi') (s2 :: ExactPi').
    (Integral a, RealFrac b, Floating b, Integral c, MinCtxt s1 b,
     MinCtxt s2 b) =>
    Proxy b -> SQuantity s1 DOne a -> SQuantity s2 DOne c
    tanhVia = ExactPi
    -> (forall a. Floating a => a -> a)
    -> Proxy b
    -> SQuantity s1 DOne a
    -> SQuantity s2 DOne c
    forall (s1 :: ExactPi') (s2 :: ExactPi') a b c.
    (Integral a, RealFrac b, Floating b, Integral c, MinCtxt s1 b,
     MinCtxt s2 b) =>
    ExactPi
    -> (forall a. Floating a => a -> a)
    -> Proxy b
    -> SQuantity s1 DOne a
    -> SQuantity s2 DOne c
    liftDimensionlessPeriodicVia ExactPi
    forall a. Floating a => a
    P.pi d -> d
    forall a. Floating a => a -> a
    P.tanh
    asinhVia :: forall a b c (s1 :: ExactPi') (s2 :: ExactPi').
    (Integral a, RealFrac b, Floating b, Integral c, MinCtxt s1 b,
     MinCtxt s2 b) =>
    Proxy b -> SQuantity s1 DOne a -> SQuantity s2 DOne c
    asinhVia = (b -> b) -> Proxy b -> SQuantity s1 DOne a -> SQuantity s2 DOne c
    forall (s1 :: ExactPi') (s2 :: ExactPi') a b c.
    (Real a, RealFrac b, Integral c, MinCtxt s1 b, MinCtxt s2 b) =>
    (b -> b) -> Proxy b -> SQuantity s1 DOne a -> SQuantity s2 DOne c
    liftDimensionlessVia b -> b
    forall a. Floating a => a -> a
    P.asinh
    acoshVia :: forall a b c (s1 :: ExactPi') (s2 :: ExactPi').
    (Integral a, RealFrac b, Floating b, Integral c, MinCtxt s1 b,
     MinCtxt s2 b) =>
    Proxy b -> SQuantity s1 DOne a -> SQuantity s2 DOne c
    acoshVia = (b -> b) -> Proxy b -> SQuantity s1 DOne a -> SQuantity s2 DOne c
    forall (s1 :: ExactPi') (s2 :: ExactPi') a b c.
    (Real a, RealFrac b, Integral c, MinCtxt s1 b, MinCtxt s2 b) =>
    (b -> b) -> Proxy b -> SQuantity s1 DOne a -> SQuantity s2 DOne c
    liftDimensionlessVia b -> b
    forall a. Floating a => a -> a
    P.acosh
    atanhVia :: forall a b c (s1 :: ExactPi') (s2 :: ExactPi').
    (Integral a, RealFrac b, Floating b, Integral c, MinCtxt s1 b,
     MinCtxt s2 b) =>
    Proxy b -> SQuantity s1 DOne a -> SQuantity s2 DOne c
    atanhVia = (b -> b) -> Proxy b -> SQuantity s1 DOne a -> SQuantity s2 DOne c
    forall (s1 :: ExactPi') (s2 :: ExactPi') a b c.
    (Real a, RealFrac b, Integral c, MinCtxt s1 b, MinCtxt s2 b) =>
    (b -> b) -> Proxy b -> SQuantity s1 DOne a -> SQuantity s2 DOne c
    liftDimensionlessVia b -> b
    forall a. Floating a => a -> a
    P.atanh

    -- | The standard two argument arctangent function.
    -- Since it interprets its two arguments in comparison with one another, the input may have any dimension.
    atan2Via :: forall s1 s2 s3 a b c d.(Integral a, RealFloat b, Integral c, E.MinCtxt s1 b, E.MinCtxt s2 b, E.MinCtxt s3 b, KnownDimension d) => Proxy b -> SQuantity s1 d a -> SQuantity s2 d a -> SQuantity s3 DOne c
    atan2Via :: forall (s1 :: ExactPi') (s2 :: ExactPi') (s3 :: ExactPi') a b c
           (d :: Dimension).
    (Integral a, RealFloat b, Integral c, MinCtxt s1 b, MinCtxt s2 b,
     MinCtxt s3 b, KnownDimension d) =>
    Proxy b
    -> SQuantity s1 d a -> SQuantity s2 d a -> SQuantity s3 DOne c
    atan2Via Proxy b
    _ SQuantity s1 d a
    y SQuantity s2 d a
    x = (b -> Unit 'NonMetric DOne b -> SQuantity s3 DOne c
    forall (s :: ExactPi') (m :: Metricality) (d :: Dimension) a b.
    (RealFrac a, Integral b, MinCtxt s a) =>
    a -> Unit m d a -> SQuantity s d b
    *~ Unit 'NonMetric DOne b
    forall (d :: Dimension) a.
    (KnownDimension d, Num a) =>
    Unit 'NonMetric d a
    siUnit) (b -> SQuantity s3 DOne c) -> b -> SQuantity s3 DOne c
    forall a b. (a -> b) -> a -> b
    $ (b -> b -> b
    forall a. RealFloat a => a -> a -> a
    P.atan2 :: b -> b -> b) (SQuantity s1 d a
    y SQuantity s1 d a -> Unit 'NonMetric d b -> b
    forall (s :: ExactPi') (m :: Metricality) (d :: Dimension) a b.
    (Real a, Fractional b, MinCtxt s b) =>
    SQuantity s d a -> Unit m d b -> b
    /~ Unit 'NonMetric d b
    forall (d :: Dimension) a.
    (KnownDimension d, Num a) =>
    Unit 'NonMetric d a
    siUnit) (SQuantity s2 d a
    x SQuantity s2 d a -> Unit 'NonMetric d b -> b
    forall (s :: ExactPi') (m :: Metricality) (d :: Dimension) a b.
    (Real a, Fractional b, MinCtxt s b) =>
    SQuantity s d a -> Unit m d b -> b
    /~ Unit 'NonMetric d b
    forall (d :: Dimension) a.
    (KnownDimension d, Num a) =>
    Unit 'NonMetric d a
    siUnit)

    -- | Lift a function on dimensionless values of a specified intermediate type to operate on possibly scaled dimensionless values.
    liftDimensionlessVia :: forall s1 s2 a b c.(Real a, RealFrac b, Integral c, E.MinCtxt s1 b, E.MinCtxt s2 b) => (b -> b) -> Proxy b -> SQuantity s1 DOne a -> SQuantity s2 DOne c
    liftDimensionlessVia :: forall (s1 :: ExactPi') (s2 :: ExactPi') a b c.
    (Real a, RealFrac b, Integral c, MinCtxt s1 b, MinCtxt s2 b) =>
    (b -> b) -> Proxy b -> SQuantity s1 DOne a -> SQuantity s2 DOne c
    liftDimensionlessVia b -> b
    f Proxy b
    _ = (b -> Unit 'NonMetric DOne b -> SQuantity s2 DOne c
    forall (s :: ExactPi') (m :: Metricality) (d :: Dimension) a b.
    (RealFrac a, Integral b, MinCtxt s a) =>
    a -> Unit m d a -> SQuantity s d b
    *~ Unit 'NonMetric DOne b
    forall (d :: Dimension) a.
    (KnownDimension d, Num a) =>
    Unit 'NonMetric d a
    siUnit) (b -> SQuantity s2 DOne c)
    -> (SQuantity s1 DOne a -> b)
    -> SQuantity s1 DOne a
    -> SQuantity s2 DOne c
    forall b c a. (b -> c) -> (a -> b) -> a -> c
    forall {k} (cat :: k -> k -> Type) (b :: k) (c :: k) (a :: k).
    Category cat =>
    cat b c -> cat a b -> cat a c
    . (b -> b
    f :: b -> b) (b -> b) -> (SQuantity s1 DOne a -> b) -> SQuantity s1 DOne a -> b
    forall b c a. (b -> c) -> (a -> b) -> a -> c
    forall {k} (cat :: k -> k -> Type) (b :: k) (c :: k) (a :: k).
    Category cat =>
    cat b c -> cat a b -> cat a c
    . (SQuantity s1 DOne a -> Unit 'NonMetric DOne b -> b
    forall (s :: ExactPi') (m :: Metricality) (d :: Dimension) a b.
    (Real a, Fractional b, MinCtxt s b) =>
    SQuantity s d a -> Unit m d b -> b
    /~ Unit 'NonMetric DOne b
    forall (d :: Dimension) a.
    (KnownDimension d, Num a) =>
    Unit 'NonMetric d a
    siUnit)

    -- | Lift a periodic function on dimensionless values of a specified intermediate type to operate on possibly scaled dimensionless values.
    --
    -- If the scale factor of the input type is an exact integer divisor of the function's period, the argument
    -- will be clamped via an integer `mod` operation prior to applying the function to avoid errors introduced by a floating point modulus.
    liftDimensionlessPeriodicVia :: forall s1 s2 a b c.(Integral a, RealFrac b, Floating b, Integral c, E.MinCtxt s1 b, E.MinCtxt s2 b) => ExactPi -> (forall d.Floating d => d -> d) -> Proxy b -> SQuantity s1 DOne a -> SQuantity s2 DOne c
    liftDimensionlessPeriodicVia :: forall (s1 :: ExactPi') (s2 :: ExactPi') a b c.
    (Integral a, RealFrac b, Floating b, Integral c, MinCtxt s1 b,
     MinCtxt s2 b) =>
    ExactPi
    -> (forall a. Floating a => a -> a)
    -> Proxy b
    -> SQuantity s1 DOne a
    -> SQuantity s2 DOne c
    liftDimensionlessPeriodicVia ExactPi
    p forall a. Floating a => a -> a
    f Proxy b
    proxy | Just a
    p'' <- Maybe a
    p', a
    p'' a -> a -> Bool
    forall a. Eq a => a -> a -> Bool
    /= a
    0 = ((b -> b) -> Proxy b -> SQuantity s1 DOne a -> SQuantity s2 DOne c
    forall (s1 :: ExactPi') (s2 :: ExactPi') a b c.
    (Real a, RealFrac b, Integral c, MinCtxt s1 b, MinCtxt s2 b) =>
    (b -> b) -> Proxy b -> SQuantity s1 DOne a -> SQuantity s2 DOne c
    liftDimensionlessVia b -> b
    forall a. Floating a => a -> a
    f Proxy b
    proxy) (SQuantity s1 DOne a -> SQuantity s2 DOne c)
    -> (SQuantity s1 DOne a -> SQuantity s1 DOne a)
    -> SQuantity s1 DOne a
    -> SQuantity s2 DOne c
    forall b c a. (b -> c) -> (a -> b) -> a -> c
    forall {k} (cat :: k -> k -> Type) (b :: k) (c :: k) (a :: k).
    Category cat =>
    cat b c -> cat a b -> cat a c
    . (a -> a) -> SQuantity s1 DOne a -> SQuantity s1 DOne a
    forall a1 a2 (d :: Dimension).
    (a1 -> a2)
    -> Dimensional ('DQuantity s1) d a1
    -> Dimensional ('DQuantity s1) d a2
    forall (v :: Variant) a1 a2 (d :: Dimension).
    KnownVariant v =>
    (a1 -> a2) -> Dimensional v d a1 -> Dimensional v d a2
    dmap (a -> a -> a
    forall a. Integral a => a -> a -> a
    `mod` a
    p'')
                                           | Bool
    otherwise = (b -> b) -> Proxy b -> SQuantity s1 DOne a -> SQuantity s2 DOne c
    forall (s1 :: ExactPi') (s2 :: ExactPi') a b c.
    (Real a, RealFrac b, Integral c, MinCtxt s1 b, MinCtxt s2 b) =>
    (b -> b) -> Proxy b -> SQuantity s1 DOne a -> SQuantity s2 DOne c
    liftDimensionlessVia b -> b
    forall a. Floating a => a -> a
    f Proxy b
    proxy
      where
        p' :: Maybe a
        p' :: Maybe a
    p' = (Integer -> a) -> Maybe Integer -> Maybe a
    forall a b. (a -> b) -> Maybe a -> Maybe b
    forall (f :: Type -> Type) a b. Functor f => (a -> b) -> f a -> f b
    fmap Integer -> a
    forall a. Num a => Integer -> a
    fromInteger (Maybe Integer -> Maybe a)
    -> (Proxy s1 -> Maybe Integer) -> Proxy s1 -> Maybe a
    forall b c a. (b -> c) -> (a -> b) -> a -> c
    forall {k} (cat :: k -> k -> Type) (b :: k) (c :: k) (a :: k).
    Category cat =>
    cat b c -> cat a b -> cat a c
    . ExactPi -> Maybe Integer
    toExactInteger (ExactPi -> Maybe Integer)
    -> (Proxy s1 -> ExactPi) -> Proxy s1 -> Maybe Integer
    forall b c a. (b -> c) -> (a -> b) -> a -> c
    forall {k} (cat :: k -> k -> Type) (b :: k) (c :: k) (a :: k).
    Category cat =>
    cat b c -> cat a b -> cat a c
    . ExactPi -> ExactPi
    forall a. Fractional a => a -> a
    P.recip (ExactPi -> ExactPi)
    -> (Proxy s1 -> ExactPi) -> Proxy s1 -> ExactPi
    forall b c a. (b -> c) -> (a -> b) -> a -> c
    forall {k} (cat :: k -> k -> Type) (b :: k) (c :: k) (a :: k).
    Category cat =>
    cat b c -> cat a b -> cat a c
    . (ExactPi -> ExactPi -> ExactPi
    forall a. Fractional a => a -> a -> a
    P./ ExactPi
    p) (ExactPi -> ExactPi)
    -> (Proxy s1 -> ExactPi) -> Proxy s1 -> ExactPi
    forall b c a. (b -> c) -> (a -> b) -> a -> c
    forall {k} (cat :: k -> k -> Type) (b :: k) (c :: k) (a :: k).
    Category cat =>
    cat b c -> cat a b -> cat a c
    . Proxy s1 -> ExactPi
    forall (v :: ExactPi'). KnownExactPi v => Proxy v -> ExactPi
    E.exactPiVal (Proxy s1 -> Maybe a) -> Proxy s1 -> Maybe a
    forall a b. (a -> b) -> a -> b
    $ (Proxy s1
    forall {k} (t :: k). Proxy t
    Proxy :: Proxy s1)

    {-
    We give '*~' and '/~' the same fixity as '*' and '/' defined below.
    Note that this necessitates the use of parenthesis when composing
    units using '*' and '/', e.g. "1 *~ (meter / second)".
    -}

    infixl 7  *~, /~

    -- | Forms a possibly scaled 'SQuantity' by multipliying a number and a unit.
    (*~) :: forall s m d a b.(RealFrac a, Integral b, E.MinCtxt s a) => a -> Unit m d a -> SQuantity s d b
    a
    x *~ :: forall (s :: ExactPi') (m :: Metricality) (d :: Dimension) a b.
    (RealFrac a, Integral b, MinCtxt s a) =>
    a -> Unit m d a -> SQuantity s d b
    *~ (Unit UnitName m
    _ ExactPi
    _ a
    y) = b -> Dimensional ('DQuantity s) d b
    forall (s :: ExactPi') (d :: Dimension) a.
    a -> Dimensional ('DQuantity s) d a
    Quantity (b -> Dimensional ('DQuantity s) d b)
    -> (a -> b) -> a -> Dimensional ('DQuantity s) d b
    forall b c a. (b -> c) -> (a -> b) -> a -> c
    forall {k} (cat :: k -> k -> Type) (b :: k) (c :: k) (a :: k).
    Category cat =>
    cat b c -> cat a b -> cat a c
    . a -> b
    forall b. Integral b => a -> b
    forall a b. (RealFrac a, Integral b) => a -> b
    round (a -> Dimensional ('DQuantity s) d b)
    -> a -> Dimensional ('DQuantity s) d b
    forall a b. (a -> b) -> a -> b
    $ (a
    x a -> a -> a
    forall a. Num a => a -> a -> a
    P.* a
    y a -> a -> a
    forall a. Fractional a => a -> a -> a
    P./ a
    s)
      where
        s :: a
    s = Proxy s -> a
    forall (v :: ExactPi') a. MinCtxt v a => Proxy v -> a
    E.injMin (Proxy s
    forall {k} (t :: k). Proxy t
    Proxy :: Proxy s)

    -- | Divides a possibly scaled 'SQuantity' by a 'Unit' of the same physical dimension, obtaining the
    -- numerical value of the quantity expressed in that unit.
    (/~) :: forall s m d a b.(Real a, Fractional b,  E.MinCtxt s b) => SQuantity s d a -> Unit m d b -> b
    (Quantity a
    x) /~ :: forall (s :: ExactPi') (m :: Metricality) (d :: Dimension) a b.
    (Real a, Fractional b, MinCtxt s b) =>
    SQuantity s d a -> Unit m d b -> b
    /~ (Unit UnitName m
    _ ExactPi
    _ b
    y) = ((a -> b
    forall a b. (Real a, Fractional b) => a -> b
    realToFrac a
    x) b -> b -> b
    forall a. Num a => a -> a -> a
    P.* b
    s b -> b -> b
    forall a. Fractional a => a -> a -> a
    P./ b
    y)
      where
        s :: b
    s = Proxy s -> b
    forall (v :: ExactPi') a. MinCtxt v a => Proxy v -> a
    E.injMin (Proxy s
    forall {k} (t :: k). Proxy t
    Proxy :: Proxy s)

    {-

    Rescaling Operations

    -}

    -- | Rescales a fixed point quantity, accomodating changes both in its scale factor and its representation type.
    --
    -- Note that this uses an arbitrary precision representation of 'pi', which may be quite slow.
    rescale :: forall a b d s1 s2.(Integral a, Integral b, E.KnownExactPi s1, E.KnownExactPi s2) => SQuantity s1 d a -> SQuantity s2 d b
    rescale :: forall a b (d :: Dimension) (s1 :: ExactPi') (s2 :: ExactPi').
    (Integral a, Integral b, KnownExactPi s1, KnownExactPi s2) =>
    SQuantity s1 d a -> SQuantity s2 d b
    rescale | Just Integer
    s' <- ExactPi -> Maybe Integer
    toExactInteger ExactPi
    s           = (Integer -> Integer) -> SQuantity s1 d a -> SQuantity s2 d b
    forall a b (s1 :: ExactPi') (d :: Dimension) (s2 :: ExactPi').
    (Integral a, Integral b) =>
    (Integer -> Integer) -> SQuantity s1 d a -> SQuantity s2 d b
    viaInteger (Integer -> Integer -> Integer
    forall a. Num a => a -> a -> a
    P.* Integer
    s')
            | Just Integer
    s' <- ExactPi -> Maybe Integer
    toExactInteger (ExactPi -> ExactPi
    forall a. Fractional a => a -> a
    P.recip ExactPi
    s) = (Integer -> Integer) -> SQuantity s1 d a -> SQuantity s2 d b
    forall a b (s1 :: ExactPi') (d :: Dimension) (s2 :: ExactPi').
    (Integral a, Integral b) =>
    (Integer -> Integer) -> SQuantity s1 d a -> SQuantity s2 d b
    viaInteger (Integer -> Integer -> Integer
    forall a. Integral a => a -> a -> a
    `P.quot` Integer
    s')
            | Just Rational
    q  <- ExactPi -> Maybe Rational
    toExactRational ExactPi
    s          = (Integer -> Integer) -> SQuantity s1 d a -> SQuantity s2 d b
    forall a b (s1 :: ExactPi') (d :: Dimension) (s2 :: ExactPi').
    (Integral a, Integral b) =>
    (Integer -> Integer) -> SQuantity s1 d a -> SQuantity s2 d b
    viaInteger ((Integer -> Integer) -> SQuantity s1 d a -> SQuantity s2 d b)
    -> (Integer -> Integer) -> SQuantity s1 d a -> SQuantity s2 d b
    forall a b. (a -> b) -> a -> b
    $ Rational -> Integer -> Integer
    timesRational Rational
    q
            | Bool
    otherwise                             = (Integer -> Integer) -> SQuantity s1 d a -> SQuantity s2 d b
    forall a b (s1 :: ExactPi') (d :: Dimension) (s2 :: ExactPi').
    (Integral a, Integral b) =>
    (Integer -> Integer) -> SQuantity s1 d a -> SQuantity s2 d b
    viaInteger ((Integer -> Integer) -> SQuantity s1 d a -> SQuantity s2 d b)
    -> (Integer -> Integer) -> SQuantity s1 d a -> SQuantity s2 d b
    forall a b. (a -> b) -> a -> b
    $ \Integer
    x -> [Integer] -> Integer
    forall a. Eq a => [a] -> a
    fixedPoint ((Rational -> Integer) -> [Rational] -> [Integer]
    forall a b. (a -> b) -> [a] -> [b]
    forall (f :: Type -> Type) a b. Functor f => (a -> b) -> f a -> f b
    fmap (((Integer -> Integer) -> Integer -> Integer
    forall a b. (a -> b) -> a -> b
    $ Integer
    x) ((Integer -> Integer) -> Integer)
    -> (Rational -> Integer -> Integer) -> Rational -> Integer
    forall b c a. (b -> c) -> (a -> b) -> a -> c
    forall {k} (cat :: k -> k -> Type) (b :: k) (c :: k) (a :: k).
    Category cat =>
    cat b c -> cat a b -> cat a c
    . Rational -> Integer -> Integer
    timesRational) (ExactPi -> [Rational]
    rationalApproximations ExactPi
    s))
      where
        s :: ExactPi
    s = (ExactPi
    s1' ExactPi -> ExactPi -> ExactPi
    forall a. Fractional a => a -> a -> a
    P./ ExactPi
    s2')
        s1' :: ExactPi
    s1' = Proxy s1 -> ExactPi
    forall (v :: ExactPi'). KnownExactPi v => Proxy v -> ExactPi
    E.exactPiVal (Proxy s1
    forall {k} (t :: k). Proxy t
    Proxy :: Proxy s1)
        s2' :: ExactPi
    s2' = Proxy s2 -> ExactPi
    forall (v :: ExactPi'). KnownExactPi v => Proxy v -> ExactPi
    E.exactPiVal (Proxy s2
    forall {k} (t :: k). Proxy t
    Proxy :: Proxy s2)
        timesRational :: Rational -> Integer -> Integer
        timesRational :: Rational -> Integer -> Integer
    timesRational Rational
    q = (Integer -> Integer -> Integer
    forall a. Integral a => a -> a -> a
    `P.quot` Rational -> Integer
    forall a. Ratio a -> a
    denominator Rational
    q) (Integer -> Integer) -> (Integer -> Integer) -> Integer -> Integer
    forall b c a. (b -> c) -> (a -> b) -> a -> c
    forall {k} (cat :: k -> k -> Type) (b :: k) (c :: k) (a :: k).
    Category cat =>
    cat b c -> cat a b -> cat a c
    . (Integer -> Integer -> Integer
    forall a. Num a => a -> a -> a
    P.* Rational -> Integer
    forall a. Ratio a -> a
    numerator Rational
    q)

    -- | Rescales a fixed point quantity, accomodating changes both in its scale factor and its representation type.
    --
    -- Expected to outperform `rescale` when a `FiniteBits` context is available for the source and destination representation types.
    rescaleFinite :: (Integral a, FiniteBits a, Integral b, FiniteBits b, E.KnownExactPi s1, E.KnownExactPi s2) => SQuantity s1 d a -> SQuantity s2 d b
    rescaleFinite :: forall a b (s1 :: ExactPi') (s2 :: ExactPi') (d :: Dimension).
    (Integral a, FiniteBits a, Integral b, FiniteBits b,
     KnownExactPi s1, KnownExactPi s2) =>
    SQuantity s1 d a -> SQuantity s2 d b
    rescaleFinite = SQuantity s1 d a -> SQuantity s2 d b
    forall a b (d :: Dimension) (s1 :: ExactPi') (s2 :: ExactPi').
    (Integral a, Integral b, KnownExactPi s1, KnownExactPi s2) =>
    SQuantity s1 d a -> SQuantity s2 d b
    rescale -- It should be possible to do this more quickly, since we have a priori knowledge of how well we need to approximate the result

    -- | Approximately rescales a fixed point quantity, accomodating changes both in its scale factor and its representation type.
    --
    -- Uses approximate arithmetic by way of an intermediate `Floating` type, to which a proxy must be supplied.
    rescaleVia :: forall a b c d s1 s2.(Integral a, RealFrac b, Floating b, Integral c, E.KnownExactPi s1, E.KnownExactPi s2) => Proxy b -> SQuantity s1 d a -> SQuantity s2 d c
    rescaleVia :: forall a b c (d :: Dimension) (s1 :: ExactPi') (s2 :: ExactPi').
    (Integral a, RealFrac b, Floating b, Integral c, KnownExactPi s1,
     KnownExactPi s2) =>
    Proxy b -> SQuantity s1 d a -> SQuantity s2 d c
    rescaleVia Proxy b
    _ = (b -> b) -> SQuantity s1 d a -> SQuantity s2 d c
    forall a b c (s1 :: ExactPi') (d :: Dimension) (s2 :: ExactPi').
    (Integral a, RealFrac b, Integral c) =>
    (b -> b) -> SQuantity s1 d a -> SQuantity s2 d c
    viaIntermediate (b -> b -> b
    forall a. Num a => a -> a -> a
    P.* b
    s)
      where
        s :: b
    s = ExactPi -> b
    forall a. Floating a => ExactPi -> a
    approximateValue (ExactPi
    s1' ExactPi -> ExactPi -> ExactPi
    forall a. Fractional a => a -> a -> a
    P./ ExactPi
    s2') :: b
        s1' :: ExactPi
    s1' = Proxy s1 -> ExactPi
    forall (v :: ExactPi'). KnownExactPi v => Proxy v -> ExactPi
    E.exactPiVal (Proxy s1 -> ExactPi) -> Proxy s1 -> ExactPi
    forall a b. (a -> b) -> a -> b
    $ (Proxy s1
    forall {k} (t :: k). Proxy t
    Proxy :: Proxy s1)
        s2' :: ExactPi
    s2' = Proxy s2 -> ExactPi
    forall (v :: ExactPi'). KnownExactPi v => Proxy v -> ExactPi
    E.exactPiVal (Proxy s2 -> ExactPi) -> Proxy s2 -> ExactPi
    forall a b. (a -> b) -> a -> b
    $ (Proxy s2
    forall {k} (t :: k). Proxy t
    Proxy :: Proxy s2)

    -- | Approximately rescales a fixed point quantity, accomodating changes both in its scale factor and its representation type.
    --
    -- Uses approximate arithmetic by way of an intermediate `Double` representation.
    rescaleD :: (Integral a, Integral b, E.KnownExactPi s1, E.KnownExactPi s2) => SQuantity s1 d a -> SQuantity s2 d b
    rescaleD :: forall a b (s1 :: ExactPi') (s2 :: ExactPi') (d :: Dimension).
    (Integral a, Integral b, KnownExactPi s1, KnownExactPi s2) =>
    SQuantity s1 d a -> SQuantity s2 d b
    rescaleD = Proxy Double -> SQuantity s1 d a -> SQuantity s2 d b
    forall a b c (d :: Dimension) (s1 :: ExactPi') (s2 :: ExactPi').
    (Integral a, RealFrac b, Floating b, Integral c, KnownExactPi s1,
     KnownExactPi s2) =>
    Proxy b -> SQuantity s1 d a -> SQuantity s2 d c
    rescaleVia (Proxy Double
    forall {k} (t :: k). Proxy t
    Proxy :: Proxy Double)

    -- Note that this does not respect scaling factors at all.
    viaInteger :: (Integral a, Integral b) => (P.Integer -> P.Integer) -> SQuantity s1 d a -> SQuantity s2 d b
    viaInteger :: forall a b (s1 :: ExactPi') (d :: Dimension) (s2 :: ExactPi').
    (Integral a, Integral b) =>
    (Integer -> Integer) -> SQuantity s1 d a -> SQuantity s2 d b
    viaInteger Integer -> Integer
    f = b -> SQuantity s2 d b
    forall (s :: ExactPi') (d :: Dimension) a.
    a -> Dimensional ('DQuantity s) d a
    Quantity (b -> SQuantity s2 d b)
    -> (SQuantity s1 d a -> b) -> SQuantity s1 d a -> SQuantity s2 d b
    forall b c a. (b -> c) -> (a -> b) -> a -> c
    forall {k} (cat :: k -> k -> Type) (b :: k) (c :: k) (a :: k).
    Category cat =>
    cat b c -> cat a b -> cat a c
    . Integer -> b
    forall a. Num a => Integer -> a
    fromInteger (Integer -> b)
    -> (SQuantity s1 d a -> Integer) -> SQuantity s1 d a -> b
    forall b c a. (b -> c) -> (a -> b) -> a -> c
    forall {k} (cat :: k -> k -> Type) (b :: k) (c :: k) (a :: k).
    Category cat =>
    cat b c -> cat a b -> cat a c
    . Integer -> Integer
    f (Integer -> Integer)
    -> (SQuantity s1 d a -> Integer) -> SQuantity s1 d a -> Integer
    forall b c a. (b -> c) -> (a -> b) -> a -> c
    forall {k} (cat :: k -> k -> Type) (b :: k) (c :: k) (a :: k).
    Category cat =>
    cat b c -> cat a b -> cat a c
    . a -> Integer
    forall a b. (Integral a, Num b) => a -> b
    fromIntegral (a -> Integer)
    -> (SQuantity s1 d a -> a) -> SQuantity s1 d a -> Integer
    forall b c a. (b -> c) -> (a -> b) -> a -> c
    forall {k} (cat :: k -> k -> Type) (b :: k) (c :: k) (a :: k).
    Category cat =>
    cat b c -> cat a b -> cat a c
    . SQuantity s1 d a -> a
    forall (s :: ExactPi') (d :: Dimension) a. SQuantity s d a -> a
    unQuantity

    -- Note that this does not respect scaling factors at all.
    viaIntermediate :: (Integral a, RealFrac b, Integral c) => (b -> b) -> SQuantity s1 d a -> SQuantity s2 d c
    viaIntermediate :: forall a b c (s1 :: ExactPi') (d :: Dimension) (s2 :: ExactPi').
    (Integral a, RealFrac b, Integral c) =>
    (b -> b) -> SQuantity s1 d a -> SQuantity s2 d c
    viaIntermediate b -> b
    f = c -> SQuantity s2 d c
    forall (s :: ExactPi') (d :: Dimension) a.
    a -> Dimensional ('DQuantity s) d a
    Quantity (c -> SQuantity s2 d c)
    -> (SQuantity s1 d a -> c) -> SQuantity s1 d a -> SQuantity s2 d c
    forall b c a. (b -> c) -> (a -> b) -> a -> c
    forall {k} (cat :: k -> k -> Type) (b :: k) (c :: k) (a :: k).
    Category cat =>
    cat b c -> cat a b -> cat a c
    . b -> c
    forall b. Integral b => b -> b
    forall a b. (RealFrac a, Integral b) => a -> b
    round (b -> c) -> (SQuantity s1 d a -> b) -> SQuantity s1 d a -> c
    forall b c a. (b -> c) -> (a -> b) -> a -> c
    forall {k} (cat :: k -> k -> Type) (b :: k) (c :: k) (a :: k).
    Category cat =>
    cat b c -> cat a b -> cat a c
    . b -> b
    f (b -> b) -> (SQuantity s1 d a -> b) -> SQuantity s1 d a -> b
    forall b c a. (b -> c) -> (a -> b) -> a -> c
    forall {k} (cat :: k -> k -> Type) (b :: k) (c :: k) (a :: k).
    Category cat =>
    cat b c -> cat a b -> cat a c
    . a -> b
    forall a b. (Integral a, Num b) => a -> b
    fromIntegral (a -> b) -> (SQuantity s1 d a -> a) -> SQuantity s1 d a -> b
    forall b c a. (b -> c) -> (a -> b) -> a -> c
    forall {k} (cat :: k -> k -> Type) (b :: k) (c :: k) (a :: k).
    Category cat =>
    cat b c -> cat a b -> cat a c
    . SQuantity s1 d a -> a
    forall (s :: ExactPi') (d :: Dimension) a. SQuantity s d a -> a
    unQuantity

    fixedPoint :: (Eq a) => [a] -> a
    fixedPoint :: forall a. Eq a => [a] -> a
    fixedPoint []                     = [Char] -> a
    forall a. HasCallStack => [Char] -> a
    error [Char]
    "Fixed point of empty list."
    fixedPoint [a
    x]                    = a
    x
    fixedPoint (a
    x1:a
    x2:[a]
    xs) | a
    x1 a -> a -> Bool
    forall a. Eq a => a -> a -> Bool
    == a
    x2  = a
    x1
                          | Bool
    otherwise = [a] -> a
    forall a. Eq a => [a] -> a
    fixedPoint (a
    x2a -> [a] -> [a]
    forall a. a -> [a] -> [a]
    :[a]
    xs)

    {-

    Changes of Representation

    -}

    -- | Convenient conversion between numerical types while retaining dimensional information.
    changeRep :: forall v1 v2 d a b.
                (KnownVariant v1, KnownVariant v2,
                 CompatibleVariants v1 v2,
                 E.MinCtxt (ScaleFactor v1 E./ ScaleFactor v2) b,
                 Real a, Fractional b)
              => Dimensional v1 d a -> Dimensional v2 d b
    changeRep :: forall (v1 :: Variant) (v2 :: Variant) (d :: Dimension) a b.
    (KnownVariant v1, KnownVariant v2, CompatibleVariants v1 v2,
     MinCtxt (ScaleFactor v1 / ScaleFactor v2) b, Real a,
     Fractional b) =>
    Dimensional v1 d a -> Dimensional v2 d b
    changeRep = (ExactPi -> ExactPi)
    -> (a -> b)
    -> UnitNameTransformer
    -> Dimensional v1 d a
    -> Dimensional v2 d b
    forall (v1 :: Variant) (v2 :: Variant) a b (d1 :: Dimension)
           (d2 :: Dimension).
    (KnownVariant v1, KnownVariant v2) =>
    (ExactPi -> ExactPi)
    -> (a -> b)
    -> UnitNameTransformer
    -> Dimensional v1 d1 a
    -> Dimensional v2 d2 b
    liftD (ExactPi -> ExactPi -> ExactPi
    forall a. Num a => a -> a -> a
    P.* ExactPi
    s) ((b -> b -> b
    forall a. Num a => a -> a -> a
    P.* b
    s') (b -> b) -> (a -> b) -> a -> b
    forall b c a. (b -> c) -> (a -> b) -> a -> c
    forall {k} (cat :: k -> k -> Type) (b :: k) (c :: k) (a :: k).
    Category cat =>
    cat b c -> cat a b -> cat a c
    . a -> b
    forall a b. (Real a, Fractional b) => a -> b
    realToFrac) UnitName m -> UnitName 'NonMetric
    UnitNameTransformer
    Name.weaken
      where
        p :: Proxy (ScaleFactor v1 E./ ScaleFactor v2)
        p :: Proxy (ScaleFactor v1 / ScaleFactor v2)
    p = Proxy (ScaleFactor v1 / ScaleFactor v2)
    forall {k} (t :: k). Proxy t
    Proxy
        s :: ExactPi
    s = Proxy (ScaleFactor v1 / ScaleFactor v2) -> ExactPi
    forall (v :: ExactPi'). KnownExactPi v => Proxy v -> ExactPi
    E.exactPiVal Proxy (ScaleFactor v1 / ScaleFactor v2)
    p
        s' :: b
    s' = Proxy (ScaleFactor v1 / ScaleFactor v2) -> b
    forall (v :: ExactPi') a. MinCtxt v a => Proxy v -> a
    E.injMin Proxy (ScaleFactor v1 / ScaleFactor v2)
    p

    -- | Convenient conversion to types with `Integral` representations using `round`.
    changeRepRound :: forall v1 v2 d a b.
                     (KnownVariant v1, KnownVariant v2,
                      CompatibleVariants v1 v2,
                      E.MinCtxt (ScaleFactor v1 E./ ScaleFactor v2) a,
                      RealFrac a, Integral b)
                   => Dimensional v1 d a -> Dimensional v2 d b
    changeRepRound :: forall (v1 :: Variant) (v2 :: Variant) (d :: Dimension) a b.
    (KnownVariant v1, KnownVariant v2, CompatibleVariants v1 v2,
     MinCtxt (ScaleFactor v1 / ScaleFactor v2) a, RealFrac a,
     Integral b) =>
    Dimensional v1 d a -> Dimensional v2 d b
    changeRepRound = (ExactPi -> ExactPi)
    -> (a -> b)
    -> UnitNameTransformer
    -> Dimensional v1 d a
    -> Dimensional v2 d b
    forall (v1 :: Variant) (v2 :: Variant) a b (d1 :: Dimension)
           (d2 :: Dimension).
    (KnownVariant v1, KnownVariant v2) =>
    (ExactPi -> ExactPi)
    -> (a -> b)
    -> UnitNameTransformer
    -> Dimensional v1 d1 a
    -> Dimensional v2 d2 b
    liftD (ExactPi -> ExactPi -> ExactPi
    forall a. Num a => a -> a -> a
    P.* ExactPi
    s) (a -> b
    forall b. Integral b => a -> b
    forall a b. (RealFrac a, Integral b) => a -> b
    round (a -> b) -> (a -> a) -> a -> b
    forall b c a. (b -> c) -> (a -> b) -> a -> c
    forall {k} (cat :: k -> k -> Type) (b :: k) (c :: k) (a :: k).
    Category cat =>
    cat b c -> cat a b -> cat a c
    . (a -> a -> a
    forall a. Num a => a -> a -> a
    P.* a
    s')) UnitName m -> UnitName 'NonMetric
    UnitNameTransformer
    Name.weaken
      where
        p :: Proxy (ScaleFactor v1 E./ ScaleFactor v2)
        p :: Proxy (ScaleFactor v1 / ScaleFactor v2)
    p = Proxy (ScaleFactor v1 / ScaleFactor v2)
    forall {k} (t :: k). Proxy t
    Proxy
        s :: ExactPi
    s = Proxy (ScaleFactor v1 / ScaleFactor v2) -> ExactPi
    forall (v :: ExactPi'). KnownExactPi v => Proxy v -> ExactPi
    E.exactPiVal Proxy (ScaleFactor v1 / ScaleFactor v2)
    p
        s' :: a
    s' = Proxy (ScaleFactor v1 / ScaleFactor v2) -> a
    forall (v :: ExactPi') a. MinCtxt v a => Proxy v -> a
    E.injMin Proxy (ScaleFactor v1 / ScaleFactor v2)
    p

    {-

    Useful Constant Values

    -}

    {- $possibly-imprecise-constants

    Note that, other than '_0' and 'epsilon', these constants may not be exactly representable with certain scale factors.

    -}

    -- | The constant for zero is polymorphic, allowing
    -- it to express zero 'Length' or 'Capacitance' or 'Velocity' etc, in addition
    -- to the 'Dimensionless' value zero.
    _0 :: Num a => SQuantity s d a
    _0 :: forall a (s :: ExactPi') (d :: Dimension). Num a => SQuantity s d a
    _0 = a -> Dimensional ('DQuantity s) d a
    forall (s :: ExactPi') (d :: Dimension) a.
    a -> Dimensional ('DQuantity s) d a
    Quantity a
    0

    _1, _2, _3, _4, _5, _6, _7, _8, _9 :: (Integral a, E.KnownExactPi s) => SQuantity s DOne a
    _1 :: forall a (s :: ExactPi').
    (Integral a, KnownExactPi s) =>
    SQuantity s DOne a
    _1 = SQuantity One DOne Integer -> SQuantity s DOne a
    forall a b (d :: Dimension) (s1 :: ExactPi') (s2 :: ExactPi').
    (Integral a, Integral b, KnownExactPi s1, KnownExactPi s2) =>
    SQuantity s1 d a -> SQuantity s2 d b
    rescale (SQuantity One DOne Integer
    forall a (s :: ExactPi') (d :: Dimension).
    Integral a =>
    SQuantity s d a
    epsilon :: SQuantity E.One DOne Integer)
    _2 :: forall a (s :: ExactPi').
    (Integral a, KnownExactPi s) =>
    SQuantity s DOne a
    _2 = SQuantity (ExactNatural 2) DOne Integer -> SQuantity s DOne a
    forall a b (d :: Dimension) (s1 :: ExactPi') (s2 :: ExactPi').
    (Integral a, Integral b, KnownExactPi s1, KnownExactPi s2) =>
    SQuantity s1 d a -> SQuantity s2 d b
    rescale (SQuantity (ExactNatural 2) DOne Integer
    forall a (s :: ExactPi') (d :: Dimension).
    Integral a =>
    SQuantity s d a
    epsilon :: SQuantity (E.ExactNatural 2) DOne Integer)
    _3 :: forall a (s :: ExactPi').
    (Integral a, KnownExactPi s) =>
    SQuantity s DOne a
    _3 = SQuantity (ExactNatural 3) DOne Integer -> SQuantity s DOne a
    forall a b (d :: Dimension) (s1 :: ExactPi') (s2 :: ExactPi').
    (Integral a, Integral b, KnownExactPi s1, KnownExactPi s2) =>
    SQuantity s1 d a -> SQuantity s2 d b
    rescale (SQuantity (ExactNatural 3) DOne Integer
    forall a (s :: ExactPi') (d :: Dimension).
    Integral a =>
    SQuantity s d a
    epsilon :: SQuantity (E.ExactNatural 3) DOne Integer)
    _4 :: forall a (s :: ExactPi').
    (Integral a, KnownExactPi s) =>
    SQuantity s DOne a
    _4 = SQuantity (ExactNatural 4) DOne Integer -> SQuantity s DOne a
    forall a b (d :: Dimension) (s1 :: ExactPi') (s2 :: ExactPi').
    (Integral a, Integral b, KnownExactPi s1, KnownExactPi s2) =>
    SQuantity s1 d a -> SQuantity s2 d b
    rescale (SQuantity (ExactNatural 4) DOne Integer
    forall a (s :: ExactPi') (d :: Dimension).
    Integral a =>
    SQuantity s d a
    epsilon :: SQuantity (E.ExactNatural 4) DOne Integer)
    _5 :: forall a (s :: ExactPi').
    (Integral a, KnownExactPi s) =>
    SQuantity s DOne a
    _5 = SQuantity (ExactNatural 5) DOne Integer -> SQuantity s DOne a
    forall a b (d :: Dimension) (s1 :: ExactPi') (s2 :: ExactPi').
    (Integral a, Integral b, KnownExactPi s1, KnownExactPi s2) =>
    SQuantity s1 d a -> SQuantity s2 d b
    rescale (SQuantity (ExactNatural 5) DOne Integer
    forall a (s :: ExactPi') (d :: Dimension).
    Integral a =>
    SQuantity s d a
    epsilon :: SQuantity (E.ExactNatural 5) DOne Integer)
    _6 :: forall a (s :: ExactPi').
    (Integral a, KnownExactPi s) =>
    SQuantity s DOne a
    _6 = SQuantity (ExactNatural 6) DOne Integer -> SQuantity s DOne a
    forall a b (d :: Dimension) (s1 :: ExactPi') (s2 :: ExactPi').
    (Integral a, Integral b, KnownExactPi s1, KnownExactPi s2) =>
    SQuantity s1 d a -> SQuantity s2 d b
    rescale (SQuantity (ExactNatural 6) DOne Integer
    forall a (s :: ExactPi') (d :: Dimension).
    Integral a =>
    SQuantity s d a
    epsilon :: SQuantity (E.ExactNatural 6) DOne Integer)
    _7 :: forall a (s :: ExactPi').
    (Integral a, KnownExactPi s) =>
    SQuantity s DOne a
    _7 = SQuantity (ExactNatural 7) DOne Integer -> SQuantity s DOne a
    forall a b (d :: Dimension) (s1 :: ExactPi') (s2 :: ExactPi').
    (Integral a, Integral b, KnownExactPi s1, KnownExactPi s2) =>
    SQuantity s1 d a -> SQuantity s2 d b
    rescale (SQuantity (ExactNatural 7) DOne Integer
    forall a (s :: ExactPi') (d :: Dimension).
    Integral a =>
    SQuantity s d a
    epsilon :: SQuantity (E.ExactNatural 7) DOne Integer)
    _8 :: forall a (s :: ExactPi').
    (Integral a, KnownExactPi s) =>
    SQuantity s DOne a
    _8 = SQuantity (ExactNatural 8) DOne Integer -> SQuantity s DOne a
    forall a b (d :: Dimension) (s1 :: ExactPi') (s2 :: ExactPi').
    (Integral a, Integral b, KnownExactPi s1, KnownExactPi s2) =>
    SQuantity s1 d a -> SQuantity s2 d b
    rescale (SQuantity (ExactNatural 8) DOne Integer
    forall a (s :: ExactPi') (d :: Dimension).
    Integral a =>
    SQuantity s d a
    epsilon :: SQuantity (E.ExactNatural 8) DOne Integer)
    _9 :: forall a (s :: ExactPi').
    (Integral a, KnownExactPi s) =>
    SQuantity s DOne a
    _9 = SQuantity (ExactNatural 9) DOne Integer -> SQuantity s DOne a
    forall a b (d :: Dimension) (s1 :: ExactPi') (s2 :: ExactPi').
    (Integral a, Integral b, KnownExactPi s1, KnownExactPi s2) =>
    SQuantity s1 d a -> SQuantity s2 d b
    rescale (SQuantity (ExactNatural 9) DOne Integer
    forall a (s :: ExactPi') (d :: Dimension).
    Integral a =>
    SQuantity s d a
    epsilon :: SQuantity (E.ExactNatural 9) DOne Integer)

    pi :: (Integral a, E.KnownExactPi s) => SQuantity s DOne a
    pi :: forall a (s :: ExactPi').
    (Integral a, KnownExactPi s) =>
    SQuantity s DOne a
    pi = SQuantity Pi DOne Integer -> SQuantity s DOne a
    forall a b (d :: Dimension) (s1 :: ExactPi') (s2 :: ExactPi').
    (Integral a, Integral b, KnownExactPi s1, KnownExactPi s2) =>
    SQuantity s1 d a -> SQuantity s2 d b
    rescale (SQuantity Pi DOne Integer
    forall a (s :: ExactPi') (d :: Dimension).
    Integral a =>
    SQuantity s d a
    epsilon :: SQuantity E.Pi DOne Integer)

    -- | Twice 'pi'.
    --
    -- For background on 'tau' see [The Tau Manifesto](https://tauday.com/tau-manifesto) (but also
    -- feel free to review [The Pi Manifesto](https://web.archive.org/web/20200926221249/http://www.thepimanifesto.com/)).
    tau :: (Integral a, E.KnownExactPi s) => SQuantity s DOne a
    tau :: forall a (s :: ExactPi').
    (Integral a, KnownExactPi s) =>
    SQuantity s DOne a
    tau = SQuantity ('ExactPi' 'Pos1 2 1) DOne Integer -> SQuantity s DOne a
    forall a b (d :: Dimension) (s1 :: ExactPi') (s2 :: ExactPi').
    (Integral a, Integral b, KnownExactPi s1, KnownExactPi s2) =>
    SQuantity s1 d a -> SQuantity s2 d b
    rescale (Dimensional ('DQuantity (ExactNatural 2 * Pi)) DOne Integer
    SQuantity ('ExactPi' 'Pos1 2 1) DOne Integer
    forall a (s :: ExactPi') (d :: Dimension).
    Integral a =>
    SQuantity s d a
    epsilon :: SQuantity (E.ExactNatural 2 E.* E.Pi) DOne Integer)

    -- | The smallest positive representable value in a given fixed-point scaled quantity type.
    epsilon :: (Integral a) => SQuantity s d a
    epsilon :: forall a (s :: ExactPi') (d :: Dimension).
    Integral a =>
    SQuantity s d a
    epsilon = a -> Dimensional ('DQuantity s) d a
    forall (s :: ExactPi') (d :: Dimension) a.
    a -> Dimensional ('DQuantity s) d a
    Quantity a
    1

    {- $synonyms

    These type synonyms for commonly used fixed-point types are provided for convenience.

    -}

    -- | A binary scale factor.
    type QScale n = (E.One E./ (E.ExactNatural (2 N.^ n)))

    -- | A dimensionless number with `n` fractional bits, using a representation of type `a`.
    type Q n a = SQuantity (QScale n) DOne a

    -- | A single-turn angle represented as a signed 8-bit integer.
    type Angle8  = SQuantity (E.Pi E.* (QScale 7))  DPlaneAngle Int8

    -- | A single-turn angle represented as a signed 16-bit integer.
    type Angle16 = SQuantity (E.Pi E.* (QScale 15)) DPlaneAngle Int16

    -- | A single-turn angle represented as a signed 32-bit integer.
    type Angle32 = SQuantity (E.Pi E.* (QScale 31)) DPlaneAngle Int32