packages feed

dimensional 1.4 → 1.5

raw patch · 17 files changed

+241/−131 lines, 17 filesdep −semigroupsdep ~basePVP ok

version bump matches the API change (PVP)

Dependencies removed: semigroups

Dependency ranges changed: base

API changes (from Hackage documentation)

+ Numeric.Units.Dimensional.NonSI: decade :: Num a => Unit 'NonMetric DTime a
+ Numeric.Units.Dimensional.NonSI: millennium :: Num a => Unit 'NonMetric DTime a

Files

CHANGELOG.md view
@@ -1,3 +1,14 @@+1.5 (2022-06)+-------------+* Add Julian `decade`, `century`, and `millennium` to `NonSI`.+* Rename `deka` prefix to `deca` in accordance with [international spelling](https://www.bipm.org/documents/20126/41483022/SI-Brochure-9.pdf/fcf090b2-04e6-88cc-1149-c3e029ad8232).+* Change `astronomicalUnit` symbol to lowercase (`au`).+* Remove `semigroups` dependency.+* Significant documentation improvements.++Thanks to @konsumlamm for many contributions!++ 1.4 (2021-05) ------------- * Add `calorie` to `NonSI`.@@ -135,7 +146,7 @@ *  Added [`tau`][3]. *  Added `KinematicViscosity`. -[3]: http://tauday.com/tau-manifesto+[3]: https://tauday.com/tau-manifesto   0.10.1.2 (2011-09)@@ -159,11 +170,11 @@ -------------- See the [announcement][2]. -[2]: http://flygdynamikern.blogspot.se/2011/05/announce-dimensional-010.html+[2]: https://flygdynamikern.blogspot.se/2011/05/announce-dimensional-010.html   0.9 (2011-04) ------------- See the [announcement][1]. -[1]: http://flygdynamikern.blogspot.se/2011/04/announce-dimensional-09.html+[1]: https://flygdynamikern.blogspot.se/2011/04/announce-dimensional-09.html
README.md view
@@ -5,8 +5,8 @@ Data kinds and closed type families provide a flexible, safe, and discoverable implementation that leads to largely self-documenting client code. -[![Build Status](https://travis-ci.org/bjornbm/dimensional.svg?branch=master)](https://travis-ci.org/bjornbm/dimensional)-[![Hackage Version](http://img.shields.io/hackage/v/dimensional.svg)](http://hackage.haskell.org/package/dimensional)+[![Build Status](https://api.travis-ci.com/bjornbm/dimensional.svg?branch=master)](https://app.travis-ci.com/github/bjornbm/dimensional)+[![Hackage Version](https://img.shields.io/hackage/v/dimensional.svg)](https://hackage.haskell.org/package/dimensional) [![Stackage version](https://www.stackage.org/package/dimensional/badge/lts?label=Stackage)](https://www.stackage.org/package/dimensional)  ## Usage
dimensional.cabal view
@@ -1,8 +1,8 @@ name:                dimensional-version:             1.4+version:             1.5 license:             BSD3 license-file:        LICENSE-copyright:           Bjorn Buckwalter 2006-2021+copyright:           Bjorn Buckwalter 2006-2022 author:              Bjorn Buckwalter maintainer:          bjorn@buckwalter.se stability:           experimental@@ -20,7 +20,7 @@     with physical quantities and units. Information about the physical     dimensions of the quantities and units is embedded in their types and the     validity of operations is verified by the type checker at compile time.-    The boxing and unboxing of numerical values as quantities is done by+    The wrapping and unwrapping of numerical values as quantities is done by     multiplication and division with units. The library is designed to, as     far as is practical, enforce/encourage best practices of unit usage. @@ -34,7 +34,8 @@ extra-source-files:  README.md,                      CHANGELOG.md,                      examples/ReadmeExample.hs,-                     examples/GM.lhs+                     examples/GM.lhs,+                     examples/NewtonianMechanics.hs  source-repository head   type:     git@@ -46,31 +47,30 @@                        exact-pi >= 0.4.1 && < 0.6,                        ieee754 >= 0.7.6,                        numtype-dk >= 0.5 && < 1.1,-                       vector >= 0.10,-                       semigroups+                       vector >= 0.10   hs-source-dirs:      src   default-language:    Haskell2010   default-extensions:  NoImplicitPrelude   if impl(ghc >= 8.6)     default-extensions: NoStarIsType   ghc-options:         -Wall-  exposed-modules:     Numeric.Units.Dimensional,-                       Numeric.Units.Dimensional.Coercion,-                       Numeric.Units.Dimensional.Dimensions,-                       Numeric.Units.Dimensional.Dimensions.TermLevel,-                       Numeric.Units.Dimensional.Dimensions.TypeLevel,-                       Numeric.Units.Dimensional.Dynamic,-                       Numeric.Units.Dimensional.FixedPoint,-                       Numeric.Units.Dimensional.Functor,-                       Numeric.Units.Dimensional.NonSI,-                       Numeric.Units.Dimensional.Prelude,-                       Numeric.Units.Dimensional.Quantities,-                       Numeric.Units.Dimensional.SIUnits,-                       Numeric.Units.Dimensional.UnitNames,-                       Numeric.Units.Dimensional.UnitNames.InterchangeNames,-                       Numeric.Units.Dimensional.Variants,+  exposed-modules:     Numeric.Units.Dimensional+                       Numeric.Units.Dimensional.Coercion+                       Numeric.Units.Dimensional.Dimensions+                       Numeric.Units.Dimensional.Dimensions.TermLevel+                       Numeric.Units.Dimensional.Dimensions.TypeLevel+                       Numeric.Units.Dimensional.Dynamic+                       Numeric.Units.Dimensional.FixedPoint+                       Numeric.Units.Dimensional.Functor+                       Numeric.Units.Dimensional.NonSI+                       Numeric.Units.Dimensional.Prelude+                       Numeric.Units.Dimensional.Quantities+                       Numeric.Units.Dimensional.SIUnits+                       Numeric.Units.Dimensional.UnitNames+                       Numeric.Units.Dimensional.UnitNames.InterchangeNames+                       Numeric.Units.Dimensional.Variants                        Numeric.Units.Dimensional.Float-  other-modules:       Numeric.Units.Dimensional.Internal,+  other-modules:       Numeric.Units.Dimensional.Internal                        Numeric.Units.Dimensional.UnitNames.Internal  test-suite tests@@ -88,7 +88,7 @@   build-depends:       dimensional,                        hspec,                        QuickCheck,-                       base < 5+                       base   build-tool-depends: hspec-discover:hspec-discover == 2.*  test-suite doctests
+ examples/NewtonianMechanics.hs view
@@ -0,0 +1,37 @@+{-# LANGUAGE NoImplicitPrelude #-}+module NewtonianMechanics where++import Numeric.Units.Dimensional.Prelude++translationalKineticEnergy :: (Fractional a) => Mass a -> Velocity a -> Energy a+translationalKineticEnergy m v = m * v ^ pos2 / _2++translationalWork :: (Num a) => Force a -> Length a -> Energy a+translationalWork f d = f * d++translationalMomentum :: (Num a) => Mass a -> Velocity a -> Momentum a+translationalMomentum m v = m * v++translationalPower :: (Num a) => Force a -> Velocity a -> Power a+translationalPower f v = f * v++forceFromChangeInMomentum :: (Fractional a) => Momentum a -> Time a -> Force a+forceFromChangeInMomentum dp dt = dp / dt++rotationalKineticEnergy :: (Fractional a) => MomentOfInertia a -> AngularVelocity a -> Energy a+rotationalKineticEnergy i w = i * w ^ pos2 / _2++rotationalWork :: (Num a) => Torque a -> PlaneAngle a -> Energy a+rotationalWork t th = t * th++rotationalMomentum :: (Num a) => MomentOfInertia a -> AngularVelocity a -> AngularMomentum a+rotationalMomentum i w = i * w++rotationalPower :: (Num a) => Torque a -> AngularVelocity a -> Power a+rotationalPower t w = t * w++torque :: (Num a) => Force a -> Length a -> Torque a+torque r f = r * f++torqueFromChangeInMomentum :: (Fractional a) => AngularMomentum a -> Time a -> Torque a+torqueFromChangeInMomentum dL dt = dL / dt
src/Numeric/Units/Dimensional.hs view
@@ -31,7 +31,7 @@ physical quantities and units. Information about the physical dimensions of the quantities/units is embedded in their types and the validity of operations is verified by the type checker at compile-time. The boxing and unboxing of numerical values as quantities is+time. The wrapping and unwrapping of numerical values as quantities is done by multiplication and division of units, of which an incomplete set is provided. @@ -47,7 +47,7 @@ == Disclaimer  Merely an engineer, the author doubtlessly uses a language and-notation that makes mathematicians and physicist cringe. He does+notation that makes mathematicians and physicists cringe. He does not mind constructive criticism (or pull requests).  The sets of functions and units defined herein are incomplete and@@ -61,7 +61,7 @@ Closed Type Families, etc. Clients of the module are generally not required to use these extensions. -Clients probably will want to use the NegativeLiterals extension.+Clients probably will want to use the @NegativeLiterals@ extension though.  == Examples @@ -69,23 +69,23 @@ work with physical quantities. A physical quantity is defined by multiplying a number with a unit (the type signature is optional). -> v :: Velocity Prelude.Double+> v :: Velocity Double > v = 90 *~ (kilo meter / hour)  It follows naturally that the numerical value of a quantity is obtained by division by a unit. -> numval :: Prelude.Double+> numval :: Double > numval = v /~ (meter / second)  The notion of a quantity as the product of a numerical value and a unit is supported by 7.1 "Value and numerical value of a quantity" of-<#note1 [1]>. While the above syntax is fairly natural it is unfortunate that+<#note1 [1]>. While the above syntax is fairly natural, it is unfortunate that it must violate a number of the guidelines in <#note1 [1]>, in particular 9.3 "Spelling unit names with prefixes", 9.4 "Spelling unit names obtained by multiplication", 9.5 "Spelling unit names obtained by division". -As a more elaborate example of how to use the module we define a+As a more elaborate example of how to use the module, we define a function for calculating the escape velocity of a celestial body <#note2 [2]>. @@ -95,9 +95,9 @@ >       two = 2 *~ one >       g = 6.6720e-11 *~ (newton * meter ^ pos2 / kilo gram ^ pos2) -For completeness we should also show an example of the error messages+For completeness, we should also show an example of the error messages we will get from GHC when performing invalid arithmetic. In the-best case GHC will be able to use the type synonyms we have defined+best case, GHC will be able to use the type synonyms we have defined in its error messages.  > let x = 1 *~ meter + 1 *~ second@@ -109,7 +109,7 @@ > In the second argument of `(*~)', namely `second' > In the second argument of `(+)', namely `1 *~ second' -In other cases the error messages aren't very friendly.+In other cases, the error messages aren't very friendly.  > let x = 1 *~ meter / (1 *~ second) + 1 *~ kilo gram >@@ -139,7 +139,7 @@  == Related work -Henning Thielemann numeric prelude has a physical units library,+Henning Thielemann's numeric prelude has a physical units library, however, checking of dimensions is dynamic rather than static. Aaron Denney has created a toy example of statically checked physical dimensions covering only length and time. HaskellWiki@@ -155,13 +155,13 @@  == References -1. #note1# http://physics.nist.gov/Pubs/SP811/-2. #note2# http://en.wikipedia.org/wiki/Escape_velocity-3. #note3# http://jscience.org/api/org/jscience/physics/models/package-summary.html-4. #note4# http://www.haskell.org/haskellwiki/Physical_units-5. #note5# http://liftm.wordpress.com/2007/06/03/scientificdimension-type-arithmetic-and-physical-units-in-haskell/+1. #note1# https://www.nist.gov/pml/special-publication-811+2. #note2# https://en.wikipedia.org/wiki/Escape_velocity+3. #note3# https://web.archive.org/web/20080905151927/http://jscience.org/api/org/jscience/physics/models/package-summary.html+4. #note4# https://wiki.haskell.org/Physical_units+5. #note5# https://liftm.wordpress.com/2007/06/03/scientificdimension-type-arithmetic-and-physical-units-in-haskell/ 6. #note6# http://jscience.org/-7. #note7# http://research.sun.com/projects/plrg/fortress.pdf+6. #note6# https://github.com/stokito/fortress-lang  -} @@ -316,12 +316,12 @@ infixl 7  *~, /~  {- $dimensions-The phantom type variable d encompasses the physical dimension of-a 'Dimensional'. As detailed in <#note5 [5]> there are seven base dimensions,+The phantom type variable @d@ encompasses the physical dimension of+a 'Dimensional'. As detailed in <#note5 [5]>, there are seven base dimensions, which can be combined in integer powers to a given physical dimension. We represent physical dimensions as the powers of the seven base dimensions that make up the given dimension. The powers are represented-using NumTypes. For convenience we collect all seven base dimensions+using NumTypes. For convenience, we collect all seven base dimensions in a data kind 'Dimension'.  We could have chosen to provide type variables for the seven base@@ -357,7 +357,7 @@ type LuminousIntensity        = Quantity DLuminousIntensity  {- $dimension-arithmetic-When performing arithmetic on units and quantities the arithmetics+When performing arithmetic on units and quantities, the arithmetics must be applied to both the numerical values of the Dimensionals but also to their physical dimensions. The type level arithmetic on physical dimensions is governed by closed type families expressed@@ -391,7 +391,7 @@ -- | Divides one 'Quantity' by another or one 'Unit' by another. -- -- The intimidating type signature captures the similarity between these operations--- and ensures that composite 'Unit's are 'NotPrefixable'.+-- and ensures that composite 'Unit's are 'NonMetric'. (/) :: (KnownVariant v1, KnownVariant v2, KnownVariant (v1 V./ v2), Fractional a) => Dimensional v1 d1 a -> Dimensional v2 d2 a -> Dimensional (v1 V./ v2) (d1 / d2) a (/) = liftD2 (Prelude./) (Prelude./) (Name./) @@ -410,7 +410,7 @@ -- also reexported by "Numeric.Units.Dimensional.Prelude". -- -- The intimidating type signature captures the similarity between these operations--- and ensures that composite 'Unit's are 'NotPrefixable'.+-- and ensures that composite 'Unit's are 'NonMetric'. (^) :: (Fractional a, KnownTypeInt i, KnownVariant v, KnownVariant (Weaken v))     => Dimensional v d1 a -> Proxy i -> Dimensional (Weaken v) (d1 ^ i) a x ^ n = let n' = (toNum n) :: Int@@ -517,7 +517,7 @@ (^/) = flip nroot  {- $collections-Here we define operators and functions to make working with homogenuous+Here we define operators and functions to make working with homogeneous lists of dimensionals more convenient.  We define two convenience operators for applying units to all@@ -655,9 +655,9 @@ -- | The unit 'one' has dimension 'DOne' and is the base unit of dimensionless values. -- -- As detailed in 7.10 "Values of quantities expressed simply as numbers:--- the unit one, symbol 1" of <#note1 [1]> the unit one generally does not+-- the unit one, symbol 1" of <#note1 [1]>, the unit one generally does not -- appear in expressions. However, for us it is necessary to use 'one'--- as we would any other unit to perform the "boxing" of dimensionless values.+-- as we would any other unit to perform the "wrapping" of dimensionless values. one :: Num a => Unit 'NonMetric DOne a one = Unit nOne 1 1 @@ -690,8 +690,8 @@  -- | Twice 'pi'. ----- For background on 'tau' see http://tauday.com/tau-manifesto (but also--- feel free to review http://www.thepimanifesto.com).+-- For background on 'tau' see https://tauday.com/tau-manifesto (but also+-- feel free to review https://web.archive.org/web/20200926221249/http://www.thepimanifesto.com/). tau :: Floating a => Dimensionless a tau = _2 * pi 
src/Numeric/Units/Dimensional/Dimensions/TermLevel.hs view
@@ -64,7 +64,7 @@ -- | The monoid of dimensions under multiplication. instance Monoid Dimension' where   mempty = dOne-  mappend = (Data.Semigroup.<>)+  mappend = (<>)  -- | The dimension of a dynamic value, which may not have any dimension at all. data DynamicDimension = NoDimension -- ^ The value has no valid dimension.@@ -77,7 +77,7 @@ -- | Dimensional values, or those that are only possibly dimensional, inhabit this class, -- which allows access to a term-level representation of their dimension. class HasDynamicDimension a where-  -- | Gets the 'DynamicDimension of a dynamic dimensional value, which may be 'NoDimension' if it does not represent+  -- | Gets the 'DynamicDimension' of a dynamic dimensional value, which may be 'NoDimension' if it does not represent   -- a dimensional value of any 'Dimension'.   --   -- A default implementation is available for types that are also in the `HasDimension` typeclass.@@ -187,6 +187,9 @@ asList :: Dimension' -> [Int] asList (Dim' l m t i th n j) = [l, m, t, i, th, n, j] +-- | Converts a list of integers, representing the exponent associated with each+-- of the 7 SI base dimensions in the standard order, to a dimension.+-- Returns 'Nothing' if the list doesn't contain exactly 7 elements. fromList :: [Int] -> Maybe Dimension' fromList [l, m, t, i, th, n, j] = Just $ Dim' l m t i th n j fromList _ = Nothing
src/Numeric/Units/Dimensional/Dimensions/TypeLevel.hs view
@@ -78,9 +78,9 @@ infixr 8  ^ infixl 7  *, / --- | Multiplication of dimensions corresponds to adding of the base+-- | Multiplication of dimensions corresponds to addition of the base -- dimensions' exponents.-type family (a::Dimension) * (b::Dimension) where+type family (a :: Dimension) * (b :: Dimension) where   DOne * d = d   d * DOne = d   ('Dim l  m  t  i  th  n  j) * ('Dim l' m' t' i' th' n' j')@@ -88,7 +88,7 @@  -- | Division of dimensions corresponds to subtraction of the base -- dimensions' exponents.-type family (a::Dimension) / (d::Dimension) where+type family (a :: Dimension) / (d :: Dimension) where   d / DOne = d   d / d = DOne   ('Dim l  m  t  i  th  n  j) / ('Dim l' m' t' i' th' n' j')@@ -98,21 +98,21 @@ -- or of negating each of the base dimensions' exponents. type Recip (d :: Dimension) = DOne / d --- | Powers of dimensions corresponds to multiplication of the base+-- | Powers of dimensions correspond to multiplication of the base -- dimensions' exponents by the exponent. -- -- We limit ourselves to integer powers of Dimensionals as fractional -- powers make little physical sense.-type family (d::Dimension) ^ (x::TypeInt) where+type family (d :: Dimension) ^ (x :: TypeInt) where   DOne ^ x = DOne   d ^ 'Zero = DOne   d ^ 'Pos1 = d   ('Dim l  m  t  i  th  n  j) ^ x     = 'Dim (l N.* x) (m N.* x) (t N.* x) (i N.* x) (th N.* x) (n N.* x) (j N.* x) --- | Roots of dimensions corresponds to division of the base dimensions'+-- | Roots of dimensions correspond to division of the base dimensions' -- exponents by the order of the root.-type family NRoot (d::Dimension) (x::TypeInt) where+type family NRoot (d :: Dimension) (x :: TypeInt) where   NRoot DOne x = DOne   NRoot d 'Pos1 = d   NRoot ('Dim l  m  t  i  th  n  j) x@@ -128,7 +128,7 @@ -- Each validly constructed type of kind 'Dimension' has a 'KnownDimension' instance. -- -- While 'KnownDimension' is a constraint synonym, the presence of @'KnownDimension' d@ in---  a context allows use of @'dimension' :: 'Proxy' d -> 'Dimension''@.+-- a context allows use of @'dimension' :: 'Proxy' d -> 'Dimension''@. type KnownDimension (d :: Dimension) = HasDimension (Proxy d)  instance ( KnownTypeInt l
src/Numeric/Units/Dimensional/Dynamic.hs view
@@ -113,7 +113,7 @@ -- they may not be added together if their dimensions do not match. instance Num a => Monoid (AnyQuantity a) where   mempty = demoteQuantity (1 Dim.*~ one)-  mappend = (Data.Semigroup.<>)+  mappend = (<>)  -- | Possibly a 'Quantity' whose 'Dimension' is only known dynamically. --@@ -192,7 +192,7 @@ -- they may not be added together if their dimensions do not match. instance Num a => Monoid (DynQuantity a) where   mempty = demoteQuantity (1 Dim.*~ one)-  mappend = (Data.Semigroup.<>)+  mappend = (<>)  -- | A 'DynQuantity' which does not correspond to a value of any dimension. invalidQuantity :: DynQuantity a@@ -210,11 +210,11 @@ polydimensionalZero :: (Num a) => DynQuantity a polydimensionalZero = DynQuantity AnyDimension 0 --- Lifts a function which is only valid on dimensionless quantities into a function on DynQuantitys.+-- | Lifts a function which is only valid on dimensionless quantities into a function on 'DynQuantity's. liftDimensionless :: (a -> a) -> DynQuantity a -> DynQuantity a liftDimensionless = liftDQ (matchDimensions $ SomeDimension D.dOne) --- Lifts a function on values into a function on DynQuantitys.+-- | Lifts a function on values into a function on 'DynQuantity's. liftDQ :: (DynamicDimension -> DynamicDimension) -- ^ How the function operates on dimensions.        -> (a -> a) -- ^ How the function operates on values.        -> DynQuantity a -> DynQuantity a@@ -222,7 +222,7 @@                                    NoDimension -> invalidQuantity                                    d' -> DynQuantity d' $ fv v --- Lifts a function on values into a function on DynQuantitys.+-- | Lifts a function on values into a function on 'DynQuantity's. -- -- This works by treating polydimensional zeros as dimensionless zeros. If that is not the desired behavior, -- handle polydimensional zeros first and then call this function.@@ -233,7 +233,7 @@                                                           NoDimension -> invalidQuantity                                                           d' -> DynQuantity d' $ fv v1 v2 --- Transforms a dynamic dimension in a way which is always valid+-- | Transforms a dynamic dimension in a way which is always valid. valid :: (Dimension' -> Dimension') -> DynamicDimension -> DynamicDimension valid _ AnyDimension      = AnyDimension valid f (SomeDimension d) = SomeDimension (f d)@@ -249,7 +249,7 @@ constant d (SomeDimension _) = SomeDimension d constant _ _ = NoDimension --- Transforms two dynamic dimensions in a way which is always valid+-- | Transforms two dynamic dimensions in a way which is always valid. valid2 :: (Dimension' -> Dimension' -> Dimension') -> DynamicDimension -> DynamicDimension -> DynamicDimension valid2 _ AnyDimension       (SomeDimension _)  = AnyDimension valid2 _ (SomeDimension _)  AnyDimension       = AnyDimension@@ -282,8 +282,9 @@ -- | 'AnyUnit's form a 'Monoid' under multiplication. instance Monoid AnyUnit where   mempty = demoteUnit' one-  mappend = (Data.Semigroup.<>)+  mappend = (<>) +-- | Extracts the 'UnitName' of an 'AnyUnit'. anyUnitName :: AnyUnit -> UnitName 'NonMetric anyUnitName (AnyUnit _ n _) = n 
src/Numeric/Units/Dimensional/FixedPoint.hs view
@@ -123,7 +123,7 @@ xs *~~ u = fmap (*~ u) 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+(/~~) :: (Functor f, Real a, Fractional b, E.MinCtxt s b) => f (SQuantity s d a) -> Unit m d b -> f b xs /~~ u = fmap (/~ u) xs  -- | The sum of all elements in a list.@@ -181,11 +181,11 @@ 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 _ y x = (*~ siUnit) $ (P.atan2 :: b -> b -> b) (y /~ siUnit) (x /~ siUnit) --- | Lift a function on dimensionless values of a specified intermediate type to operate on possibly scaled dimensionless.+-- | 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 f _ = (*~ siUnit) . (f :: b -> b) . (/~ siUnit) --- | Lift a periodic function on dimensionless values of a specified intermediate type to operate on possibly scaled dimensionless.+-- | 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.@@ -342,12 +342,12 @@  -- | Twice 'pi'. ----- For background on 'tau' see http://tauday.com/tau-manifesto (but also--- feel free to review http://www.thepimanifesto.com).+-- For background on 'tau' see https://tauday.com/tau-manifesto (but also+-- feel free to review https://web.archive.org/web/20200926221249/http://www.thepimanifesto.com/). tau :: (Integral a, E.KnownExactPi s) => SQuantity s DOne a tau = rescale (epsilon :: SQuantity (E.ExactNatural 2 E.* E.Pi) DOne Integer) --- | The least positive representable value in a given fixed-point scaled quantity type.+-- | The smallest positive representable value in a given fixed-point scaled quantity type. epsilon :: (Integral a) => SQuantity s d a epsilon = Quantity 1 
src/Numeric/Units/Dimensional/Float.hs view
@@ -8,8 +8,8 @@ Defines convenience functions for inspecting and manipulating quantities with 'RealFloat' floating-point representations. -The dimensionally-typed versions of functions from Patrick Perry's @ieee754@ package-copy that package's API as closely as possible, by permission. In turn they are based on+The dimensionally-typed versions of functions from Patrick Perry's [ieee754](https://hackage.haskell.org/package/ieee754) package+copy that packages API as closely as possible, by permission. In turn they are based on the @tango@ math library for the D language.  -}
src/Numeric/Units/Dimensional/Internal.hs view
@@ -135,7 +135,7 @@ -- | 'Quantity's of a given 'Dimension' form a 'Monoid' under addition. instance (Num a) => Monoid (SQuantity s d a) where   mempty = Quantity 0-  mappend = liftQ2 (+)+  mappend = (<>)  {- @@ -163,9 +163,9 @@ instance NFData a => NFData (Quantity d a) -- instance is derived from Generic instance  instance Storable a => Storable (SQuantity s d a) where-  sizeOf _ = sizeOf (undefined::a)+  sizeOf _ = sizeOf (undefined :: a)   {-# INLINE sizeOf #-}-  alignment _ = alignment (undefined::a)+  alignment _ = alignment (undefined :: a)   {-# INLINE alignment #-}   poke ptr = poke (castPtr ptr :: Ptr a) . coerce   {-# INLINE poke #-}
src/Numeric/Units/Dimensional/NonSI.hs view
@@ -27,10 +27,10 @@  = References -1. #note1# http://physics.nist.gov/Pubs/SP811/-2. #note2# http://www.iau.org/science/publications/proceedings_rules/units/-3. #note3# http://en.m.wikipedia.org/wiki/Pressure-4. #note4# http://en.m.wikipedia.org/wiki/Torr+1. #note1# https://www.nist.gov/pml/special-publication-811+2. #note2# https://www.iau.org/publications/proceedings_rules/units/+3. #note3# https://en.wikipedia.org/wiki/Pressure+4. #note4# https://en.wikipedia.org/wiki/Torr  -} @@ -56,7 +56,7 @@   usSurveyFoot, usSurveyInch, usSurveyMil, usSurveyYard, usSurveyMile, usSurveyAcre,   -- * Years   -- $year-  year, century,+  year, decade, century, millennium,   -- * Pressure Units   -- $pressure-units   bar, atmosphere, technicalAtmosphere, mmHg, inHg, inHg_UCUM, inHg_NIST, torr,@@ -99,7 +99,7 @@ From Table 7, units accepted for use with the SI whose values in SI units are obtained experimentally. -When <#note1 [1]> was published the electron volt had a standard combined+When <#note1 [1]> was published, the electron volt had a standard combined uncertainity of 0.00000049e-19 J and the unified atomic mass unit had a combined uncertainty of 0.0000010e-27 kg. @@ -119,7 +119,7 @@  -- | One percent is one hundrendth. ----- The dimensionless number 0.01 , represented by the symbol %, is commonly used as a dimensionless unit.+-- The dimensionless number 0.01, represented by the symbol %, is commonly used as a dimensionless unit. -- -- See section 7.10.2 of the <#note1 [1]> for further information. --@@ -468,7 +468,7 @@ knot :: (Fractional a) => Unit 'NonMetric DVelocity a knot = mkUnitQ (ucum "[kt_i]" "kt" "knot") 1 $ nauticalMile / hour --- | One revolution is an angle equal to 2 pi radians; a full circle.+-- | One revolution is an angle equal to 2*pi radians; a full circle. -- -- See <https://en.wikipedia.org/wiki/Turn_%28geometry%29 here> for further information. --@@ -510,15 +510,17 @@ The IAU recommends <#note2 [2]> that:    Although there are several different kinds of year (as there are-  several kinds of day), it is best to regard a year as a julian-  year of 365.25 days (31.5576 Ms) unless otherwise specified.+  several kinds of day), it is best to regard a year as a Julian+  year of 365.25 days (31557600 s) unless otherwise specified.  -} --- | One mean Julian year is a unit of measurement of time defined as exactly 365.25 days of 86 400 'second's each.+-- | One Julian year is a unit of measurement of time defined as exactly 365.25 days of 86 400 'second's each. -- -- See <https://en.wikipedia.org/wiki/Julian_year_%28astronomy%29 here> for further information. --+-- prop> 1 *~ year === 365.25 *~ day+-- -- >>> 1 *~ year -- 3.15576e7 s --@@ -527,8 +529,24 @@ year :: Num a => Unit 'NonMetric DTime a year = mkUnitZ (ucum "a_j" "a" "mean Julian year") 31557600 $ second --- | One mean Julian century is one hundred mean Julian 'year's.+-- | One Julian decade is ten Julian 'year's. --+-- prop> 1 *~ decade === 10 *~ year+--+-- >>> 1 *~ decade+-- 3.15576e8 s+--+-- >>> 1 *~ decade :: Time Rational+-- 315576000 % 1 s+decade :: Num a => Unit 'NonMetric DTime a+decade = mkUnitZ (dimensionalAtom "d_j" "dec" "mean Julian decade") 10 $ year++-- | One Julian century is one hundred Julian 'year's, or 35 525 'day's of 86 400 'second's each.+--+-- prop> 1 *~ century === 100 *~ year+--+-- prop> 1 *~ century === 36525 *~ day+-- -- >>> 1 *~ century -- 3.15576e9 s --@@ -537,6 +555,18 @@ century :: Num a => Unit 'NonMetric DTime a century = mkUnitZ (dimensionalAtom "c_j" "cen" "mean Julian century") 100 $ year +-- | One Julian millennium is one thousand Julian 'year's.+--+-- prop> 1 *~ millennium === 1000 *~ year+--+-- >>> 1 *~ millennium+-- 3.15576e10 s+--+-- >>> 1 *~ millennium :: Time Rational+-- 31557600000 % 1 s+millennium :: Num a => Unit 'NonMetric DTime a+millennium = mkUnitZ (dimensionalAtom "m_j" "mil" "mean Julian millennium") 1000 $ year+ {- $pressure-units It seems that nearly every area of application has its own customary unit for measuring pressure. We include some of the common ones here. 'psi' was defined earlier.@@ -726,7 +756,7 @@ degreeRankine = mkUnitQ (ucum "[degR]" "°R" "degree Rankine") 1 $ degreeFahrenheit  {- $imperial-volumes-Per http://en.wikipedia.org/wiki/Imperial_units and http://en.wikipedia.org/wiki/Cup_(unit)#Imperial_cup.+Per https://en.wikipedia.org/wiki/Imperial_units and https://en.wikipedia.org/wiki/Cup_(unit)#Imperial_cup. -}  -- | One imperial gallon is defined exactly in terms of the 'liter'@@ -806,7 +836,7 @@ imperialFluidOunce = mkUnitQ (ucum "[foz_br]" "fl oz" "fluid ounce") (1 Prelude./ 20) $ imperialPint  {- $us-customary-volumes-Per http://www.nist.gov/pml/wmd/pubs/upload/2012-hb44-final.pdf page 452 and http://en.wikipedia.org/wiki/United_States_customary_units#Fluid_volume+Per https://www.nist.gov/system/files/documents/2017/05/09/2012-hb44-final.pdf page 452 and https://en.wikipedia.org/wiki/United_States_customary_units#Fluid_volume Note that there exist rarely-used "dry" variants of units with overlapping names. -} 
src/Numeric/Units/Dimensional/Quantities.hs view
@@ -20,11 +20,11 @@ for the dimensionality is defined first in terms of base dimension exponents. Then a type synonym for the corresponding quantity type is defined. If there are several quantity types with the same-dimensionality type synonyms are provided for each quantity type.+dimensionality, type synonyms are provided for each quantity type.  = References -1. #note1# http://physics.nist.gov/Pubs/SP811/+1. #note1# https://www.nist.gov/pml/special-publication-811  -} @@ -373,7 +373,7 @@  {- -Thermal conductance and resistance quantities after http://en.wikipedia.org/wiki/Thermal_conductivity#Definitions.+Thermal conductance and resistance quantities after https://en.wikipedia.org/wiki/Thermal_conductivity#Definitions.  -} 
src/Numeric/Units/Dimensional/SIUnits.hs view
@@ -18,9 +18,9 @@  = References -1. #note1# http://physics.nist.gov/Pubs/SP811/-2. #note2# http://en.wikipedia.org/wiki/Minute_of_arc-3. #note3# http://en.wikipedia.org/wiki/Astronomical_unit+1. #note1# https://www.nist.gov/pml/special-publication-811+2. #note2# https://en.wikipedia.org/wiki/Minute_of_arc+3. #note3# https://en.wikipedia.org/wiki/Astronomical_unit  -} @@ -73,9 +73,7 @@  {- $multiples Prefixes are used to form decimal multiples and submultiples of SI-Units as described in section 4.4. We will define the SI prefixes-in terms of the 'prefix' function which applies a scale factor to a-unit.+Units as described in section 4.4.  By defining SI prefixes as functions applied to a 'Unit' we satisfy section 6.2.6 "Unacceptability of stand-alone prefixes".@@ -90,24 +88,36 @@     n' = N.applyPrefix p (name u)     x = N.scaleFactor p -deka, deca, hecto, kilo, mega, giga, tera, peta, exa, zetta, yotta+deca, deka, hecto, kilo, mega, giga, tera, peta, exa, zetta, yotta   :: Num a => Unit 'Metric d a -> Unit 'NonMetric d a-deka  = applyMultiple I.deka -- International English.-deca  = deka      -- American English.+-- | The "deca" prefix, denoting a factor of 10.+deca  = applyMultiple I.deca -- International English.+-- | An alias for 'deca'.+deka  = deca      -- American English.+-- | The "hecto" prefix, denoting a factor of 100. hecto = applyMultiple I.hecto+-- | The "kilo" prefix, denoting a factor of 1000. kilo  = applyMultiple I.kilo+-- | The "mega" prefix, denoting a factor of 10^6. mega  = applyMultiple I.mega+-- | The "giga" prefix, denoting a factor of 10^9. giga  = applyMultiple I.giga+-- | The "tera" prefix, denoting a factor of 10^12. tera  = applyMultiple I.tera+-- | The "peta" prefix, denoting a factor of 10^15. peta  = applyMultiple I.peta+-- | The "exa" prefix, denoting a factor of 10^18. exa   = applyMultiple I.exa+-- | The "zetta" prefix, denoting a factor of 10^21. zetta = applyMultiple I.zetta+-- | The "yotta" prefix, denoting a factor of 10^24. yotta = applyMultiple I.yotta  {- $submultiples Then the submultiples. -} +-- | Apply a 'Prefix' to a metric 'Unit'. applyPrefix :: (Fractional a) => Prefix -> Unit 'Metric d a -> Unit 'NonMetric d a applyPrefix p u = mkUnitQ n' x u   where@@ -116,15 +126,25 @@  deci, centi, milli, micro, nano, pico, femto, atto, zepto, yocto   :: Fractional a => Unit 'Metric d a -> Unit 'NonMetric d a+-- | The "deci" prefix, denoting a factor of 0.1. deci  = applyPrefix I.deci+-- | The "centi" prefix, denoting a factor of 0.01. centi = applyPrefix I.centi+-- | The "milli" prefix, denoting a factor of 0.001. milli = applyPrefix I.milli+-- | The "micro" prefix, denoting a factor of 10^-6. micro = applyPrefix I.micro+-- | The "nano" prefix, denoting a factor of 10^-9. nano  = applyPrefix I.nano+-- | The "pico" prefix, denoting a factor of 10^-12. pico  = applyPrefix I.pico+-- | The "femto" prefix, denoting a factor of 10^-15. femto = applyPrefix I.femto+-- | The "atto" prefix, denoting a factor of 10^-18. atto  = applyPrefix I.atto+-- | The "zepto" prefix, denoting a factor of 10^-21. zepto = applyPrefix I.zepto+-- | The "yocto" prefix, denoting a factor of 10^-24. yocto = applyPrefix I.yocto  {- $reified-prefixes@@ -137,7 +157,7 @@ {- $base-units These are the base units from section 4.1. To avoid a myriad of one-letter functions that would doubtlessly cause clashes-and frustration in users' code we spell out all unit names in full,+and frustration in users' code, we spell out all unit names in full, as we did for prefixes. We also elect to spell the unit names in singular form, as allowed by section 9.7 "Other spelling conventions". @@ -311,4 +331,4 @@ -}  astronomicalUnit :: Num a => Unit 'NonMetric DLength a-astronomicalUnit = mkUnitZ (ucum "AU" "AU" "astronomical unit") 149597870700 $ meter+astronomicalUnit = mkUnitZ (ucum "au" "au" "astronomical unit") 149597870700 $ meter
src/Numeric/Units/Dimensional/UnitNames/Internal.hs view
@@ -30,23 +30,23 @@  -- | The name of a unit. data UnitName (m :: Metricality) where-  -- The name of the unit of dimensionless values.+  -- | The name of the unit of dimensionless values.   One :: UnitName 'NonMetric-  -- A name of an atomic unit to which metric prefixes may be applied.+  -- | A name of an atomic unit to which metric prefixes may be applied.   MetricAtomic :: NameAtom ('UnitAtom 'Metric) -> UnitName 'Metric-  -- A name of an atomic unit to which metric prefixes may not be applied.+  -- | A name of an atomic unit to which metric prefixes may not be applied.   Atomic :: NameAtom ('UnitAtom 'NonMetric) -> UnitName 'NonMetric-  -- A name of a prefixed unit.+  -- | A name of a prefixed unit.   Prefixed :: PrefixName -> UnitName 'Metric -> UnitName 'NonMetric-  -- A compound name formed from the product of two names.+  -- | A compound name formed from the product of two names.   Product :: UnitName 'NonMetric -> UnitName 'NonMetric -> UnitName 'NonMetric-  -- A compound name formed from the quotient of two names.+  -- | A compound name formed from the quotient of two names.   Quotient :: UnitName 'NonMetric -> UnitName 'NonMetric -> UnitName 'NonMetric-  -- A compound name formed by raising a unit name to an integer power.+  -- | A compound name formed by raising a unit name to an integer power.   Power :: UnitName 'NonMetric -> Int -> UnitName 'NonMetric-  -- A compound name formed by grouping another name, which is generally compound.+  -- | A compound name formed by grouping another name, which is generally compound.   Grouped :: UnitName 'NonMetric -> UnitName 'NonMetric-  -- A weakened name formed by forgetting that it could accept a metric prefix.+  -- | A weakened name formed by forgetting that it could accept a metric prefix.   --   -- Also available is the smart constructor `weaken` which accepts any `UnitName` as input.   Weaken :: UnitName 'Metric -> UnitName 'NonMetric@@ -79,12 +79,14 @@   show (Grouped n) = "(" ++ show n ++ ")"   show (Weaken n) = show n +-- | Converts a 'UnitName' to a 'NameAtom', if possible. asAtomic :: UnitName m -> Maybe (NameAtom ('UnitAtom m)) asAtomic (MetricAtomic a) = Just a asAtomic (Atomic a) = Just a asAtomic (Weaken n) = coerce <$> asAtomic n asAtomic _ = Nothing +-- | Returns 'True' if the 'UnitName' is atomic. isAtomic :: UnitName m -> Bool isAtomic One = True isAtomic (MetricAtomic _) = True@@ -98,7 +100,7 @@ isAtomicOrProduct (Product _ _) = True isAtomicOrProduct n = isAtomic n --- reduce by algebraic simplifications+-- | Reduce a 'UnitName' by algebraic simplifications. reduce :: UnitName m -> UnitName m reduce One = One reduce n@(MetricAtomic _) = n@@ -131,6 +133,7 @@ -- | The name of a metric prefix. type PrefixName = NameAtom 'PrefixAtom +-- | A metric prefix. data Prefix = Prefix               {                 -- | The name of a metric prefix.@@ -184,8 +187,8 @@ baseUnitNames :: [UnitName 'NonMetric] baseUnitNames = [weaken nMeter, nKilogram, weaken nSecond, weaken nAmpere, weaken nKelvin, weaken nMole, weaken nCandela] -deka, hecto, kilo, mega, giga, tera, peta, exa, zetta, yotta :: Prefix-deka  = prefix "da" "da" "deka" 1e1+deca, hecto, kilo, mega, giga, tera, peta, exa, zetta, yotta :: Prefix+deca  = prefix "da" "da" "deca" 1e1 hecto = prefix "h" "h" "hecto"  1e2 kilo  = prefix "k" "k" "kilo"   1e3 mega  = prefix "M" "M" "mega"   1e6@@ -209,7 +212,7 @@  -- | A list of all 'Prefix'es defined by the SI. siPrefixes :: [Prefix]-siPrefixes = [yocto, zepto, atto, femto, pico, nano, micro, milli, centi, deci, deka, hecto, kilo, mega, giga, tera, peta, exa, zetta, yotta]+siPrefixes = [yocto, zepto, atto, femto, pico, nano, micro, milli, centi, deci, deca, hecto, kilo, mega, giga, tera, peta, exa, zetta, yotta]  -- | Forms a 'UnitName' from a 'Metric' name by applying a metric prefix. applyPrefix :: Prefix -> UnitName 'Metric -> UnitName 'NonMetric@@ -282,8 +285,8 @@   = NameAtom   {     _interchangeName :: InterchangeName, -- ^ The interchange name of the unit.-    abbreviation_en :: String, -- ^ The abbreviated name of the unit in international English-    name_en :: String -- ^ The full name of the unit in international English+    abbreviation_en :: String, -- ^ The abbreviated name of the unit in international English.+    name_en :: String -- ^ The full name of the unit in international English.   }   deriving (Eq, Ord, Data, Typeable, Generic) 
src/Numeric/Units/Dimensional/Variants.hs view
@@ -71,6 +71,11 @@   'DUnit m1 * 'DUnit m2 = 'DUnit 'NonMetric   'DQuantity s1 * 'DQuantity s2 = 'DQuantity (s1 E.* s2) +-- | Forms the quotient of two 'Variant's.+--+-- The quotient of units is a non-metric unit.+--+-- The quotient of quantities is a quantity. type family (v1 :: Variant) / (v2 :: Variant) :: Variant where   'DUnit m1 / 'DUnit m2 = 'DUnit 'NonMetric   'DQuantity s1 / 'DQuantity s2 = 'DQuantity (s1 E./ s2)@@ -83,8 +88,8 @@ -- | Two 'Variant's are compatible when dimensional values of the first may be converted -- into the second merely by changing the representation of their values. type family AreCompatible (v1 :: Variant) (v2 :: Variant) :: Bool where-  AreCompatible ('DQuantity s1)  ('DQuantity s2) = 'True-  AreCompatible ('DUnit m) ('DUnit 'NonMetric)   = 'True+  AreCompatible ('DQuantity s1) ('DQuantity s2) = 'True+  AreCompatible ('DUnit m) ('DUnit 'NonMetric)  = 'True   AreCompatible s s   = 'True   AreCompatible s1 s2 = 'False 
tests/Spec.hs view
@@ -1,4 +1,4 @@ {-# OPTIONS_GHC -F -pgmF hspec-discover #-}  -- This module will automatically pull in all the Spec modules.--- See http://hspec.github.io/hspec-discover.html for a summary of how it works.+-- See https://hspec.github.io/hspec-discover.html for a summary of how it works.