packages feed

dimensional 0.7.3 → 0.8

raw patch · 11 files changed

+85/−478 lines, 11 filesdep +numtypedep ~basePVP ok

version bump matches the API change (PVP)

Dependencies added: numtype

Dependency ranges changed: base

API changes (from Hackage documentation)

- Numeric.NumType: (*) :: (Mul a b c) => a -> b -> c
- Numeric.NumType: (+) :: (Sum a b c) => a -> b -> c
- Numeric.NumType: (-) :: (Sum a b c) => c -> b -> a
- Numeric.NumType: (/) :: (Div a b c) => a -> b -> c
- Numeric.NumType: class (NumTypeI a, NonZeroI b, NumTypeI c) => Div a b c | a b -> c, c b -> a
- Numeric.NumType: class (NumTypeI a, NumTypeI b, NumTypeI c) => Mul a b c | a b -> c
- Numeric.NumType: class (NegTypeI n) => NegType n
- Numeric.NumType: class (NumTypeI a, NumTypeI b) => Negate a b | a -> b, b -> a
- Numeric.NumType: class (NonZeroI n) => NonZero n
- Numeric.NumType: class (NumTypeI n) => NumType n
- Numeric.NumType: class (PosTypeI n) => PosType n
- Numeric.NumType: class (NumTypeI a, NumTypeI b) => Succ a b | a -> b, b -> a
- Numeric.NumType: class (Add a b c, Sub c b a) => Sum a b c | a b -> c, a c -> b, b c -> a
- Numeric.NumType: data Neg n
- Numeric.NumType: data Pos n
- Numeric.NumType: data Zero
- Numeric.NumType: decr :: (Succ a b) => b -> a
- Numeric.NumType: incr :: (Succ a b) => a -> b
- Numeric.NumType: instance (Add a b c, Sub c b a) => Sum a b c
- Numeric.NumType: instance (NegTypeI a) => Succ (Neg (Neg a)) (Neg a)
- Numeric.NumType: instance (NegTypeI a, PosTypeI b, Negate a b) => Negate (Neg a) (Pos b)
- Numeric.NumType: instance (NegTypeI a, Succ c b, Add a c d) => Add (Neg a) b d
- Numeric.NumType: instance (NegTypeI n) => NegType n
- Numeric.NumType: instance (NegTypeI n) => NegTypeI (Neg n)
- Numeric.NumType: instance (NegTypeI n) => NonZeroI (Neg n)
- Numeric.NumType: instance (NegTypeI n) => NumTypeI (Neg n)
- Numeric.NumType: instance (NegTypeI n) => Show (Neg n)
- Numeric.NumType: instance (NegTypeI n, Div c (Neg n) a) => Mul a (Neg n) c
- Numeric.NumType: instance (NegTypeI n, NegTypeI n', Negate n p, Negate n' p', Div (Pos p) (Pos p') (Pos p'')) => Div (Neg n) (Neg n') (Pos p'')
- Numeric.NumType: instance (NegTypeI n, Negate n p', Div (Pos p') (Pos p) (Pos p''), Negate (Pos p'') (Neg n'')) => Div (Neg n) (Pos p) (Neg n'')
- Numeric.NumType: instance (NegTypeI n, Negate n p', Div (Pos p) (Pos p') (Pos p''), Negate (Pos p'') (Neg n'')) => Div (Pos p) (Neg n) (Neg n'')
- Numeric.NumType: instance (NonZeroI n) => Div Zero n Zero
- Numeric.NumType: instance (NonZeroI n) => NonZero n
- Numeric.NumType: instance (NumType a) => Sub a Zero a
- Numeric.NumType: instance (NumTypeI a) => Add Zero a a
- Numeric.NumType: instance (NumTypeI n) => Mul n Zero Zero
- Numeric.NumType: instance (NumTypeI n) => NumType n
- Numeric.NumType: instance (PosTypeI a) => Succ (Pos a) (Pos (Pos a))
- Numeric.NumType: instance (PosTypeI a, NegTypeI b, Negate a b) => Negate (Pos a) (Neg b)
- Numeric.NumType: instance (PosTypeI a, Succ b c, Add a c d) => Add (Pos a) b d
- Numeric.NumType: instance (PosTypeI n) => NonZeroI (Pos n)
- Numeric.NumType: instance (PosTypeI n) => NumTypeI (Pos n)
- Numeric.NumType: instance (PosTypeI n) => PosType n
- Numeric.NumType: instance (PosTypeI n) => PosTypeI (Pos n)
- Numeric.NumType: instance (PosTypeI n) => Show (Pos n)
- Numeric.NumType: instance (PosTypeI p, Div c (Pos p) a) => Mul a (Pos p) c
- Numeric.NumType: instance (Succ a a', NegTypeI b, Sub a' b c) => Sub a (Neg b) c
- Numeric.NumType: instance (Succ a' a, PosTypeI b, Sub a' b c) => Sub a (Pos b) c
- Numeric.NumType: instance (Sum n' (Pos n'') (Pos n), Div n'' (Pos n') n''', PosTypeI n''') => Div (Pos n) (Pos n') (Pos n''')
- Numeric.NumType: instance NegTypeI Zero
- Numeric.NumType: instance Negate Zero Zero
- Numeric.NumType: instance NumTypeI Zero
- Numeric.NumType: instance PosTypeI Zero
- Numeric.NumType: instance Show Zero
- Numeric.NumType: instance Succ (Neg Zero) Zero
- Numeric.NumType: instance Succ Zero (Pos Zero)
- Numeric.NumType: neg1 :: Neg1
- Numeric.NumType: neg2 :: Neg2
- Numeric.NumType: neg3 :: Neg3
- Numeric.NumType: neg4 :: Neg4
- Numeric.NumType: neg5 :: Neg5
- Numeric.NumType: negate :: (Negate a b) => a -> b
- Numeric.NumType: pos1 :: Pos1
- Numeric.NumType: pos2 :: Pos2
- Numeric.NumType: pos3 :: Pos3
- Numeric.NumType: pos4 :: Pos4
- Numeric.NumType: pos5 :: Pos5
- Numeric.NumType: toNum :: (NumTypeI n, Num a) => n -> a
- Numeric.NumType: type Neg1 = Neg Zero
- Numeric.NumType: type Neg2 = Neg Neg1
- Numeric.NumType: type Neg3 = Neg Neg2
- Numeric.NumType: type Neg4 = Neg Neg3
- Numeric.NumType: type Neg5 = Neg Neg4
- Numeric.NumType: type Pos1 = Pos Zero
- Numeric.NumType: type Pos2 = Pos Pos1
- Numeric.NumType: type Pos3 = Pos Pos2
- Numeric.NumType: type Pos4 = Pos Pos3
- Numeric.NumType: type Pos5 = Pos Pos4
- Numeric.NumType: zero :: Zero
+ Numeric.Units.Dimensional.NonSI: century :: (Num a) => Unit DTime a
+ Numeric.Units.Dimensional.NonSI: year :: (Num a) => Unit DTime a

Files

− Numeric/NumType.lhs
@@ -1,402 +0,0 @@-Numeric.NumType -- Type level integers-Bjorn Buckwalter, bjorn.buckwalter@gmail.com-License: BSD3---= Summary =--This Module provides type level representations, hereafter referred-to as "NumTypes", of the (positive and negative) integers and some-basic operations (addition, subtraction...) on these. While functions-are provided for the operations NumTypes are solely for the type-level and their only value is 'undefined'.--There are similarities with the HNats of the HList library [1],-which was indeed a source of inspiration. Occasionally references-are made to the HNats. The main addition in this module is negative-numbers.--The practical size of the NumTypes is limited by the type checker-stack. If the NumTypes grow too large (which can happen quickly-with multiplication) an error message similar to the following will-be emitted:--    Context reduction stack overflow; size = 20 -    Use -fcontext-stack=N to increase stack size to N--This situation could concievably be mitigated significantly by using-e.g. a binary representation of integers rather than Peano numbers.---= Preliminaries =--This module requires GHC 6.6 or later. We utilize multi-parameter-type classes, phantom types, functional dependencies and undecidable-instances (and possibly additional unidentified GHC extensions).--> {-# LANGUAGE UndecidableInstances->            , ScopedTypeVariables->            , EmptyDataDecls->            , FunctionalDependencies->            , MultiParamTypeClasses->            , FlexibleInstances -> #-}--> {- |->    Copyright  : Copyright (C) 2006-2008 Bjorn Buckwalter->    License    : BSD3->->    Maintainer : bjorn.buckwalter@gmail.com->    Stability  : Stable->    Portability: GHC only?-> -> Please refer to the literate Haskell code for documentation of both API-> and implementation.-> -}--> module Numeric.NumType ->   -- Basic classes (exported versions).->   ( NumType, PosType, NegType, NonZero->   -- Arithmetic classes.->   , Succ, Negate, Sum, Div, Mul->   -- Functions.->   , toNum, incr, decr, negate, (+), (-), (*), (/)->   -- Data types.->   , Zero, Pos, Neg->   -- Type synonyms for convenience.-> 	, Pos1, Pos2, Pos3, Pos4, Pos5, Neg1, Neg2, Neg3, Neg4, Neg5->   -- Values for convenience.-> 	, zero, pos1, pos2, pos3, pos4, pos5, neg1, neg2, neg3, neg4, neg5->   ) where--> import Prelude hiding ((*), (/), (+), (-), negate)-> import qualified Prelude ((+), (-))--Use the same fixity for operators as the Prelude.--> infixl 7  *, /-> infixl 6  +, ----= NumTypes =--We start by defining a class encompassing all integers with the-class function 'toNum' that converts from the type-level to a-value-level 'Num'.--> class NumTypeI n where toNum :: (Num a) => n -> a--Then we define classes encompassing all positive and negative-integers respectively. The 'PosTypeI' class corresponds to HList's-'HNat'. We also define a class for non-zero numbers (used to-prohibit division by zero).--> class (NumTypeI n) => PosTypeI n-> class (NumTypeI n) => NegTypeI n-> class (NumTypeI n) => NonZeroI n--Now we use a trick from Oleg Kiselyov and Chung-chieh Shan [2]:--    -- The well-formedness condition, the kind predicate-    class Nat0 a where toInt :: a -> Int-    class Nat0 a => Nat a           -- (positive) naturals--    -- To prevent the user from adding new instances to Nat0 and especially-    -- to Nat (e.g., to prevent the user from adding the instance |Nat B0|)-    -- we do NOT export Nat0 and Nat. Rather, we export the following proxies.-    -- The proxies entail Nat and Nat0 and so can be used to add Nat and Nat0-    -- constraints in the signatures. However, all the constraints below-    -- are expressed in terms of Nat0 and Nat rather than proxies. Thus,-    -- even if the user adds new instances to proxies, it would not matter.-    -- Besides, because the following proxy instances are most general,-    -- one may not add further instances without overlapping instance extension.-    class    Nat0 n => Nat0E n-    instance Nat0 n => Nat0E n-    class    Nat n => NatE n-    instance Nat n => NatE n--We apply this trick to our classes. In our case we will elect to-append an "I" to the internal (non-exported) classes rather than-appending an "E" to the exported classes.--> class    (NumTypeI n) => NumType n-> instance (NumTypeI n) => NumType n-> class    (PosTypeI n) => PosType n-> instance (PosTypeI n) => PosType n-> class    (NegTypeI n) => NegType n-> instance (NegTypeI n) => NegType n-> class    (NonZeroI n) => NonZero n-> instance (NonZeroI n) => NonZero n--We do not have to do this for our other classes. They have the above-classes in their constraints and since the instances are complete-(not proven) a new instance cannot be defined (actually used in the-case of GHC) without overlapping instances.--Now we Define the data types used to represent integers. We begin-with 'Zero', which we allow to be used as both a positive and a-negative number in the sense of the previously defined type classes.-'Zero' corresponds to HList's 'HZero'.--> data Zero-> instance NumTypeI Zero where toNum _ = 0-> instance PosTypeI Zero-> instance NegTypeI Zero--Next we define the "successor" type, here called 'Pos' (corresponding-to HList's 'HSucc').--> data Pos n-> instance (PosTypeI n) => NumTypeI (Pos n) where ->   toNum _ = toNum (undefined :: n) Prelude.+ 1 -> instance (PosTypeI n) => PosTypeI (Pos n)-> instance (PosTypeI n) => NonZeroI (Pos n)--We could be more restrictive using "data (PosTypeI n) => Pos n" but-this constraint will not be checked (by GHC) anyway when 'Pos' is-used solely at the type level. --Finally we define the "predecessor" type used to represent negative-numbers.--> data Neg n-> instance (NegTypeI n) => NumTypeI (Neg n) where->   toNum _ = toNum (undefined :: n) Prelude.- 1 -> instance (NegTypeI n) => NegTypeI (Neg n)-> instance (NegTypeI n) => NonZeroI (Neg n)- --= Show instances =--For convenience we create show instances for the defined NumTypes.--> instance Show Zero where show _ = "NumType 0"-> instance (PosTypeI n) => Show (Pos n) where show x = "NumType " ++ show (toNum x :: Integer)-> instance (NegTypeI n) => Show (Neg n) where show x = "NumType " ++ show (toNum x :: Integer)-- -= Negation, incrementing and decrementing =--We start off with some basic building blocks. Negation is a simple-matter of recursively changing 'Pos' to 'Neg' or vice versa while-leaving 'Zero' unchanged.--> class (NumTypeI a, NumTypeI b) => Negate a b | a -> b, b -> a--> instance Negate Zero Zero-> instance (PosTypeI a, NegTypeI b, Negate a b) => Negate (Pos a) (Neg b)-> instance (NegTypeI a, PosTypeI b, Negate a b) => Negate (Neg a) (Pos b) --We define a type class for incrementing and decrementing NumTypes.-The 'incr' and 'decr' functions correspond roughly to HList's 'hSucc'-and 'hPred' respectively.--> class (NumTypeI a, NumTypeI b) => Succ a b | a -> b, b -> a--To increment NumTypes we either prepend 'Pos' to numbers greater-than or equal to Zero or remove a 'Neg' from numbers less than Zero.--> instance Succ Zero (Pos Zero)-> instance (PosTypeI a) => Succ (Pos a) (Pos (Pos a))-> instance Succ (Neg Zero) Zero-> instance (NegTypeI a) => Succ (Neg (Neg a)) (Neg a)---= Addition and subtraction =--Now let us move on towards more complex arithmetic operations. We-define a class for addition and subtraction of NumTypes.--> class (Add a b c, Sub c b a)->    => Sum a b c | a b -> c, a c -> b, b c -> a--In order to provide instances satisfying the functional dependencies-of 'Sum', in particular the property that any two parameters uniquely-define the third, we must use helper classes.--> class (NumTypeI a, NumTypeI b, NumTypeI c) => Add a b c | a b -> c-> class (NumTypeI a, NumTypeI b, NumTypeI c) => Sub a b c | a b -> c--Adding anything to Zero gives "anything".--> instance (NumTypeI a) => Add Zero a a--When adding to a non-Zero number our strategy is to "transfer" type-constructors from the first type to the second type until the first-type is Zero. We use the 'Succ' class to do this.--> instance (PosTypeI a, Succ b c, Add a c d) => Add (Pos a) b d-> instance (NegTypeI a, Succ c b, Add a c d) => Add (Neg a) b d--We define our helper class for subtraction analogously.--> instance (NumType a) => Sub a Zero a-> instance (Succ a' a, PosTypeI b, Sub a' b c) => Sub a (Pos b) c-> instance (Succ a a', NegTypeI b, Sub a' b c) => Sub a (Neg b) c--While we cold have defined a single 'Sub' instance using negation and-addition.--] instance (Negate b b', Add a b' c) => Sub a b c--However, the constraints of such a 'Sub' instance which are not-also constraints of the 'Sub' class can complicate type signatures-(is this true or was I confused by other issues at the time?). Thus-we elect to use the lower level instances analoguous to the 'Add'-instances.--Using the helper classes we can provide an instance of 'Sum' that-satisfies its functional dependencies. We provide an instance of-'Sum' in terms of 'Add' and 'Sub'.--> instance (Add a b c, Sub c b a) => Sum a b c---= Division =--We will do division on NumTypes before we do multiplication. This-may be surprising but it will in fact simplify the multiplication.-The reason for this is that we can have a "reverse" functional-dependency for division but not for multiplication. Consider the-expressions "x / y = z". If y and z are known we can always determine-x. However, in "x * y = z" we can not determine x if y and z are-zero.--The 'NonZeroI' class is used as a constraint on the denominator 'b'-in our 'Div' class.--> class (NumTypeI a, NonZeroI b, NumTypeI c) => Div a b c | a b -> c, c b -> a--Zero divided by anything (we don't bother with infinity) equals-zero.--> instance (NonZeroI n) => Div Zero n Zero--Note that We could omit the 'NonZeroI' class completely and instead-provide the following two instances.--] instance (PosTypeI n) => Div Zero (Pos n) Zero-] instance (NegTypeI n) => Div Zero (Neg n) Zero--Going beyond zero numbers we start with a base case with all numbers-positive. We recursively subtract the denominator from nominator-while incrementing the result, until we reach the zero case.--> instance ( Sum n' (Pos n'') (Pos n)->          , Div n'' (Pos n') n''', PosTypeI n''') ->       => Div (Pos n) (Pos n') (Pos n''')--Now we tackle cases with negative numbers involved. We trivially-convert these to the all-positive case and negate the result if-appropriate.--> instance ( NegTypeI n, NegTypeI n'->          , Negate n p, Negate n' p'->          , Div (Pos p) (Pos p') (Pos p''))->       => Div (Neg n) (Neg n') (Pos p'')-> instance ( NegTypeI n, Negate n p'->          , Div (Pos p) (Pos p') (Pos p'')->          , Negate (Pos p'') (Neg n''))->       => Div (Pos p) (Neg n) (Neg n'')-> instance ( NegTypeI n, Negate n p'->          , Div (Pos p') (Pos p) (Pos p'')->          , Negate (Pos p'') (Neg n''))->       => Div (Neg n) (Pos p) (Neg n'')---= Multiplication =--Class for multiplication. Limited by the type checker stack. If the-multiplication is too large this error message will be emitted:--    Context reduction stack overflow; size = 20 -    Use -fcontext-stack=N to increase stack size to N--> class (NumTypeI a, NumTypeI b, NumTypeI c) => Mul a b c | a b -> c--Providing instances for the 'Mul' class is really easy thanks to-the 'Div' class having the functional dependency "c b -> a".--> instance (NumTypeI n) => Mul n Zero Zero-> instance (PosTypeI p, Div c (Pos p) a) => Mul a (Pos p) c-> instance (NegTypeI n, Div c (Neg n) a) => Mul a (Neg n) c---= Functions =--Using the above type classes we define functions for various-arithmetic operations. All functions are undefined and only operate-on the type level. Their main contribution is that they facilitate-NumType arithmetic without explicit (and tedious) type declarations.--The main reason to collect all functions here is to keep the-preceeding sections free from distraction.--> negate :: (Negate a b) => a -> b-> negate _ = undefined--> incr :: (Succ a b) => a -> b-> incr _ = undefined-> decr :: (Succ a b) => b -> a-> decr _ = undefined--> (+) :: (Sum a b c) => a -> b -> c-> _ + _ = undefined-> (-) :: (Sum a b c) => c -> b -> a-> _ - _ = undefined--> (/) :: (Div a b c) => a -> b -> c -> _ / _ = undefined--> (*) :: (Mul a b c) => a -> b -> c -> _ * _ = undefined---= Convenince types and values =--Finally we define some type synonyms for the convenience of clients-of the library.--> type Pos1 = Pos Zero-> type Pos2 = Pos Pos1-> type Pos3 = Pos Pos2-> type Pos4 = Pos Pos3-> type Pos5 = Pos Pos4-> type Neg1 = Neg Zero-> type Neg2 = Neg Neg1-> type Neg3 = Neg Neg2-> type Neg4 = Neg Neg3-> type Neg5 = Neg Neg4--Analogously we also define some convenience values (all 'undefined'-but with the expected types).--> zero :: Zero  -- ~ hZero-> zero = undefined-> pos1 :: Pos1-> pos1 = incr zero-> pos2 :: Pos2-> pos2 = incr pos1-> pos3 :: Pos3-> pos3 = incr pos2-> pos4 :: Pos4-> pos4 = incr pos3-> pos5 :: Pos5-> pos5 = incr pos4-> neg1 :: Neg1-> neg1 = decr zero-> neg2 :: Neg2-> neg2 = decr neg1-> neg3 :: Neg3-> neg3 = decr neg2-> neg4 :: Neg4-> neg4 = decr neg3-> neg5 :: Neg5-> neg5 = decr neg4---= References =--[1] http://homepages.cwi.nl/~ralf/HList/-[2] http://okmij.org/ftp/Computation/resource-aware-prog/BinaryNumber.hs-
Numeric/Units/Dimensional.lhs view
@@ -63,24 +63,24 @@ >    Maintainer : bjorn.buckwalter@gmail.com >    Stability  : Stable >    Portability: GHC only?-> +> > Please refer to the literate Haskell code for documentation of both API > and implementation. > -} -> module Numeric.Units.Dimensional +> module Numeric.Units.Dimensional >       -- TODO discriminate exports, in particular Variants and Dims. >   where -> import Prelude +> import Prelude >   ( Show, Eq, Ord, Num, Fractional, Floating, RealFloat, Functor, fmap >   , (.), flip, show, (++), undefined, otherwise, (==), String, unwords >   , map, foldr, null, Integer >   )-> import qualified Prelude +> import qualified Prelude > import Data.List (genericLength) > import Data.Maybe (Maybe (Just, Nothing), catMaybes)-> import Numeric.NumType +> import Numeric.NumType >   ( NumType, NonZero, PosType, Zero, toNum, Sum >   , Pos1, Pos2, pos2, Pos3, pos3 >   )@@ -151,7 +151,7 @@ > Dimensional x /~ Dimensional y = x Prelude./ y  We give '*~' and '/~' the same fixity as '*' and '/' defined below.-Note that this necessitates the use of parenthesis when composing +Note that this necessitates the use of parenthesis when composing units using '*' and '/', e.g. "1 *~ (meter / second)".  > infixl 7  *~, /~@@ -167,7 +167,7 @@ using NumTypes. For convenience we collect all seven base dimensions in a data type 'Dim'. -> data Dim l m t i th n j +> data Dim l m t i th n j  where the respective dimensions are represented by type variables using the following convention.@@ -260,7 +260,7 @@ powers make little physical sense. Since the value of the exponent affects the type of the result the value of the exponent must be visible to the type system, therefore we will generally represent-the exponent with a 'NumType'. +the exponent with a 'NumType'.  Powers of dimensions corresponds to multiplication of the base dimensions' exponents by the exponent.@@ -272,7 +272,7 @@ >           N.Mul i  x i', >           N.Mul th x th', >           N.Mul n  x n',->           N.Mul j  x j') => Pow (Dim l  m  t  i  th  n  j) x +>           N.Mul j  x j') => Pow (Dim l  m  t  i  th  n  j) x >                                 (Dim l' m' t' i' th' n' j')  Roots of dimensions corresponds to division of the base dimensions'@@ -285,7 +285,7 @@ >           N.Div i  x i', >           N.Div th x th', >           N.Div n  x n',->           N.Div j  x j') => Root (Dim l  m  t  i  th  n  j) x +>           N.Div j  x j') => Root (Dim l  m  t  i  th  n  j) x >                                  (Dim l' m' t' i' th' n' j')  @@ -297,11 +297,11 @@  Multiplication, division and powers apply to both units and quantities. -> (*) :: (Num a, Mul d d' d'') +> (*) :: (Num a, Mul d d' d'') >     => Dimensional v d a -> Dimensional v d' a -> Dimensional v d'' a > Dimensional x * Dimensional y = Dimensional (x Prelude.* y) -> (/) :: (Fractional a, Div d d' d'') +> (/) :: (Fractional a, Div d d' d'') >     => Dimensional v d a -> Dimensional v d' a -> Dimensional v d'' a > Dimensional x / Dimensional y = Dimensional (x Prelude./ y) @@ -398,9 +398,9 @@ >   fmap f (Dimensional x) = Dimensional (f x)  We continue by defining elementary functions on 'Dimensionless'-that may be obviously useful. +that may be obviously useful. -> exp, log, sin, cos, tan, asin, acos, atan, sinh, cosh, tanh, asinh, acosh, atanh +> exp, log, sin, cos, tan, asin, acos, atan, sinh, cosh, tanh, asinh, acosh, atanh >   :: (Floating a) => Dimensionless a -> Dimensionless a > exp   = fmap Prelude.exp > log   = fmap Prelude.log@@ -417,14 +417,14 @@ > acosh = fmap Prelude.acosh > atanh = fmap Prelude.atanh -> (**) :: (Floating a) +> (**) :: (Floating a) >      => Dimensionless a -> Dimensionless a -> Dimensionless a > Dimensional x ** Dimensional y = Dimensional (x Prelude.** y)  For 'atan2' the operands need not be dimensionless but they must be of the same type. The result will of course always be dimensionless. -> atan2 :: (RealFloat a) +> atan2 :: (RealFloat a) >       => Quantity d a -> Quantity d a -> Dimensionless a > atan2 (Dimensional y) (Dimensional x) = Dimensional (Prelude.atan2 y x) @@ -494,7 +494,7 @@ users of the 'Extensible' module.  > dimUnit :: (NumType n) => String -> n -> Maybe String-> dimUnit u n +> dimUnit u n >   | x == 0    = Nothing >   | x == 1    = Just u >   | otherwise = Just (u ++ "^" ++ show x)@@ -525,7 +525,7 @@  ] numval :: Prelude.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 [1]. While the above syntax is fairly natural it is unfortunate that@@ -539,7 +539,7 @@  ] escapeVelocity :: (Floating a) => Mass a -> Length a -> Velocity a ] escapeVelocity m r = sqrt (two * g * m / r)-]   where +]   where ]       two = 2 *~ one ]       g = 6.6720e-11 *~ (newton * meter ^ pos2 / kilo gram ^ pos2) @@ -592,7 +592,7 @@  While there is an insane amount of units in use around the world it is reasonable to provide at least all SI units. Units outside-of SI will most likely be added on an as-needed basis. +of SI will most likely be added on an as-needed basis.  There are also plenty of elementary functions to add. The 'Floating' class can be used as reference.@@ -601,12 +601,12 @@ The 'show' implementation could output the numerical value and the unit expressed in (base?) SI units, along the lines of: -] instance (Fractional a, Show a) => Show (Length a) +] instance (Fractional a, Show a) => Show (Length a) ]   where show x = show (x /~ meter) ++ " m"  Additional functions could be provided for "showing" with any unit and prefix.  The 'read' implementation should be able to read values-with any unit and prefix. It is not clear to the author how to best +with any unit and prefix. It is not clear to the author how to best implement these.  Additional physics models could be implemented. See [3] for ideas.
Numeric/Units/Dimensional/CGS.lhs view
@@ -18,7 +18,7 @@ In this module we show that we can in a straight forward manner support systems with rational exponents, provided that the rationals that may be encountered are known a priori. As an example we provide-a rudimentary implementation of the CGS system. +a rudimentary implementation of the CGS system.  We also show that we can indeed statically prohibit invalid conversions between different systems.@@ -38,13 +38,13 @@ I would appreciate pointers to the CGS representation of these dimensions. -Please correct and inform me if my assumptions are wrong! +Please correct and inform me if my assumptions are wrong!   = Preliminaries =  > {-# LANGUAGE UndecidableInstances->            , ScopedTypeVariables +>            , ScopedTypeVariables >            , EmptyDataDecls >            , MultiParamTypeClasses >            , FlexibleInstances@@ -58,7 +58,7 @@ >    Maintainer : bjorn.buckwalter@gmail.com >    Stability  : Experimental >    Portability: GHC only?-> +> > Please refer to the literate Haskell code for documentation of both API > and implementation. > -}@@ -75,8 +75,8 @@ > import Numeric.NumType ( Neg2, Neg1, Zero, Pos1, Pos2, Pos3, NumType ) > import Numeric.NumType ( neg2, pos2, pos3 ) > import Data.Maybe (catMaybes)-  + = Dimensions =  Analogously with the SI we collect the base dimensions of the CGS@@ -107,24 +107,24 @@  > instance ( N.Sum lh lh' lh'' >          , N.Sum mh mh' mh''->          , N.Sum t  t'  t'' ) => Mul (CGSDim lh   mh   t) ->                                      (CGSDim lh'  mh'  t') +>          , N.Sum t  t'  t'' ) => Mul (CGSDim lh   mh   t)+>                                      (CGSDim lh'  mh'  t') >                                      (CGSDim lh'' mh'' t'')  > instance ( N.Sum lh lh' lh'' >          , N.Sum mh mh' mh''->          , N.Sum t  t'  t'' ) => Div (CGSDim lh'' mh'' t'') ->                                      (CGSDim lh'  mh'  t') +>          , N.Sum t  t'  t'' ) => Div (CGSDim lh'' mh'' t'')+>                                      (CGSDim lh'  mh'  t') >                                      (CGSDim lh   mh   t)  > instance ( N.Mul lh x lh' >          , N.Mul mh x mh'->          , N.Mul t  x t' ) => Pow (CGSDim lh  mh  t) x +>          , N.Mul t  x t' ) => Pow (CGSDim lh  mh  t) x >                                   (CGSDim lh' mh' t')  > instance ( N.Div lh x lh' >          , N.Div mh x mh'->          , N.Div t  x t' ) => Root (CGSDim lh  mh  t) x +>          , N.Div t  x t' ) => Root (CGSDim lh  mh  t) x >                                    (CGSDim lh' mh' t')  @@ -272,9 +272,9 @@  > q_si  = 1.6021773e-19 *~ SI.coulomb -- Elementary charge in SI. > r_si  = 0.1 *~ SI.nano SI.meter     -- Distance in SI-> f_si  = q_si ^ pos2 / (_4 * pi * e0 * r_si ^ pos2) ->   where ->       e0 = 8.8541878e-12 *~ (SI.ampere * SI.second / (SI.volt * SI.meter)) +> f_si  = q_si ^ pos2 / (_4 * pi * e0 * r_si ^ pos2)+>   where+>       e0 = 8.8541878e-12 *~ (SI.ampere * SI.second / (SI.volt * SI.meter))  The same calculation in the CGS system. @@ -287,7 +287,7 @@    *Numeric.Dimensional.CGS> f_si   2.3070794737101255e-8 m kg s^-2-  *Numeric.Dimensional.CGS> f_cgs +  *Numeric.Dimensional.CGS> f_cgs   2.30708078598602e-3 sqrt(cm)^2 sqrt(g)^2 s^-2  To convert from CGS to SI we must specify the type of the SI 'Quantity'.
Numeric/Units/Dimensional/Extensible.lhs view
@@ -41,7 +41,7 @@ >    Maintainer : bjorn.buckwalter@gmail.com >    Stability  : Experimental >    Portability: GHC only?-> +> > Please refer to the literate Haskell code for documentation of both API > and implementation. > -}@@ -49,7 +49,7 @@ > module Numeric.Units.Dimensional.Extensible ( DExt, showDExt ) where  > import Numeric.Units.Dimensional ( Dim, Mul, Div, Pow, Root, dimUnit )-> import Numeric.NumType ( NumType, Sum, Negate, Zero, Pos, Neg ) +> import Numeric.NumType ( NumType, Sum, Negate, Zero, Pos, Neg ) > import qualified Numeric.NumType as N ( Div, Mul )  @@ -106,9 +106,9 @@ with extent in apples and oranges is simple.  ] instance (NumType n, Show d) => Show (DExt TApples n d) where-]   show = showDExt "apple" +]   show = showDExt "apple" ] instance (NumType n, Show d) => Show (DExt TOranges n d) where-]   show = showDExt "orange" +]   show = showDExt "orange"   = The 'DropZero' class =@@ -132,7 +132,7 @@ > instance DropZero (DExt a (Neg n) d) (DExt a (Neg n) d)  -= Classes from 'Numeric.Dimensional' = += Classes from 'Numeric.Dimensional' =  We get negation, addition and subtraction for free with extended Dimensionals. However, we will need instances of the 'Mul', 'Div',@@ -145,24 +145,24 @@ When only one of the 'Mul' factors is an extended dimensional there is no need to minimize. -> instance (Mul d (Dim l m t i th n j) d') +> instance (Mul d (Dim l m t i th n j) d') >       => Mul (DExt a x d) (Dim l m t i th n j) (DExt a x d')-> instance (Mul (Dim l m t i th n j) d d') +> instance (Mul (Dim l m t i th n j) d d') >       => Mul (Dim l m t i th n j) (DExt a x d) (DExt a x d')  If both of the factors are extended the product must be minimized. -> instance (Sum n n' n'', Mul d d' d'', DropZero (DExt a n'' d'') d''') +> instance (Sum n n' n'', Mul d d' d'', DropZero (DExt a n'' d'') d''') >       => Mul (DExt a n d) (DExt a n' d') d'''  Analogously for 'Div'. -> instance (Div d (Dim l m t i th n j) d') +> instance (Div d (Dim l m t i th n j) d') >       => Div (DExt a x d) (Dim l m t i th n j) (DExt a x d')-> instance (Div (Dim l m t i th n j) d d', Negate x x') +> instance (Div (Dim l m t i th n j) d d', Negate x x') >       => Div (Dim l m t i th n j) (DExt a x d) (DExt a x' d') -> instance (Sum n'' n' n, Div d d' d'', DropZero (DExt a n'' d'') d''') +> instance (Sum n'' n' n, Div d d' d'', DropZero (DExt a n'' d'') d''') >       => Div (DExt a n d) (DExt a n' d') d'''  The instances for 'Pow' and 'Root' are simpler since they can not
Numeric/Units/Dimensional/ExtensibleTest.lhs view
@@ -30,13 +30,13 @@ Define show instances.  > instance (NumType n, Show d) => Show (DExt TApples n d) where->   show = showDExt "apple" +>   show = showDExt "apple"  > instance (NumType n, Show d) => Show (DExt TOranges n d) where->   show = showDExt "orange" +>   show = showDExt "orange"  > instance (NumType n, Show d) => Show (DExt TPeaches n d) where->   show = showDExt "peaches" +>   show = showDExt "peaches"  Finally the base units. @@ -85,7 +85,7 @@  Main function. -> main = do +> main = do >   putStrLn "If I compiled I'm mostly OK!" >   runTestTT $ TestList [testShow] 
Numeric/Units/Dimensional/NonSI.lhs view
@@ -7,7 +7,7 @@  This module defines units that are not part of the SI, with the exception of those defined in the 'SIUnits' module (units outside-of the SI accepted for use with the SI). +of the SI accepted for use with the SI).  Any chapters, sections or tables referenced are from [1] unless otherwise specified.@@ -19,7 +19,7 @@ >    Maintainer : bjorn.buckwalter@gmail.com >    Stability  : Stable >    Portability: GHC only?-> +> > Please refer to the literate Haskell code for documentation of both API > and implementation. > -}@@ -88,7 +88,22 @@ > teaspoon = prefix 5 (milli liter)  +The IAU recommends[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.++This aligns well with my needs so I'm happy to oblige. We define+the year in terms of seconds in order to avoid a 'Fractional'+constraint, and also provide a Julian century.++> year, century :: Num a => Unit DTime a+> year    = prefix 31557600 second+> century = prefix 100 year++ = References =  [1] http://physics.nist.gov/Pubs/SP811/-+[2] http://www.iau.org/science/publications/proceedings_rules/units/
Numeric/Units/Dimensional/Prelude.hs view
@@ -1,4 +1,4 @@-module Numeric.Units.Dimensional.Prelude +module Numeric.Units.Dimensional.Prelude     ( module Numeric.Units.Dimensional     , module Numeric.Units.Dimensional.Quantities     , module Numeric.Units.Dimensional.SIUnits@@ -6,7 +6,7 @@     , module Prelude     ) where -import Numeric.Units.Dimensional hiding +import Numeric.Units.Dimensional hiding     ( Dimensional (Dimensional)     ) @@ -14,7 +14,7 @@  import Numeric.Units.Dimensional.SIUnits -import Numeric.NumType +import Numeric.NumType     ( neg5, neg4, neg3, neg2, neg1, zero, pos1, pos2, pos3, pos4, pos5     )  -- Used in exponents. 
Numeric/Units/Dimensional/Quantities.lhs view
@@ -22,19 +22,19 @@ >    Maintainer : bjorn.buckwalter@gmail.com >    Stability  : Stable >    Portability: GHC only?-> +> > Please refer to the literate Haskell code for documentation of both API > and implementation. > -}  > module Numeric.Units.Dimensional.Quantities where -> import Numeric.Units.Dimensional +> import Numeric.Units.Dimensional >   ( Dim, Quantity, Dimensionless >   , DOne, DLuminousIntensity, DThermodynamicTemperature >   , Unit, DLength, (^+) -- Used only for 'square' and 'cubic'. >   )-> import Numeric.NumType +> import Numeric.NumType >   ( Neg3, Neg2, Neg1, Zero, Pos1, Pos2, Pos3, Pos4 >   , pos2, pos3 -- Used only for 'square' and 'cubic'. >   )@@ -74,7 +74,7 @@ > type MassDensity  = Quantity DMassDensity > type Density      = MassDensity -- Short name. -> type DSpecificVolume = Dim Pos3 Neg1 Zero Zero Zero Zero Zero +> type DSpecificVolume = Dim Pos3 Neg1 Zero Zero Zero Zero Zero > type SpecificVolume  = Quantity DSpecificVolume  > type DCurrentDensity = Dim Neg2 Zero Zero Pos1 Zero Zero Zero
Numeric/Units/Dimensional/SIUnits.lhs view
@@ -17,7 +17,7 @@ >    Maintainer : bjorn.buckwalter@gmail.com >    Stability  : Stable >    Portability: GHC only?-> +> > Please refer to the literate Haskell code for documentation of both API > and implementation. > -}@@ -41,7 +41,7 @@  We define all SI prefixes from Table 5. Multiples first. -> deka, deca, hecto, kilo, mega, giga, tera, peta, exa, zetta, yotta +> deka, deca, hecto, kilo, mega, giga, tera, peta, exa, zetta, yotta >   :: Num a => Unit d a -> Unit d a > deka  = prefix 10 -- International English. > deca  = deka      -- American English.@@ -56,7 +56,7 @@ > yotta = kilo . zetta  Then the submultiples.- + > deci, centi, milli, micro, nano, pico, femto, atto, zepto, yocto >   :: Fractional a => Unit d a -> Unit d a > deci  = prefix 0.1
Test.hs view
@@ -1,12 +1,8 @@--import qualified Numeric.NumTypeTests import qualified Numeric.Units.Dimensional.Test import qualified Numeric.Units.Dimensional.QuantitiesTest import qualified Numeric.Units.Dimensional.ExtensibleTest  main = do-  Numeric.NumTypeTests.main   Numeric.Units.Dimensional.Test.main   Numeric.Units.Dimensional.QuantitiesTest.main   Numeric.Units.Dimensional.ExtensibleTest.main-
dimensional.cabal view
@@ -1,9 +1,9 @@ Name:                dimensional-Version:             0.7.3+Version:             0.8 License:             BSD3 License-File:        LICENSE-Copyright:           Bjorn Buckwalter 2006-2008-Author:              Bjorn Buckwalter +Copyright:           Bjorn Buckwalter 2006-2009+Author:              Bjorn Buckwalter Maintainer:          bjorn.buckwalter@gmail.com Stability:           mostly stable Homepage:            http://dimensional.googlecode.com/@@ -19,10 +19,9 @@     Requires GHC 6.6.1 or later. Category:            Math Build-Type:          Simple-Build-Depends:       base, time+Build-Depends:       base < 5, time, numtype                      -- , fad-Exposed-Modules:     Numeric.NumType, -                     Numeric.Units.Dimensional, +Exposed-Modules:     Numeric.Units.Dimensional,                      Numeric.Units.Dimensional.Prelude,                      Numeric.Units.Dimensional.Quantities,                      Numeric.Units.Dimensional.SIUnits,@@ -39,4 +38,3 @@                      -- , Numeric/Units/Dimensional/ForwardADTest.lhs                      examples/README,                      examples/GM.lhs-