-- Hoogle documentation, generated by Haddock -- See Hoogle, http://www.haskell.org/hoogle/ -- | A domain-specific type system for dimensional analysis -- -- The units package provides a mechanism for compile-time dimensional -- analysis in Haskell programs. It defines an embedded type system based -- on units-of-measure. The units defined are fully extensible, and need -- not relate to physical properties. The package supports defining -- multiple inter-convertible units, such as Meter and Foot. When -- extracting a number from a dimensioned quantity, the desired unit must -- be specified, and the value is converted into that unit. If you are -- looking for specific systems of units (such as SI), please see the -- `units-defs` package. The Haddock documentation is insufficient for -- using the units package. Please see the README file, available from -- the package home page. @package units @version 2.4 -- | This module defines a datatype and operations to represent type-level -- integers. Though it's defined as part of the units package, it may be -- useful beyond dimensional analysis. If you have a compelling non-units -- use of this package, please let me (Richard, eir at -- cis.upenn.edu) know. module Data.Metrology.Z -- | The datatype for type-level integers. data Z Zero :: Z S :: Z -> Z P :: Z -> Z -- | The singleton kind-indexed data family. type SZ = (Sing :: Z -> *) type ZeroSym0 = Zero data SSym0 (l_ab5l :: TyFun Z Z) type SSym1 (t_ab5k :: Z) = S t_ab5k data PSym0 (l_ab5o :: TyFun Z Z) type PSym1 (t_ab5n :: Z) = P t_ab5n -- | Convert a Z to an Int zToInt :: Z -> Int -- | Convert a singleton Z to an Int. szToInt :: Sing (z :: Z) -> Int -- | Add one to an integer -- | Subtract one from an integer -- | Negate an integer -- | Add two integers -- | Subtract two integers -- | Multiply two integers -- | Divide two integers -- | Add one to a singleton Z. sSucc :: Sing z -> Sing (Succ z) -- | Subtract one from a singleton Z. sPred :: Sing z -> Sing (Pred z) -- | Negate a singleton Z. sNegate :: Sing z -> Sing (Negate z) -- | Less-than comparison -- | Check if a type-level integer is in fact a natural number type One = S Zero type Two = S One type Three = S Two type Four = S Three type Five = S Four type MOne = P Zero type MTwo = P MOne type MThree = P MTwo type MFour = P MThree type MFive = P MFour -- | This is the singleton value representing Zero at the term -- level and at the type level, simultaneously. Used for raising units to -- powers. sZero :: Sing Z Zero sOne :: Sing Z (S Zero) sTwo :: Sing Z (S (S Zero)) sThree :: Sing Z (S (S (S Zero))) sFour :: Sing Z (S (S (S (S Zero)))) sFive :: Sing Z (S (S (S (S (S Zero))))) sMOne :: Sing Z (P Zero) sMTwo :: Sing Z (P (P Zero)) sMThree :: Sing Z (P (P (P Zero))) sMFour :: Sing Z (P (P (P (P Zero)))) sMFive :: Sing Z (P (P (P (P (P Zero))))) -- | Deprecated: The singleton prefix is changing from p to -- s. The p versions will be removed in a future -- release. pZero :: Sing Z Zero -- | Deprecated: The singleton prefix is changing from p to -- s. The p versions will be removed in a future -- release. pOne :: Sing Z (S Zero) -- | Deprecated: The singleton prefix is changing from p to -- s. The p versions will be removed in a future -- release. pTwo :: Sing Z (S (S Zero)) -- | Deprecated: The singleton prefix is changing from p to -- s. The p versions will be removed in a future -- release. pThree :: Sing Z (S (S (S Zero))) -- | Deprecated: The singleton prefix is changing from p to -- s. The p versions will be removed in a future -- release. pFour :: Sing Z (S (S (S (S Zero)))) -- | Deprecated: The singleton prefix is changing from p to -- s. The p versions will be removed in a future -- release. pFive :: Sing Z (S (S (S (S (S Zero))))) -- | Deprecated: The singleton prefix is changing from p to -- s. The p versions will be removed in a future -- release. pMOne :: Sing Z (P Zero) -- | Deprecated: The singleton prefix is changing from p to -- s. The p versions will be removed in a future -- release. pMTwo :: Sing Z (P (P Zero)) -- | Deprecated: The singleton prefix is changing from p to -- s. The p versions will be removed in a future -- release. pMThree :: Sing Z (P (P (P Zero))) -- | Deprecated: The singleton prefix is changing from p to -- s. The p versions will be removed in a future -- release. pMFour :: Sing Z (P (P (P (P Zero)))) -- | Deprecated: The singleton prefix is changing from p to -- s. The p versions will be removed in a future -- release. pMFive :: Sing Z (P (P (P (P (P Zero))))) -- | Deprecated: The singleton prefix is changing from p to -- s. The p versions will be removed in a future -- release. pSucc :: Sing Z z -> Sing Z (Succ z) -- | Deprecated: The singleton prefix is changing from p to -- s. The p versions will be removed in a future -- release. pPred :: Sing Z z -> Sing Z (Pred z) instance GHC.Classes.Eq Data.Metrology.Z.Z instance Data.Singletons.Prelude.Eq.PEq 'Data.Proxy.KProxy instance Data.Singletons.SuppressUnusedWarnings.SuppressUnusedWarnings Data.Metrology.Z.SSym0 instance Data.Singletons.SuppressUnusedWarnings.SuppressUnusedWarnings Data.Metrology.Z.PSym0 instance Data.Singletons.SingKind 'Data.Proxy.KProxy instance Data.Singletons.Prelude.Eq.SEq 'Data.Proxy.KProxy instance Data.Singletons.Decide.SDecide 'Data.Proxy.KProxy instance Data.Singletons.SingI 'Data.Metrology.Z.Zero instance Data.Singletons.SingI n0 => Data.Singletons.SingI ('Data.Metrology.Z.S n0) instance Data.Singletons.SingI n0 => Data.Singletons.SingI ('Data.Metrology.Z.P n0) -- | This module defines a few set-like operations on type-level lists. It -- may be applicable beyond the units package. module Data.Metrology.Set -- | Are two lists equal, when considered as sets? -- | Is one list a subset of the other? -- | Is an element contained in a list? -- | This module defines Show instance for quantities. The show -- instance prints out the number stored internally with its correct -- units. To print out quantities with specific units use the function -- showIn. module Data.Metrology.Show instance Data.Metrology.Show.ShowUnitFactor '[] instance (Data.Metrology.Show.ShowUnitFactor rest, GHC.Show.Show unit, Data.Singletons.SingI z) => Data.Metrology.Show.ShowUnitFactor ('Data.Metrology.Factor.F unit z : rest) instance (Data.Metrology.Show.ShowUnitFactor (Data.Metrology.LCSU.LookupList dims lcsu), GHC.Show.Show n) => GHC.Show.Show (Data.Metrology.Qu.Qu dims lcsu n) -- | This module exports the constructor of the Qu type. This allows -- you to write code that takes creates and reads quantities at will, -- which may lead to dimension unsafety. Use at your peril. -- -- This module also exports UnsafeQu, which is a simple wrapper -- around Qu that has Functor, etc., instances. The reason -- Qu itself doesn't have a Functor instance is that it -- would be unit-unsafe, allowing you, say, to add 1 to a quantity.... -- but 1 what? That's the problem. However, a Functor instance is -- likely useful, hence UnsafeQu. module Data.Metrology.Unsafe -- | Qu adds a dimensional annotation to its numerical value type -- n. This is the representation for all quantities. newtype Qu (a :: [Factor *]) (lcsu :: LCSU *) (n :: *) Qu :: n -> Qu -- | A basic wrapper around Qu that has more instances. newtype UnsafeQu d l n UnsafeQu :: Qu d l n -> UnsafeQu d l n [qu] :: UnsafeQu d l n -> Qu d l n instance GHC.Base.Functor (Data.Metrology.Unsafe.UnsafeQu d l) instance GHC.Base.Applicative (Data.Metrology.Unsafe.UnsafeQu d l) instance Data.Foldable.Foldable (Data.Metrology.Unsafe.UnsafeQu d l) instance Data.Traversable.Traversable (Data.Metrology.Unsafe.UnsafeQu d l) -- | Exports combinators for building quantities out of vectors, from the -- linear library. module Data.Metrology.Linear -- | The number 0, polymorphic in its dimension. Use of this will often -- require a type annotation. zeroV :: (Additive f, Num a) => Qu d l (f a) -- | Add two compatible vector quantities (|^+^|) :: (d1 @~ d2, Additive f, Num a) => Qu d1 l (f a) -> Qu d2 l (f a) -> Qu d1 l (f a) -- | Subtract two compatible quantities (|^-^|) :: (d1 @~ d2, Additive f, Num a) => Qu d1 l (f a) -> Qu d2 l (f a) -> Qu d1 l (f a) -- | Negate a vector quantity qNegateV :: (Additive f, Num a) => Qu d l (f a) -> Qu d l (f a) -- | Take the sum of a list of quantities qSumV :: (Foldable t, Additive f, Num a) => t (Qu d l (f a)) -> Qu d l (f a) -- | Multiply a scalar quantity by a vector quantity (|*^|) :: (Functor f, Num a) => Qu d1 l a -> Qu d2 l (f a) -> Qu (Normalize (d1 @+ d2)) l (f a) -- | Multiply a vector quantity by a scalar quantity (|^*|) :: (Functor f, Num a) => Qu d1 l (f a) -> Qu d2 l a -> Qu (Normalize (d1 @+ d2)) l (f a) -- | Divide a vector quantity by a scalar quantity (|^/|) :: (Functor f, Fractional a) => Qu d1 l (f a) -> Qu d2 l a -> Qu (Normalize (d1 @- d2)) l (f a) -- | Multiply a quantity by a plain old number from the left (*^|) :: (Functor f, Num a) => a -> Qu b l (f a) -> Qu b l (f a) -- | Multiply a quantity by a plain old number from the right (|^*) :: (Functor f, Num a) => Qu b l (f a) -> a -> Qu b l (f a) -- | Divide a quantity by a plain old number (|^/) :: (Functor f, Fractional a) => Qu d l (f a) -> a -> Qu d l (f a) -- | Take a inner (dot) product between two quantities. (|.|) :: (Metric f, Num a) => Qu d1 l (f a) -> Qu d2 l (f a) -> Qu (Normalize (d1 @+ d2)) l a -- | Return a default basis, where each basis element measures 1 of the -- unit provided. qBasis :: (ValidDLU dim lcsu unit, Additive f, Traversable f, Fractional a) => unit -> [Qu dim lcsu (f a)] -- | Return a default basis for the vector space provided. Each basis -- element measures 1 of the unit provided. qBasisFor :: (ValidDLU dim lcsu unit, Additive f, Traversable f, Fractional a) => unit -> Qu dim lcsu (f b) -> [Qu dim lcsu (f a)] -- | Produce a diagonal (scale) matrix from a vector qScaled :: (Traversable f, Num a) => Qu dim lcsu (f a) -> Qu dim lcsu (f (f a)) -- | Outer (tensor) product of two quantity vectors qOuter :: (Functor f, Functor g, Num a) => Qu d1 l (f a) -> Qu d2 l (g a) -> Qu (Normalize (d1 @+ d2)) l (f (g a)) -- | Create a unit vector from a setter and a choice of unit. qUnit :: (ValidDLU dim lcsu unit, Additive t, Fractional a) => ASetter' (t a) a -> unit -> Qu dim lcsu (t a) -- | Square the length of a vector. qQuadrance :: (Metric f, Num a) => Qu d l (f a) -> Qu (d @* Two) l a -- | Length of a vector. qNorm :: (Metric f, Floating a) => Qu d l (f a) -> Qu d l a -- | Vector in same direction as given one but with length of one. If given -- the zero vector, then return it. The returned vector is dimensionless. qSignorm :: (Metric f, Floating a) => Qu d l (f a) -> Qu '[] l (f a) -- | qProject u v computes the projection of v onto -- u. qProject :: (Metric f, Fractional a) => Qu d2 l (f a) -> Qu d1 l (f a) -> Qu d1 l (f a) -- | Cross product of 3D vectors. qCross :: Num a => Qu d1 l (V3 a) -> Qu d2 l (V3 a) -> Qu (Normalize (d1 @+ d2)) l (V3 a) -- | Subtract point quantities. (|.-.|) :: (d1 @~ d2, Affine f, Num a) => Qu d1 l (f a) -> Qu d2 l (f a) -> Qu d1 l (Diff f a) -- | Add a point to a vector. (|.+^|) :: (d1 @~ d2, Affine f, Num a) => Qu d1 l (f a) -> Qu d2 l (Diff f a) -> Qu d1 l (f a) -- | Subract a vector from a point. (|.-^|) :: (d1 @~ d2, Affine f, Num a) => Qu d1 l (f a) -> Qu d2 l (Diff f a) -> Qu d1 l (f a) -- | Square of the distance between two vectors. qQd :: (d1 @~ d2, Metric f, Metric (Diff f), Num a) => Qu d1 l (f a) -> Qu d2 l (f a) -> Qu (d1 @* Two) l a -- | Distance between two vectors. qDistance :: (d1 @~ d2, Metric f, Metric (Diff f), Floating a) => Qu d1 l (f a) -> Qu d2 l (f a) -> Qu d1 l a -- | Square of the distance between two points. qQdA :: (d1 @~ d2, Affine f, Foldable (Diff f), Num a) => Qu d1 l (f a) -> Qu d2 l (f a) -> Qu (d1 @* Two) l a -- | Distance between two points. qDistanceA :: (d1 @~ d2, Affine f, Foldable (Diff f), Floating a) => Qu d1 l (f a) -> Qu d2 l (f a) -> Qu d1 l a -- | Extracts a numerical value from a dimensioned quantity, expressed in -- the given unit. For example: -- --
--   inMeters :: Length -> Double
--   inMeters x = numIn x Meter
--   
-- -- or -- --
--   inMeters x = x # Meter
--   
numInV :: (ValidDLU dim lcsu unit, Functor f, Fractional a) => Qu dim lcsu (f a) -> unit -> (f a) -- | Infix synonym for numIn (^#) :: (ValidDLU dim lcsu unit, Functor f, Fractional a) => Qu dim lcsu (f a) -> unit -> (f a) -- | Creates a dimensioned quantity in the given unit. For example: -- --
--   height :: Length
--   height = quOf 2.0 Meter
--   
-- -- or -- --
--   height = 2.0 % Meter
--   
quOfV :: (ValidDLU dim lcsu unit, Functor f, Fractional a) => (f a) -> unit -> Qu dim lcsu (f a) -- | Infix synonym for quOf (^%) :: (ValidDLU dim lcsu unit, Functor f, Fractional a) => (f a) -> unit -> Qu dim lcsu (f a) -- | Show a dimensioned quantity in a given unit. (The default -- Show instance always uses units as specified in the LCSU.) showInV :: (ValidDLU dim lcsu unit, Functor f, Fractional a, Show unit, Show a, Show (f a)) => Qu dim lcsu (f a) -> unit -> String -- | Dimension-keeping cast between different CSUs. convertV :: (ConvertibleLCSUs d l1 l2, Functor f, Fractional a) => Qu d l1 (f a) -> Qu d l2 (f a) -- | Compute the argument in the DefaultLCSU, and present the -- result as lcsu-polymorphic dimension-polymorphic value. Named -- constant because one of its dominant usecase is to inject -- constant quantities into dimension-polymorphic expressions. constantV :: (d @~ e, ConvertibleLCSUs e DefaultLCSU l, Functor f, Fractional a) => Qu d DefaultLCSU (f a) -> Qu e l (f a) -- | This file gathers and exports user-visible type-level definitions, to -- make error messages less cluttered. Non-expert users should never have -- to use the definitions exported from this module. module Data.Metrology.Internal -- | Are two LCSUs inter-convertible at the given dimension? -- | Check if a (dimension factors, LCSU, unit) triple are all valid to be -- used together. -- | Check if a (dimension factors, LCSU) pair are valid to be used -- together. This checks that each dimension maps to a unit of the -- correct dimension. -- | Check if two [Factor *]s, representing units, should -- be considered to be equal -- | Given a list of unit factors, extract out the canonical units they are -- based on. -- | Check to make sure that a unit has the same dimension as its base -- unit, if any. -- | Is this unit a canonical unit? -- | Get the canonical unit from a given unit. For example: -- CanonicalUnit Foot = Meter type CanonicalUnit (unit :: *) = CanonicalUnit' (BaseUnit unit) unit -- | Helper function in CanonicalUnit -- | Essentially, a constraint that checks if a conversion ratio can be -- calculated for a BaseUnit of a unit. -- | Classifies well-formed list of unit factors, and permits calculating a -- conversion ratio for the purposes of LCSU conversions. class UnitFactor (units :: [Factor *]) -- | This will only be used at the kind level. It holds a dimension or unit -- with its exponent. data Factor star F :: star -> Z -> Factor star -- | Do these Factors represent the same dimension? -- | (Extract s lst) pulls the Factor that matches s out of lst, -- returning a diminished list and, possibly, the extracted Factor. -- --
--   Extract A [A, B, C] ==> ([B, C], Just A
--   Extract F [A, B, C] ==> ([A, B, C], Nothing)
--   
-- | Reorders a to be the in the same order as b, putting entries not in b -- at the end -- --
--   Reorder [A 1, B 2] [B 5, A 2] ==> [B 2, A 1]
--   Reorder [A 1, B 2, C 3] [C 2, A 8] ==> [C 3, A 1, B 2]
--   Reorder [A 1, B 2] [B 4, C 1, A 9] ==> [B 2, A 1]
--   Reorder x x ==> x
--   Reorder x [] ==> x
--   Reorder [] x ==> []
--   
-- | Helper function in Reorder -- | Check if two [Factor *]s should be considered to be equal -- | Take a [Factor *] and remove any Factors with an -- exponent of 0 -- | Adds corresponding exponents in two dimension, assuming the lists are -- ordered similarly. -- | Adds corresponding exponents in two dimension, preserving order -- | Subtract exponents in two dimensions, assuming the lists are ordered -- similarly. -- | Subtract exponents in two dimensions -- | negate a single Factor -- | negate a list of Factors -- | Multiplication of the exponents in a dimension by a scalar -- | Division of the exponents in a dimension by a scalar -- | Exports combinators for building quantities out of vectors, from the -- vector-space library. module Data.Metrology.Vector -- | The number 0, polymorphic in its dimension. Use of this will often -- require a type annotation. zero :: AdditiveGroup n => Qu dimspec l n -- | Add two compatible quantities (|+|) :: (d1 @~ d2, AdditiveGroup n) => Qu d1 l n -> Qu d2 l n -> Qu d1 l n -- | Subtract two compatible quantities (|-|) :: (d1 @~ d2, AdditiveGroup n) => Qu d1 l n -> Qu d2 l n -> Qu d1 l n -- | Take the sum of a list of quantities qSum :: (Foldable f, AdditiveGroup n) => f (Qu d l n) -> Qu d l n -- | Negate a quantity qNegate :: AdditiveGroup n => Qu d l n -> Qu d l n -- | Multiply two quantities (|*|) :: Num n => Qu a l n -> Qu b l n -> Qu (Normalize (a @+ b)) l n -- | Divide two quantities (|/|) :: Fractional n => Qu a l n -> Qu b l n -> Qu (Normalize (a @- b)) l n -- | Divide a scalar by a quantity (/|) :: Fractional n => n -> Qu b l n -> Qu (Normalize ('[] @- b)) l n -- | Multiply a quantity by a scalar from the left (*|) :: VectorSpace n => Scalar n -> Qu b l n -> Qu b l n -- | Multiply a quantity by a scalar from the right (|*) :: VectorSpace n => Qu a l n -> Scalar n -> Qu a l n -- | Divide a quantity by a scalar (|/) :: (VectorSpace n, Fractional (Scalar n)) => Qu a l n -> Scalar n -> Qu a l n -- | Multiply a scalar quantity by a vector quantity (|*^|) :: VectorSpace n => Qu d1 l (Scalar n) -> Qu d2 l n -> Qu (Normalize (d1 @+ d2)) l n -- | Multiply a vector quantity by a scalar quantity (|^*|) :: VectorSpace n => Qu d1 l n -> Qu d2 l (Scalar n) -> Qu (Normalize (d1 @+ d2)) l n -- | Divide a vector quantity by a scalar quantity (|^/|) :: (VectorSpace n, Fractional (Scalar n)) => Qu d1 l n -> Qu d2 l (Scalar n) -> Qu (Normalize (d1 @- d2)) l n -- | Take a inner (dot) product between two quantities. (|.|) :: InnerSpace n => Qu d1 l n -> Qu d2 l n -> Qu (Normalize (d1 @+ d2)) l (Scalar n) -- | Raise a quantity to a integer power, knowing at compile time that the -- integer is non-negative. (|^) :: (NonNegative z, Num n) => Qu a l n -> Sing z -> Qu (a @* z) l n -- | Raise a quantity to a integer power known at compile time (|^^) :: Fractional n => Qu a l n -> Sing z -> Qu (a @* z) l n -- | Take the n'th root of a quantity, where n is known at compile time qNthRoot :: ((Zero < z) ~ True, Floating n) => Sing z -> Qu a l n -> Qu (a @/ z) l n -- | Square a quantity qSq :: Num n => Qu a l n -> Qu (Normalize (a @+ a)) l n -- | Cube a quantity qCube :: Num n => Qu a l n -> Qu (Normalize (Normalize (a @+ a) @+ a)) l n -- | Take the square root of a quantity qSqrt :: Floating n => Qu a l n -> Qu (a @/ Two) l n -- | Take the cubic root of a quantity qCubeRoot :: Floating n => Qu a l n -> Qu (a @/ Three) l n -- | Square the length of a vector. qMagnitudeSq :: InnerSpace n => Qu d l n -> Qu (d @* Two) l (Scalar n) -- | Length of a vector. qMagnitude :: (InnerSpace n, Floating (Scalar n)) => Qu d l n -> Qu d l (Scalar n) -- | Vector in same direction as given one but with length of one. If given -- the zero vector, then return it. The returned vector is dimensionless. qNormalized :: (InnerSpace n, Floating (Scalar n)) => Qu d l n -> Qu '[] l n -- | qProject u v computes the projection of v onto -- u. qProject :: (InnerSpace n, Floating (Scalar n)) => Qu d2 l n -> Qu d1 l n -> Qu d1 l n -- | Cross product of 2D vectors. qCross2 :: HasCross2 n => Qu d l n -> Qu d l n -- | Cross product of 3D vectors. qCross3 :: HasCross3 n => Qu d1 l n -> Qu d2 l n -> Qu (Normalize (d1 @+ d2)) l n -- | A Point n is an affine space built over n. Two -- Points cannot be added, but they can be subtracted to yield a -- difference of type n. newtype Point n Point :: n -> Point n -- | Make a point quantity from a non-point quantity. -- | Subtract point quantities. (|.-.|) :: (d1 @~ d2, AffineSpace n) => Qu d1 l n -> Qu d2 l n -> Qu d1 l (Diff n) -- | Add a point to a vector. (|.+^|) :: (d1 @~ d2, AffineSpace n) => Qu d1 l n -> Qu d2 l (Diff n) -> Qu d1 l n -- | Subract a vector from a point. (|.-^|) :: (d1 @~ d2, AffineSpace n) => Qu d1 l n -> Qu d2 l (Diff n) -> Qu d1 l n -- | Square of the distance between two points. qDistanceSq :: (d1 @~ d2, AffineSpace n, InnerSpace (Diff n)) => Qu d1 l n -> Qu d2 l n -> Qu (d1 @* Two) l (Scalar (Diff n)) -- | Distance between two points. qDistance :: (d1 @~ d2, AffineSpace n, InnerSpace (Diff n), Floating (Scalar (Diff n))) => Qu d1 l n -> Qu d2 l n -> Qu d1 l (Scalar (Diff n)) -- | Extract the numerical value from a point quantity. Like numIn. pointNumIn :: (ValidDLU dim lcsu unit, VectorSpace n, Fractional (Scalar n)) => Qu dim lcsu (Point n) -> unit -> n -- | Infix synonym for pointNumIn. (.#) :: (ValidDLU dim lcsu unit, VectorSpace n, Fractional (Scalar n)) => Qu dim lcsu (Point n) -> unit -> n -- | Make a point quantity at the given unit. Like quOf. quOfPoint :: (ValidDLU dim lcsu unit, VectorSpace n, Fractional (Scalar n)) => n -> unit -> Qu dim lcsu (Point n) -- | Infix synonym of quOfPoint (%.) :: (ValidDLU dim lcsu unit, VectorSpace n, Fractional (Scalar n)) => n -> unit -> Qu dim lcsu (Point n) -- | Compare two quantities qCompare :: (d1 @~ d2, Ord n) => Qu d1 l n -> Qu d2 l n -> Ordering -- | Check if one quantity is less than a compatible one (|<|) :: (d1 @~ d2, Ord n) => Qu d1 l n -> Qu d2 l n -> Bool -- | Check if one quantity is greater than a compatible one (|>|) :: (d1 @~ d2, Ord n) => Qu d1 l n -> Qu d2 l n -> Bool -- | Check if one quantity is less than or equal to a compatible one (|<=|) :: (d1 @~ d2, Ord n) => Qu d1 l n -> Qu d2 l n -> Bool -- | Check if one quantity is greater than or equal to a compatible one (|>=|) :: (d1 @~ d2, Ord n) => Qu d1 l n -> Qu d2 l n -> Bool -- | Check if two quantities are equal (uses the equality of the underlying -- numerical type) (|==|) :: (d1 @~ d2, Eq n) => Qu d1 l n -> Qu d2 l n -> Bool -- | Check if two quantities are not equal (|/=|) :: (d1 @~ d2, Eq n) => Qu d1 l n -> Qu d2 l n -> Bool -- | Compare two compatible quantities for approximate equality. If the -- difference between the left hand side and the right hand side -- arguments are less than or equal to the epsilon, they are -- considered equal. qApprox :: (d0 @~ d1, d0 @~ d2, Num n, Ord n) => Qu d0 l n -> Qu d1 l n -> Qu d2 l n -> Bool -- | Compare two compatible quantities for approixmate inequality. -- qNapprox e a b = not $ qApprox e a b qNapprox :: (d0 @~ d1, d0 @~ d2, Num n, Ord n) => Qu d0 l n -> Qu d1 l n -> Qu d2 l n -> Bool -- | Extracts a numerical value from a dimensioned quantity, expressed in -- the given unit. For example: -- --
--   inMeters :: Length -> Double
--   inMeters x = numIn x Meter
--   
-- -- or -- --
--   inMeters x = x # Meter
--   
numIn :: (ValidDLU dim lcsu unit, VectorSpace n, Fractional (Scalar n)) => Qu dim lcsu n -> unit -> n -- | Infix synonym for numIn (#) :: (ValidDLU dim lcsu unit, VectorSpace n, Fractional (Scalar n)) => Qu dim lcsu n -> unit -> n -- | Creates a dimensioned quantity in the given unit. For example: -- --
--   height :: Length
--   height = quOf 2.0 Meter
--   
-- -- or -- --
--   height = 2.0 % Meter
--   
quOf :: (ValidDLU dim lcsu unit, VectorSpace n, Fractional (Scalar n)) => n -> unit -> Qu dim lcsu n -- | Infix synonym for quOf (%) :: (ValidDLU dim lcsu unit, VectorSpace n, Fractional (Scalar n)) => n -> unit -> Qu dim lcsu n -- | Show a dimensioned quantity in a given unit. (The default -- Show instance always uses units as specified in the LCSU.) showIn :: (ValidDLU dim lcsu unit, VectorSpace n, Fractional (Scalar n), Show unit, Show n) => Qu dim lcsu n -> unit -> String -- | The number 1, expressed as a unitless dimensioned quantity. unity :: Num n => Qu '[] l n -- | Cast between equivalent dimension within the same CSU. for example [kg -- m s] and [s m kg]. See the README for more info. redim :: (d @~ e) => Qu d l n -> Qu e l n -- | Dimension-keeping cast between different CSUs. convert :: (ConvertibleLCSUs d l1 l2, VectorSpace n, Fractional (Scalar n)) => Qu d l1 n -> Qu d l2 n -- | Use this to choose a default LCSU for a dimensioned quantity. The -- default LCSU uses the DefaultUnitOfDim representation for each -- dimension. defaultLCSU :: Qu dim DefaultLCSU n -> Qu dim DefaultLCSU n -- | Compute the argument in the DefaultLCSU, and present the -- result as lcsu-polymorphic dimension-polymorphic value. Named -- constant because one of its dominant usecase is to inject -- constant quantities into dimension-polymorphic expressions. constant :: (d @~ e, ConvertibleLCSUs e DefaultLCSU l, VectorSpace n, Fractional (Scalar n)) => Qu d DefaultLCSU n -> Qu e l n -- | Multiply two units to get another unit. For example: type -- MetersSquared = Meter :* Meter data (:*) u1 u2 (:*) :: u1 -> u2 -> (:*) u1 u2 -- | Divide two units to get another unit data (:/) u1 u2 (:/) :: u1 -> u2 -> (:/) u1 u2 -- | Raise a unit to a power, known at compile time data (:^) unit (power :: Z) (:^) :: unit -> Sing power -> (:^) unit -- | Multiply a conversion ratio by some constant. Used for defining -- prefixes. data (:@) prefix unit (:@) :: prefix -> unit -> (:@) prefix unit -- | A class for user-defined prefixes class UnitPrefix prefix -- | This should return the desired multiplier for the prefix being -- defined. This function must not inspect its argument. multiplier :: (UnitPrefix prefix, Fractional f) => prefix -> f -- | Multiply two quantity types to produce a new one. For example: -- --
--   type Velocity = Length %/ Time
--   
-- | Divide two quantity types to produce a new one -- | Exponentiate a quantity type to an integer -- | Qu adds a dimensional annotation to its numerical value type -- n. This is the representation for all quantities. data Qu (a :: [Factor *]) (lcsu :: LCSU *) (n :: *) -- | Make a quantity type capable of storing a value of a given unit. This -- uses a Double for storage of the value. For example: -- --
--   data LengthDim = LengthDim
--   instance Dimension LengthDim
--   data Meter = Meter
--   instance Unit Meter where
--     type BaseUnit Meter = Canonical
--     type DimOfUnit Meter = LengthDim
--   type instance DefaultUnitOfDim LengthDim = Meter
--   type Length = MkQu_D LengthDim
--   
-- -- Note that the dimension must have an instance for the type -- family DefaultUnitOfDim for this to work. type MkQu_D dim = Qu (DimFactorsOf dim) DefaultLCSU Double -- | Make a quantity type with a custom numerical type and LCSU. type MkQu_DLN dim = Qu (DimFactorsOf dim) -- | Make a quantity type with a given unit. It will be stored as a -- Double. Note that the corresponding dimension must have -- an appropriate instance for DefaultUnitOfDim for this to work. type MkQu_U unit = Qu (DimFactorsOf (DimOfUnit unit)) DefaultLCSU Double -- | Make a quantity type with a unit and LCSU with custom numerical type. -- The quantity will have the dimension corresponding to the unit. type MkQu_ULN unit = Qu (DimFactorsOf (DimOfUnit unit)) -- | This class is used to mark abstract dimensions, such as -- Length, or Mass. class Dimension dim where type family DimFactorsOf dim :: [Factor *] DimFactorsOf dim = '[F dim One] class DimOfUnitIsConsistent unit => Unit unit where type family BaseUnit unit :: * type family DimOfUnit unit :: * type family UnitFactorsOf unit :: [Factor *] DimOfUnit unit = DimOfUnit (BaseUnit unit) UnitFactorsOf unit = If (IsCanonical unit) '[F unit One] (UnitFactorsOf (BaseUnit unit)) conversionRatio _ = 1 canonicalConvRatio u = conversionRatio u * baseUnitRatio u -- | The conversion ratio from the base unit to this unit. If -- left out, a conversion ratio of 1 is assumed. -- -- For example: -- --
--   instance Unit Foot where
--     type BaseUnit Foot = Meter
--     conversionRatio _ = 0.3048
--   
-- -- Implementations should never examine their argument! conversionRatio :: Unit unit => unit -> Rational -- | Dummy type use just to label canonical units. It does not have -- a Unit instance. data Canonical -- | The dimension for the dimensionless quantities. It is also called -- "quantities of dimension one", but One is confusing with the -- type-level integer One. data Dimensionless Dimensionless :: Dimensionless -- | The unit for unitless dimensioned quantities data Number Number :: Number -- | The type of unitless dimensioned quantities. This is an instance of -- Num, though Haddock doesn't show it. This is parameterized by -- an LCSU and a number representation. type Count = MkQu_ULN Number -- | Convert a raw number into a unitless dimensioned quantity quantity :: n -> Qu '[] l n -- | Make a local consistent set of units. The argument is a type-level -- list of tuple types, to be interpreted as an association list from -- dimensions to units. For example: -- --
--   type MyLCSU = MkLCSU '[(Length, Foot), (Mass, Gram), (Time, Year)]
--   
data LCSU star DefaultLCSU :: LCSU star -- | Assign a default unit for a dimension. Necessary only when using -- default LCSUs. -- | Check if an LCSU has consistent entries for the given unit. i.e. can -- the lcsu describe the unit? -- | Check if an LCSU can express the given dimension -- | Like ConvertibleLCSUs, but takes a dimension, not a dimension -- factors. -- | Check if the DefaultLCSU can convert into the given one, at the -- given dimension. -- | Check if the DefaultLCSU can convert into the given one, at the -- given unit. -- | Extract a dimension specifier from a list of factors -- | Extract a unit specifier from a list of factors -- | Extract a unit from a dimension factor list and an LCSU -- | The datatype for type-level integers. data Z Zero :: Z S :: Z -> Z P :: Z -> Z -- | Add one to an integer -- | Subtract one from an integer -- | Add two integers -- | Subtract two integers -- | Multiply two integers -- | Divide two integers -- | Negate an integer type One = S Zero type Two = S One type Three = S Two type Four = S Three type Five = S Four type MOne = P Zero type MTwo = P MOne type MThree = P MTwo type MFour = P MThree type MFive = P MFour -- | This is the singleton value representing Zero at the term -- level and at the type level, simultaneously. Used for raising units to -- powers. sZero :: Sing Z Zero sOne :: Sing Z (S Zero) sTwo :: Sing Z (S (S Zero)) sThree :: Sing Z (S (S (S Zero))) sFour :: Sing Z (S (S (S (S Zero)))) sFive :: Sing Z (S (S (S (S (S Zero))))) sMOne :: Sing Z (P Zero) sMTwo :: Sing Z (P (P Zero)) sMThree :: Sing Z (P (P (P Zero))) sMFour :: Sing Z (P (P (P (P Zero)))) sMFive :: Sing Z (P (P (P (P (P Zero))))) -- | Add one to a singleton Z. sSucc :: Sing z -> Sing (Succ z) -- | Subtract one from a singleton Z. sPred :: Sing z -> Sing (Pred z) -- | Negate a singleton Z. sNegate :: Sing z -> Sing (Negate z) instance GHC.Enum.Bounded n => GHC.Enum.Bounded (Data.Metrology.Vector.Point n) instance GHC.Enum.Enum n => GHC.Enum.Enum (Data.Metrology.Vector.Point n) instance GHC.Classes.Eq n => GHC.Classes.Eq (Data.Metrology.Vector.Point n) instance GHC.Show.Show n => GHC.Show.Show (Data.Metrology.Vector.Point n) instance Data.AdditiveGroup.AdditiveGroup n => Data.AffineSpace.AffineSpace (Data.Metrology.Vector.Point n) -- | This module exports all the gubbins needed for type-checking your -- dimensioned quantities. See Metrology for some functions -- restricted to using a default LCSU, which is suitable for many -- applications. See also Vector for polymorphic functions -- suitable for use with the numerical classes from the -- vector-space package. module Data.Metrology.Poly -- | The number 0, polymorphic in its dimension. Use of this will often -- require a type annotation. zero :: Num n => Qu dimspec l n -- | Add two compatible quantities (|+|) :: (d1 @~ d2, Num n) => Qu d1 l n -> Qu d2 l n -> Qu d1 l n -- | Subtract two compatible quantities (|-|) :: (d1 @~ d2, Num n) => Qu d1 l n -> Qu d2 l n -> Qu d1 l n -- | Take the sum of a list of quantities qSum :: (Foldable f, Num n) => f (Qu d l n) -> Qu d l n -- | Negate a quantity qNegate :: Num n => Qu d l n -> Qu d l n -- | Multiply two quantities (|*|) :: Num n => Qu a l n -> Qu b l n -> Qu (Normalize (a @+ b)) l n -- | Divide two quantities (|/|) :: Fractional n => Qu a l n -> Qu b l n -> Qu (Normalize (a @- b)) l n -- | Multiply a quantity by a scalar from the left (*|) :: Num n => n -> Qu b l n -> Qu b l n -- | Multiply a quantity by a scalar from the right (|*) :: Num n => Qu a l n -> n -> Qu a l n -- | Divide a scalar by a quantity (/|) :: Fractional n => n -> Qu b l n -> Qu (Normalize ('[] @- b)) l n -- | Divide a quantity by a scalar (|/) :: Fractional n => Qu a l n -> n -> Qu a l n -- | Raise a quantity to a integer power, knowing at compile time that the -- integer is non-negative. (|^) :: (NonNegative z, Num n) => Qu a l n -> Sing z -> Qu (a @* z) l n -- | Raise a quantity to a integer power known at compile time (|^^) :: Fractional n => Qu a l n -> Sing z -> Qu (a @* z) l n -- | Take the n'th root of a quantity, where n is known at compile time qNthRoot :: ((Zero < z) ~ True, Floating n) => Sing z -> Qu a l n -> Qu (a @/ z) l n -- | Square a quantity qSq :: Num n => Qu a l n -> Qu (Normalize (a @+ a)) l n -- | Cube a quantity qCube :: Num n => Qu a l n -> Qu (Normalize (Normalize (a @+ a) @+ a)) l n -- | Take the square root of a quantity qSqrt :: Floating n => Qu a l n -> Qu (a @/ Two) l n -- | Take the cubic root of a quantity qCubeRoot :: Floating n => Qu a l n -> Qu (a @/ Three) l n -- | Compare two quantities qCompare :: (d1 @~ d2, Ord n) => Qu d1 l n -> Qu d2 l n -> Ordering -- | Check if one quantity is less than a compatible one (|<|) :: (d1 @~ d2, Ord n) => Qu d1 l n -> Qu d2 l n -> Bool -- | Check if one quantity is greater than a compatible one (|>|) :: (d1 @~ d2, Ord n) => Qu d1 l n -> Qu d2 l n -> Bool -- | Check if one quantity is less than or equal to a compatible one (|<=|) :: (d1 @~ d2, Ord n) => Qu d1 l n -> Qu d2 l n -> Bool -- | Check if one quantity is greater than or equal to a compatible one (|>=|) :: (d1 @~ d2, Ord n) => Qu d1 l n -> Qu d2 l n -> Bool -- | Check if two quantities are equal (uses the equality of the underlying -- numerical type) (|==|) :: (d1 @~ d2, Eq n) => Qu d1 l n -> Qu d2 l n -> Bool -- | Check if two quantities are not equal (|/=|) :: (d1 @~ d2, Eq n) => Qu d1 l n -> Qu d2 l n -> Bool -- | Compare two compatible quantities for approximate equality. If the -- difference between the left hand side and the right hand side -- arguments are less than or equal to the epsilon, they are -- considered equal. qApprox :: (d0 @~ d1, d0 @~ d2, Num n, Ord n) => Qu d0 l n -> Qu d1 l n -> Qu d2 l n -> Bool -- | Compare two compatible quantities for approixmate inequality. -- qNapprox e a b = not $ qApprox e a b qNapprox :: (d0 @~ d1, d0 @~ d2, Num n, Ord n) => Qu d0 l n -> Qu d1 l n -> Qu d2 l n -> Bool -- | Extracts a numerical value from a dimensioned quantity, expressed in -- the given unit. For example: -- --
--   inMeters :: Length -> Double
--   inMeters x = numIn x Meter
--   
-- -- or -- --
--   inMeters x = x # Meter
--   
numIn :: (ValidDLU dim lcsu unit, Fractional n) => Qu dim lcsu n -> unit -> n -- | Infix synonym for numIn (#) :: (ValidDLU dim lcsu unit, Fractional n) => Qu dim lcsu n -> unit -> n -- | Creates a dimensioned quantity in the given unit. For example: -- --
--   height :: Length
--   height = quOf 2.0 Meter
--   
-- -- or -- --
--   height = 2.0 % Meter
--   
quOf :: (ValidDLU dim lcsu unit, Fractional n) => n -> unit -> Qu dim lcsu n -- | Infix synonym for quOf (%) :: (ValidDLU dim lcsu unit, Fractional n) => n -> unit -> Qu dim lcsu n -- | Show a dimensioned quantity in a given unit. (The default -- Show instance always uses units as specified in the LCSU.) showIn :: (ValidDLU dim lcsu unit, Fractional n, Show unit, Show n) => Qu dim lcsu n -> unit -> String -- | The number 1, expressed as a unitless dimensioned quantity. unity :: Num n => Qu '[] l n -- | Cast between equivalent dimension within the same CSU. for example [kg -- m s] and [s m kg]. See the README for more info. redim :: (d @~ e) => Qu d l n -> Qu e l n -- | Dimension-keeping cast between different CSUs. convert :: (ConvertibleLCSUs d l1 l2, Fractional n) => Qu d l1 n -> Qu d l2 n -- | Use this to choose a default LCSU for a dimensioned quantity. The -- default LCSU uses the DefaultUnitOfDim representation for each -- dimension. defaultLCSU :: Qu dim DefaultLCSU n -> Qu dim DefaultLCSU n -- | Compute the argument in the DefaultLCSU, and present the -- result as lcsu-polymorphic dimension-polymorphic value. Named -- constant because one of its dominant usecase is to inject -- constant quantities into dimension-polymorphic expressions. constant :: (d @~ e, ConvertibleLCSUs e DefaultLCSU l, Fractional n) => Qu d DefaultLCSU n -> Qu e l n -- | Multiply two units to get another unit. For example: type -- MetersSquared = Meter :* Meter data (:*) u1 u2 (:*) :: u1 -> u2 -> (:*) u1 u2 -- | Divide two units to get another unit data (:/) u1 u2 (:/) :: u1 -> u2 -> (:/) u1 u2 -- | Raise a unit to a power, known at compile time data (:^) unit (power :: Z) (:^) :: unit -> Sing power -> (:^) unit -- | Multiply a conversion ratio by some constant. Used for defining -- prefixes. data (:@) prefix unit (:@) :: prefix -> unit -> (:@) prefix unit -- | A class for user-defined prefixes class UnitPrefix prefix -- | This should return the desired multiplier for the prefix being -- defined. This function must not inspect its argument. multiplier :: (UnitPrefix prefix, Fractional f) => prefix -> f -- | Multiply two quantity types to produce a new one. For example: -- --
--   type Velocity = Length %/ Time
--   
-- | Divide two quantity types to produce a new one -- | Exponentiate a quantity type to an integer -- | Qu adds a dimensional annotation to its numerical value type -- n. This is the representation for all quantities. data Qu (a :: [Factor *]) (lcsu :: LCSU *) (n :: *) -- | Make a quantity type capable of storing a value of a given unit. This -- uses a Double for storage of the value. For example: -- --
--   data LengthDim = LengthDim
--   instance Dimension LengthDim
--   data Meter = Meter
--   instance Unit Meter where
--     type BaseUnit Meter = Canonical
--     type DimOfUnit Meter = LengthDim
--   type instance DefaultUnitOfDim LengthDim = Meter
--   type Length = MkQu_D LengthDim
--   
-- -- Note that the dimension must have an instance for the type -- family DefaultUnitOfDim for this to work. type MkQu_D dim = Qu (DimFactorsOf dim) DefaultLCSU Double -- | Make a quantity type with a custom numerical type and LCSU. type MkQu_DLN dim = Qu (DimFactorsOf dim) -- | Make a quantity type with a given unit. It will be stored as a -- Double. Note that the corresponding dimension must have -- an appropriate instance for DefaultUnitOfDim for this to work. type MkQu_U unit = Qu (DimFactorsOf (DimOfUnit unit)) DefaultLCSU Double -- | Make a quantity type with a unit and LCSU with custom numerical type. -- The quantity will have the dimension corresponding to the unit. type MkQu_ULN unit = Qu (DimFactorsOf (DimOfUnit unit)) -- | This class is used to mark abstract dimensions, such as -- Length, or Mass. class Dimension dim where type family DimFactorsOf dim :: [Factor *] DimFactorsOf dim = '[F dim One] class DimOfUnitIsConsistent unit => Unit unit where type family BaseUnit unit :: * type family DimOfUnit unit :: * type family UnitFactorsOf unit :: [Factor *] DimOfUnit unit = DimOfUnit (BaseUnit unit) UnitFactorsOf unit = If (IsCanonical unit) '[F unit One] (UnitFactorsOf (BaseUnit unit)) conversionRatio _ = 1 canonicalConvRatio u = conversionRatio u * baseUnitRatio u -- | The conversion ratio from the base unit to this unit. If -- left out, a conversion ratio of 1 is assumed. -- -- For example: -- --
--   instance Unit Foot where
--     type BaseUnit Foot = Meter
--     conversionRatio _ = 0.3048
--   
-- -- Implementations should never examine their argument! conversionRatio :: Unit unit => unit -> Rational -- | Dummy type use just to label canonical units. It does not have -- a Unit instance. data Canonical -- | The dimension for the dimensionless quantities. It is also called -- "quantities of dimension one", but One is confusing with the -- type-level integer One. data Dimensionless Dimensionless :: Dimensionless -- | The unit for unitless dimensioned quantities data Number Number :: Number -- | The type of unitless dimensioned quantities. This is an instance of -- Num, though Haddock doesn't show it. This is parameterized by -- an LCSU and a number representation. type Count = MkQu_ULN Number -- | Convert a raw number into a unitless dimensioned quantity quantity :: n -> Qu '[] l n -- | Make a local consistent set of units. The argument is a type-level -- list of tuple types, to be interpreted as an association list from -- dimensions to units. For example: -- --
--   type MyLCSU = MkLCSU '[(Length, Foot), (Mass, Gram), (Time, Year)]
--   
data LCSU star DefaultLCSU :: LCSU star -- | Assign a default unit for a dimension. Necessary only when using -- default LCSUs. -- | Check if an LCSU has consistent entries for the given unit. i.e. can -- the lcsu describe the unit? -- | Check if an LCSU can express the given dimension -- | Like ConvertibleLCSUs, but takes a dimension, not a dimension -- factors. -- | Check if the DefaultLCSU can convert into the given one, at the -- given dimension. -- | Check if the DefaultLCSU can convert into the given one, at the -- given unit. -- | Extract a dimension specifier from a list of factors -- | Extract a unit specifier from a list of factors -- | Extract a unit from a dimension factor list and an LCSU -- | The datatype for type-level integers. data Z Zero :: Z S :: Z -> Z P :: Z -> Z -- | Add one to an integer -- | Subtract one from an integer -- | Add two integers -- | Subtract two integers -- | Multiply two integers -- | Divide two integers -- | Negate an integer type One = S Zero type Two = S One type Three = S Two type Four = S Three type Five = S Four type MOne = P Zero type MTwo = P MOne type MThree = P MTwo type MFour = P MThree type MFive = P MFour -- | This is the singleton value representing Zero at the term -- level and at the type level, simultaneously. Used for raising units to -- powers. sZero :: Sing Z Zero sOne :: Sing Z (S Zero) sTwo :: Sing Z (S (S Zero)) sThree :: Sing Z (S (S (S Zero))) sFour :: Sing Z (S (S (S (S Zero)))) sFive :: Sing Z (S (S (S (S (S Zero))))) sMOne :: Sing Z (P Zero) sMTwo :: Sing Z (P (P Zero)) sMThree :: Sing Z (P (P (P Zero))) sMFour :: Sing Z (P (P (P (P Zero)))) sMFive :: Sing Z (P (P (P (P (P Zero))))) -- | Add one to a singleton Z. sSucc :: Sing z -> Sing (Succ z) -- | Subtract one from a singleton Z. sPred :: Sing z -> Sing (Pred z) -- | Negate a singleton Z. sNegate :: Sing z -> Sing (Negate z) -- | Deprecated: The singleton prefix is changing from p to -- s. The p versions will be removed in a future -- release. pZero :: Sing Z Zero -- | Deprecated: The singleton prefix is changing from p to -- s. The p versions will be removed in a future -- release. pOne :: Sing Z (S Zero) -- | Deprecated: The singleton prefix is changing from p to -- s. The p versions will be removed in a future -- release. pTwo :: Sing Z (S (S Zero)) -- | Deprecated: The singleton prefix is changing from p to -- s. The p versions will be removed in a future -- release. pThree :: Sing Z (S (S (S Zero))) -- | Deprecated: The singleton prefix is changing from p to -- s. The p versions will be removed in a future -- release. pFour :: Sing Z (S (S (S (S Zero)))) -- | Deprecated: The singleton prefix is changing from p to -- s. The p versions will be removed in a future -- release. pFive :: Sing Z (S (S (S (S (S Zero))))) -- | Deprecated: The singleton prefix is changing from p to -- s. The p versions will be removed in a future -- release. pMOne :: Sing Z (P Zero) -- | Deprecated: The singleton prefix is changing from p to -- s. The p versions will be removed in a future -- release. pMTwo :: Sing Z (P (P Zero)) -- | Deprecated: The singleton prefix is changing from p to -- s. The p versions will be removed in a future -- release. pMThree :: Sing Z (P (P (P Zero))) -- | Deprecated: The singleton prefix is changing from p to -- s. The p versions will be removed in a future -- release. pMFour :: Sing Z (P (P (P (P Zero)))) -- | Deprecated: The singleton prefix is changing from p to -- s. The p versions will be removed in a future -- release. pMFive :: Sing Z (P (P (P (P (P Zero))))) -- | Deprecated: The singleton prefix is changing from p to -- s. The p versions will be removed in a future -- release. pSucc :: Sing Z z -> Sing Z (Succ z) -- | Deprecated: The singleton prefix is changing from p to -- s. The p versions will be removed in a future -- release. pPred :: Sing Z z -> Sing Z (Pred z) -- | This module exports Template Haskell functions to make working with -- units a little more convenient. module Data.Metrology.TH -- | Evaluates a type as far as it can. This is useful, say, in -- instance declarations: -- --
--   instance Show $(evalType [t| Length |]) where ...
--   
-- -- Without the evalType, the instance declaration fails because -- Length mentions type families, which can't be used in -- instance declarations. -- -- This function is somewhat experimental, and will likely not work with -- more polymorphic types. (If it doesn't work, not all of the type -- families will be evaluated, and the instance declaration will fail. -- This function should never cause incorrect behavior.) evalType :: Q Type -> Q Type -- | Declare a new dimension of the given name: -- --
--   $(declareDimension "Length")
--   
-- -- produces -- --
--   data Length = Length
--   instance Dimension Length
--   
declareDimension :: String -> Q [Dec] -- | declareCanonicalUnit unit_name dim (Just abbrev) creates a -- new canonical unit (that is, it is not defined in terms of other known -- units) named unit_name, measuring dimension dim. -- abbrev will be the abbreviation in the unit's Show -- instance. If no abbraviation is supplied, then no Show -- instance will be generated. -- -- Example usage: -- --
--   $(declareCanonicalUnit "Meter" [t| Length |] (Just "m"))
--   
declareCanonicalUnit :: String -> Q Type -> Maybe String -> Q [Dec] -- | declareDerivedUnit unit_name base_unit_type ratio (Just -- abbrev) creates a new derived unit, expressed in terms of -- base_unit_type. ratio says how many base units are -- in the derived unit. (Thus, if unit_name is -- Minute and base_unit_type is -- ''Second, then ratio would be 60.) -- abbrev, if supplied, becomes the string produced in the -- derived unit's Show instance. If no abbreviation is supplied, -- no Show instance is generated. -- -- Example usage: -- --
--   $(declareDerivedUnit "Minute" [t| Second |] 60 (Just "min"))
--   
declareDerivedUnit :: String -> Q Type -> Rational -> Maybe String -> Q [Dec] -- | declareMonoUnit unit_name (Just abbrev) creates a new derived -- unit, intended for use without unit polymorphism. The same type stands -- for both the unit and dimension, and the instance of -- DefaultUnitOfDim is set up accordingly. Use this function (with -- the Metrology imports) if you don't want to bother with LCSUs -- and just want to get to work. The abbrev, if supplied, -- creates an appropriate Show instance. -- --
--   $(declareMonoUnit "Meter" (Just "m"))
--   
-- -- produces all of the following -- --
--   data Meter = Meter
--   instance Dimension Meter
--   instance Unit Meter where
--     type BaseUnit Meter = Canonical
--     type DimOfUnit Meter = Meter
--   type instance DefaultUnitOfDim Meter = Meter
--   instance Show Meter where
--     show _ = "m"
--   
-- -- After a declaration like this, you probably want -- --
--   type Length = MkQu_U Meter
--   
-- -- This last line is not generated, as it is easy enough for you -- to write, and it involves a new name (Length). declareMonoUnit :: String -> Maybe String -> Q [Dec] -- | declareConstant const_name value unit_type creates a new -- numerical constant, named const_name. Its numerical value is -- value expressed in units given by unit_type. The -- constant is polymorphic in both its LCSU and numerical representation. -- For example, -- --
--   declareConstant "gravity_g" 9.80665 [t| Meter :/ Second :^ Two |]
--   
-- -- yields -- --
--   gravity_g :: ( Fractional n
--                , CompatibleUnit lcsu (Meter :/ Second :^ Two) )
--             => MkQu_ULN (Meter :/ Second :^ Two) lcsu n
--   gravity_g = 9.80665 % (undefined :: Meter :/ Second :^ Two)
--   
declareConstant :: String -> Rational -> Q Type -> Q [Dec] -- | Exports a class Quantity to allow easy conversion between -- proper quantities and types from other libraries. module Data.Metrology.Quantity -- | Quantity allows for easy conversions in and out of quantities. -- For example, say you are working with an outside library for time that -- defines UTCTime, where that stores the time measured in -- seconds. You could say -- --
--   instance Quantity UTCTime where
--     type QuantityUnit = Second
--     fromQuantity = ...
--     toQuantity = ...
--   
-- -- Then, conversions are easy and unit-safe. class Quantity t where type family QuantityUnit t :: * type family QuantityLCSU t :: LCSU * type family QuantityRep t :: * QuantityLCSU t = DefaultLCSU QuantityRep t = Double fromQuantity :: Quantity t => QuantityQu t -> t toQuantity :: Quantity t => t -> QuantityQu t -- | The Qu type associated with a member of the Quantity -- class type QuantityQu t = MkQu_ULN (QuantityUnit t) (QuantityLCSU t) (QuantityRep t) instance Data.Metrology.Validity.ValidDL d l => Data.Metrology.Quantity.Quantity (Data.Metrology.Qu.Qu d l n) -- | The units package is a framework for strongly-typed dimensional -- analysis. This haddock documentation is generally not enough to -- be able to use this package effectively. Please see the readme at -- https://github.com/goldfirere/units/blob/master/README.md. -- -- Some of the types below refer to declarations that are not exported -- and not documented here. This is because Haddock does not allow -- finely-tuned abstraction in documentation. (In particular, right-hand -- sides of type synonym declarations are always included.) If a symbol -- is not exported, you do not need to know anything about it to -- use this package. -- -- Though it doesn't appear here, Count is an instance of -- Num, and generally has all the numeric instances that -- Double has. -- -- This module exports definitions that lack unit-polymorphism. If you -- wish to write more polymorphic code, see Poly. If you wish to -- use the numerical hierarchy from the vector-space package, -- see Vector. module Data.Metrology -- | Extracts a numerical value from a dimensioned quantity, expressed in -- the given unit. For example: -- --
--   inMeters :: Length -> Double
--   inMeters x = numIn x Meter
--   
-- -- or -- --
--   inMeters x = x # Meter   
--   
numIn :: (ValidDLU dim DefaultLCSU unit, Fractional n) => Qu dim DefaultLCSU n -> unit -> n -- | Infix synonym for numIn (#) :: (ValidDLU dim DefaultLCSU unit, Fractional n) => Qu dim DefaultLCSU n -> unit -> n -- | Creates a dimensioned quantity in the given unit. For example: -- --
--   height :: Length
--   height = quOf 2.0 Meter
--   
-- -- or -- --
--   height = 2.0 % Meter
--   
quOf :: (ValidDLU dim DefaultLCSU unit, Fractional n) => n -> unit -> Qu dim DefaultLCSU n -- | Infix synonym for quOf (%) :: (ValidDLU dim DefaultLCSU unit, Fractional n) => n -> unit -> Qu dim DefaultLCSU n -- | The type of unitless dimensioned quantities. This is an instance of -- Num, though Haddock doesn't show it. This assumes a default -- LCSU and an internal representation of Double. type Count = MkQu_U Number -- | This module exports functions allowing users to create their own unit -- quasiquoters to make for compact unit expressions. -- -- A typical use case is this: -- --
--   $(makeQuasiQuoter "unit" [''Kilo, ''Milli] [''Meter, ''Second])
--   
-- -- and then, in a separate module (due to GHC's staging -- constraints) -- --
--   x = 3 % [unit| m/s^2 ]
--   
-- -- The unit expressions can refer to the prefixes and units specified in -- the call to makeQuasiQuoter. The spellings of the prefixes and -- units are taken from their Show instances. -- -- The syntax for these expressions is like F#'s. There are four -- arithmetic operators (*, /, ^, and -- juxtaposition). Exponentiation binds the tightest, and it allows an -- integer to its right (possibly with minus signs and parentheses). Next -- tightest is juxtaposition, which indicates multiplication. Because -- juxtaposition binds tighter than division, the expressions -- m/s^2 and m/s s are equivalent. Multiplication and -- division bind the loosest and are left-associative, meaning that -- m/s*s is equivalent to (m/s)*s, probably not what -- you meant. Parentheses in unit expressions are allowed, of course. -- -- Within a unit string (that is, a unit with an optional prefix), there -- may be ambiguity. If a unit string can be interpreted as a unit -- without a prefix, that parsing is preferred. Thus, min would -- be minutes, not milli-inches (assuming appropriate prefixes and units -- available.) There still may be ambiguity between unit strings, even -- interpreting the string as a prefix and a base unit. If a unit string -- is amiguous in this way, it is rejected. For example, if we have -- prefixes da and d and units m and -- am, then dam is ambiguous like this. module Data.Metrology.Parser -- | makeQuasiQuoter "qq" prefixes units makes a quasi-quoter -- named qq that considers the prefixes and units provided. -- These are provided via names of the type constructors, -- not the data constructors. See the module documentation for -- more info and an example. makeQuasiQuoter :: String -> [Name] -> [Name] -> Q [Dec] -- | Gets a list of the names of all units with Show instances in -- scope. Example usage: -- --
--   $( do units <- allUnits
--         makeQuasiQuoter "unit" [] units )
--   
allUnits :: Q [Name] -- | Gets a list of the names of all unit prefixes with Show -- instances in scope. Example usage: -- --
--   $( do units    <- allUnits
--         prefixes <- allPrefixes
--         makeQuasiQuoter "unit" prefixes units )
--   
allPrefixes :: Q [Name] -- | Parse a unit expression, interpreted with respect the given symbol -- table. Returns either an error message or the successfully-parsed unit -- expression. parseUnit :: (Show pre, Show u) => SymbolTable pre u -> String -> Either String (UnitExp pre u) -- | Parsed unit expressions, parameterized by a prefix identifier type and -- a unit identifier type data UnitExp pre u :: * -> * -> * -- | "1" Unity :: UnitExp pre u -- | a unit with, perhaps, a prefix Unit :: Maybe pre -> u -> UnitExp pre u Mult :: UnitExp pre u -> UnitExp pre u -> UnitExp pre u Div :: UnitExp pre u -> UnitExp pre u -> UnitExp pre u Pow :: UnitExp pre u -> Integer -> UnitExp pre u -- | A "symbol table" for the parser, mapping prefixes and units to their -- representations. data SymbolTable pre u :: * -> * -> * -- | Build a symbol table from prefix mappings and unit mappings. The -- prefix mapping can be empty. This function checks to make sure that -- the strings are not inherently ambiguous and are purely alphabetic. mkSymbolTable :: (Show pre, Show u) => [(String, pre)] -> [(String, u)] -> Either String (SymbolTable pre u)