Commits

Thijs Alkemade committed df59bf0

Following Takayuki Muranushi's suggestion, replaced all uses of .*., ./. with |*|, |/|, where the | means that side uses a unit.

So, this also adds:

|*, /|, |/, |+, etc.

This makes it easier to modify the underlying value, while maintaining the unit.

Removed the pow* functions, as these were broken.

  • Participants
  • Parent commits a19e568

Comments (0)

Files changed (5)

         POne, PTwo, PThree, PFour, PFive, PSix,
         NOne, NTwo, NThree, NFour,
 
-        coerce, as, to, one, mkVal, val, mapVal, (.*.), (./.), (.+.), (.-.), (*|), (~.),
-        (.==.), (.<=.), (.<.), (.>=.), (.>.),
+        coerce, as, to, one, mkVal, val, mapVal, (|*|), (|/|), (|+|), (|-|),
+        (*|), (|*), (|/), (/|), (|+), (+|), (|-), (-|),
+        (|==|), (|<=|), (|<|), (|>=|), (|>|),
 
-        square, cubic,
-
-        {- pown3, pown2, pown1, pow0, pow1, pow2, pow3, pow4, pow5, pow6 -}
-
+        square, cubic
 ) where
 
 -- |Type level natural numbers (excluding zero, though).
 coerce :: (Convertible' a b, Convertible' c d, Fractional f, MapEq a c True) => Value f a b -> Value f c d -> Value f c d
 coerce u _ = let result = mkVal (factor' (proxy' u) * val u / factor' (proxy' result)) in result
 
-infixl 5 ~.
-infixl 8 *|
-
--- |Shorthand for 'coerce'.
-(~.) :: (Convertible' a b, Convertible' c d, Fractional f, MapEq a c True) => Value f a b -> Value f c d -> Value f c d
-(~.) = coerce
-
 infixl 5 `as`
 
 -- |Shorthand for 'coerce'.
 to :: (Convertible' a b, Convertible' c d, Fractional f, MapEq a c True) => Value f c d -> Value f a b -> Value f c d
 to = flip coerce
 
-infixl 7 .*., ./.
-infixl 6 .+., .-.
+infixl 7 |*|, |/|
+infixl 6 |+|, |-|
 
 -- |Multiply two values, constructing a value with as dimension the product of the dimensions,
 -- and as unit the multplication of the units.
-(.*.) :: (Fractional f, Convertible' a b, Convertible' c d, MapMerge a c u, MapMerge b d s) => Value f a b -> Value f c d -> Value f u s
-a .*. b = mkVal (val a * val b)
+(|*|) :: (Fractional f, Convertible' a b, Convertible' c d, MapMerge a c u, MapMerge b d s) => Value f a b -> Value f c d -> Value f u s
+a |*| b = mkVal (val a * val b)
 
 -- |Divide two values, constructing a value with as dimension the division of the dimension of the lhs by the dimension of the rhs,
 -- and the same for the units.
-(./.), per :: (Fractional f, Convertible' a b, Convertible' c d, MapMerge a c' u, MapNeg c c', MapNeg d d', MapMerge b d' s) => Value f a b -> Value f c d -> Value f u s
-a ./. b = mkVal (val a / val b)
-per = (./.)
+(|/|), per :: (Fractional f, Convertible' a b, Convertible' c d, MapMerge a c' u, MapNeg c c', MapNeg d d', MapMerge b d' s) => Value f a b -> Value f c d -> Value f u s
+a |/| b = mkVal (val a / val b)
+per = (|/|)
 
 -- |Add two values with matching dimensions. Units are automatically resolved. The result will have the same unit as the lhs.
-(.+.) :: (Fractional f, Convertible' a b, Convertible' c d, MapEq c a True) => Value f a b -> Value f c d -> Value f a b
-a .+. b = mkVal (val a + val (coerce b a))
+(|+|) :: (Fractional f, Convertible' a b, Convertible' c d, MapEq c a True) => Value f a b -> Value f c d -> Value f a b
+a |+| b = mkVal (val a + val (coerce b a))
 
 -- |Subtract two values with matching dimensions. Units are automatically resolved. The result will have the same unit as the lhs.
-(.-.) :: (Fractional f, Convertible' a b, Convertible' c d, MapEq c a True) => Value f a b -> Value f c d -> Value f a b
-a .-. b = mkVal (val a - val (coerce b a))
+(|-|) :: (Fractional f, Convertible' a b, Convertible' c d, MapEq c a True) => Value f a b -> Value f c d -> Value f a b
+a |-| b = mkVal (val a - val (coerce b a))
+
+infixl 7 *|, |*, |/, /|
+infixl 6 +|, |+, -|, |-
+
+-- |Multiply a scalar by a unit.
+(*|) :: (Convertible' a b, Fractional f) => f -> Value f a b -> Value f a b
+d *| u = mkVal (d * val u)
 
 -- |Multiply a unit by a scalar.
-(*|) :: (Convertible' a b, Fractional f) => f -> Value f a b -> Value f a b
-d *| u = mkVal (d * val u)
+(|*) :: (Convertible' a b, Fractional f) => Value f a b -> f -> Value f a b
+u |* d = mkVal (val u * d)
+
+-- |Divide a scalar by a unit.
+(/|) :: (Convertible' a b, Fractional f, MapNeg a a', MapNeg b b') => f -> Value f a b -> Value f a' b'
+d /| u = mkVal (d / val u)
+
+-- |Divide a unit by a scalar.
+(|/) :: (Convertible' a b, Fractional f) => Value f a b -> f -> Value f a b
+u |/ d = mkVal (val u / d)
+
+-- |Add a unit to a scalar.
+(+|) :: (Convertible' a b, Fractional f) => f -> Value f a b -> Value f a b
+d +| u = mkVal (d + val u)
+
+-- |Add a scalar to a unit.
+(|+) :: (Convertible' a b, Fractional f) => Value f a b -> f -> Value f a b
+u |+ d = mkVal (val u + d)
+
+-- |Subtract a unit from a scalar.
+(-|) :: (Convertible' a b, Fractional f) => f -> Value f a b -> Value f a b
+d -| u = mkVal (d - val u)
+
+-- |Subtract a scalar from a unit.
+(|-) :: (Convertible' a b, Fractional f) => Value f a b -> f -> Value f a b
+u |- d = mkVal (val u - d)
 
 -- |Create a new value with given scalar as value.
 mkVal :: (Fractional f) => f -> Value f a b
 -- >>> 100 *| square meter `as` square yard
 -- 119.59900463010803 yd⋅yd⋅#
 square :: (Fractional f, MapMerge c c u, MapMerge d d s, Convertible' c d) => Value f c d -> Value f u s
-square x = x .*. x
+square x = x |*| x
 
 -- |Calculate the third power of a value. Identical to pow3, reads better on units:
 --
 -- >>> 1 *| cubic inch `as` mili liter
 -- 16.387063999999995 mL
 cubic   :: (Fractional f, MapMerge a c u, MapMerge b d s, MapMerge c c a, MapMerge d d b, Convertible' a b, Convertible' c d) => Value f c d -> Value f u s
-cubic x = x .*. x .*. x
-
--- |Calculate @x^(-3)@.
-pown3 :: (Fractional f, Convertible' a b, Pow a b NThree c d) => Value f a b -> Value f c d
-pown3 = pow (undefined :: NumberProxy NThree)
-
--- |Calculate @x^(-2)@.
-pown2 :: (Fractional f, Convertible' a b, Pow a b NTwo c d) => Value f a b -> Value f c d
-pown2 = pow (undefined :: NumberProxy NTwo)
-
--- |Calculate @x^(-1)@.
-pown1 :: (Fractional f, Convertible' a b, Pow a b NOne c d) => Value f a b -> Value f c d
-pown1 = pow (undefined :: NumberProxy NOne)
-
--- |Calculate @x^0@. Yes, this is always @one :: Value f ('[] Count@.
-pow0 :: (Fractional f, Convertible' a b, Pow a b Zero c d) => Value f a b -> Value f c d
-pow0 = pow (undefined :: NumberProxy Zero)
-
--- |Calculate @x^1@.
-pow1 :: (Fractional f, Convertible' a b, Pow a b POne c d) => Value f a b -> Value f c d
-pow1 = pow (undefined :: NumberProxy POne)
-
--- |Calculate @x^2@.
-pow2 :: (Fractional f, Convertible' a b, Pow a b PTwo c d) => Value f a b -> Value f c d
-pow2 = pow (undefined :: NumberProxy PTwo)
-
--- |Calculate @x^3@.
-pow3 :: (Fractional f, Convertible' a b, Pow a b PThree c d) => Value f a b -> Value f c d
-pow3 = pow (undefined :: NumberProxy PThree)
-
--- |Calculate @x^4@.
-pow4 :: (Fractional f, Convertible' a b, Pow a b PFour c d) => Value f a b -> Value f c d
-pow4 = pow (undefined :: NumberProxy PFour)
-
--- |Calculate @x^5@.
-pow5 :: (Fractional f, Convertible' a b, Pow a b PFive c d) => Value f a b -> Value f c d
-pow5 = pow (undefined :: NumberProxy PFive)
-
--- |Calculate @x^6@.
-pow6 :: (Fractional f, Convertible' a b, Pow a b PSix c d) => Value f a b -> Value f c d
-pow6 = pow (undefined :: NumberProxy PSix)
+cubic x = x |*| x |*| x
 
 wrapB :: (Convertible' a b, Convertible' c d, MapEq c a True) => (Rational -> Rational -> Bool) -> Value Rational a b -> Value Rational c d -> Bool
 wrapB op a b = op (val a) (val $ coerce b a)
 
-infixl 4 .==., .<., .>., .<=., .>=.
+infixl 4 |==|, |<|, |>|, |<=|, |>=|
 
-(.==.), (.<.), (.>.), (.<=.), (.>=.) :: (Convertible' a b, Convertible' c d, MapEq c a True) => Value Rational a b -> Value Rational c d -> Bool
+(|==|), (|<|), (|>|), (|<=|), (|>=|) :: (Convertible' a b, Convertible' c d, MapEq c a True) => Value Rational a b -> Value Rational c d -> Bool
 -- |'==' for values. Only defined for values with rational contents. Can be used on any two values with the same dimension.
-(.==.) = wrapB (==)
+(|==|) = wrapB (==)
 -- |'<' on values. Only defined for values with rational contents. Can be used on any two values with the same dimension.
-(.<.) = wrapB (<)
+(|<|) = wrapB (<)
 -- |'<=' on values. Only defined for values with rational contents. Can be used on any two values with the same dimension.
-(.<=.) = wrapB (<=)
+(|<=|) = wrapB (<=)
 -- |'>' on values. Only defined for values with rational contents. Can be used on any two values with the same dimension.
-(.>.) = wrapB (>)
+(|>|) = wrapB (>)
 -- |'>=' on values. Only defined for values with rational contents. Can be used on any two values with the same dimension.
-(.>=.) = wrapB (>=)
+(|>=|) = wrapB (>=)
 
 ----
 -- Counting. These are dimension-less values.
 instance Convertible '[] Count where
         factor _ = 1
         showunit _ = "#"
-
---
-
-class (Convertible' a b, Convertible' c d) => Pow' q a b (i :: Number) c d | q a b i -> c d where
-        _pow :: (Fractional f) => q -> NumberProxy i -> Value f a b -> Value f c d
-
-instance (Convertible' c d, MapNull c True, MapNull d True, Convertible' a b) => Pow' () a b Zero c d where
-        _pow _ _ _ = one
-
-instance (Convertible' a b, Convertible' a'' b'', Pow' q a b i' a' b', Pre' (Pos i) i', MapMerge a a' a'', MapMerge b b' b'') => Pow' q a b (Pos i) a'' b'' where
-        _pow _ _ _ = one
-
--- |'^' is not definable on 'Value's in general, as the result depends on the exponent.
--- However, we can use this class to raise a unit to a type level 'Number'.
-class (Convertible' a b, Convertible' c d, Pow' () a b i c d) => Pow a b (i :: Number) c d | a b -> c d where
-        pow :: (Fractional f) => NumberProxy i -> Value f a b -> Value f c d
-
-instance (Convertible' a b, Pow' () a b i c d) => Pow a b (i :: Number) c d where
-        pow = _pow ()
-
---

src/UnitTyped/NoPrelude.hs

 infixl 6 +, -
 infixl 7 *, /
 
--- |See '.*.'
+-- |See '|*|'
 (*) :: (Fractional f, Convertible' a b, Convertible' c d, MapMerge a c u, MapMerge b d s) => Value f a b -> Value f c d -> Value f u s
-(*) = (.*.)
+(*) = (|*|)
 
--- |See './.'
+-- |See '|/|'
 (/) :: (Fractional f, Convertible' a b, Convertible' c d, MapMerge a c' u, MapNeg c c', MapNeg d d', MapMerge b d' s) => Value f a b -> Value f c d -> Value f u s
-(/) = (./.)
+(/) = (|/|)
 
--- |See '.+.'
+-- |See '|+|'
 (+) :: (Fractional f, Convertible' a b, Convertible' c d, MapEq c a True) => Value f a b -> Value f c d -> Value f a b
-(+) = (.+.)
+(+) = (|+|)
 
--- |See '.-.'
+-- |See '|-|'
 (-) :: (Fractional f, Convertible' a b, Convertible' c d, MapEq c a True) => Value f a b -> Value f c d -> Value f a b
-(-) = (.-.)
+(-) = (|-|)
 
 wrap1 :: (Floating f, Convertible' '[] b) => (f -> f) -> Value f '[] b -> Value f '[] '[]
 wrap1 op v = op (val $ coerce v rad) *| one
 infixl 5 ==, <, <=, >, >=
 
 (==), (<), (<=), (>), (>=) :: (Convertible' a b, Convertible' c d, MapEq c a 'True) => Value Prelude.Rational a b -> Value Prelude.Rational c d -> Bool
--- |See '.==.'
-(==) = (.==.)
--- |See '.<.'
-(<) = (.<.)
--- |See '.<=.'
-(<=) = (.<=.)
--- |See '.>.'
-(>) = (.>.)
--- |See '.>.'
-(>=) = (.>=.)
+-- |See '|==|'
+(==) = (|==|)
+-- |See '|<|'
+(<) = (|<|)
+-- |See '|<=|'
+(<=) = (|<=|)
+-- |See '|>|'
+(>) = (|>|)
+-- |See '|>|'
+(>=) = (|>=|)
 
 -- |Obtain the 'Prelude.floor' of a value.
 floor :: (Prelude.RealFrac f) => Value f a b -> Value f a b
 
 -- |Obtain @x - floor x@ of a value.
 diff :: (Convertible' a b, Prelude.RealFrac f) => Value f a b -> Value f a b
-diff x = x .-. (floor x)
+diff x = x |-| (floor x)
 
 -- |Obtain the 'Prelude.abs' of a value.
 abs :: (Fractional f) => Value f a b -> Value f a b
-abs = mapVal Prelude.abs
+abs = mapVal Prelude.abs

src/UnitTyped/SI/Constants.hs

 
 -- |Reduced Planck constant
 hbar :: Fractional f => Value f '[ '(Time, NOne), '(Length, PTwo), '(Mass, POne)] '[ '(Second, POne), '(Joule, POne) ]
-hbar = coerce (h ./. (2 *| UnitTyped.SI.Constants.pi)) (joule .*. second)
+hbar = coerce (h |/| (2 *| UnitTyped.SI.Constants.pi)) (joule |*| second)
 
 -- |Atomic unit of charge (elementary charge)
 e :: (Fractional f) => Value f Charge (Unit Coulomb)
 
 ---- |Planck mass
 --m_P :: (Fractional f, Floating f) => Value f MassDimension (Unit (Kilo Gram))
---m_P = mkVal (sqrt (val $ hbar .*. c ./. g))
+--m_P = mkVal (sqrt (val $ hbar |*| c |/| g))
 
 ---- |Reduced Planck mass
 --m_P' :: (Fractional f, Floating f) => Value f MassDimension (Unit (Kilo Gram))
---m_P' = mkVal (sqrt (val $ hbar .*. c ./. ((Prelude.pi * 8) *| g)))
+--m_P' = mkVal (sqrt (val $ hbar |*| c |/| ((Prelude.pi * 8) *| g)))

src/UnitTyped/SI/Show.hs

 -- |Show a unit with all possible SI-prefixes.
 -- For instance, a light year in meters:
 --
--- >>> meta_str meter (c .*. 1 *| year)
+-- >>> meta_str meter (c |*| 1 *| year)
 -- "9 Pm, 460 Tm, 536 Gm, 207 Mm, 68 km, 16 m"
 meta_str :: (Convertible' a b, Convertible c d, MapEq a c 'True) => Value Rational c (Unit d) -> Value Rational a b -> String
 meta_str unit v = format_end (yocto unit) $ format (zepto unit) $ format (atto unit) $ format (femto unit)
 import Prelude (zip, show, (++), IO, Bool(..), Integer, return, error, putStrLn)
 import System.Exit (exitFailure)
 
-t1 = hertz == (count / second)
+t1 = hertz == (1 /| second)
 t2 = rad == (meter / meter)
 t3 = newton == kilo gram * meter / square second
 t4 = pascal == newton / square meter
 
 t25 = hbar == (h / (2 *| pi))
 
-t26 = True -- pown3 meter * pow3 meter == pown1 meter * pow1 meter
-t27 = True -- pown3 meter * pow3 meter == pown2 meter * pow2 meter
-t28 = True -- pow0 meter == count
-
-t29 = 3e9 *| gram == mega solarMass
+t26 = 3e9 *| gram == mega solarMass
   where
     solarMass = 3 *| kilo gram
 
                                                   ; return False
                                                   }
 
-main = do { b <- foldM runTest True (zip [t1, t2, t3, t4, t5, t6, t7, t8, t9, t10, t11, t12, t13, t14, t15, t16, t17, t18, t19, t20, t21, t22, t23, t24, t25, t26, t27, t28, t29] [1..])
+main = do { b <- foldM runTest True (zip [t1, t2, t3, t4, t5, t6, t7, t8, t9, t10, t11, t12, t13, t14, t15, t16, t17, t18, t19, t20, t21, t22, t23, t24, t25, t26] [1..])
                   ; unless b exitFailure
                   }