Algebra.DimensionTerm
 Portability portable Stability provisional Maintainer numericprelude@henning-thielemann.de
 Contents Type constructors Rewrites Example dimensions Scalar Basis dimensions Derived dimensions
Description

We already have the dynamically checked physical units provided by Number.Physical and the statically checked ones of the dimensional package of Buckwalter, which require multi-parameter type classes with functional dependencies.

Here we provide a poor man's approach: The units are presented by type terms. There is no canonical form and thus the type checker can not automatically check for equal units. However, if two unit terms represent the same unit, then you can tell the type checker to rewrite one into the other.

You can add more dimensions by introducing more types of class C.

This approach is not entirely safe because you can write your own flawed rewrite rules. It is however more safe than with no units at all.

Synopsis
class Show a => C a
noValue :: C a => a
data Scalar = Scalar
data Mul a b = Mul
data Recip a = Recip
type Sqr a = Mul a a
appPrec :: Int
scalar :: Scalar
mul :: (C a, C b) => a -> b -> Mul a b
recip :: C a => a -> Recip a
(%*%) :: (C a, C b) => a -> b -> Mul a b
(%/%) :: (C a, C b) => a -> b -> Mul a (Recip b)
applyLeftMul :: (C u0, C u1, C v) => (u0 -> u1) -> Mul u0 v -> Mul u1 v
applyRightMul :: (C u0, C u1, C v) => (u0 -> u1) -> Mul v u0 -> Mul v u1
applyRecip :: (C u0, C u1) => (u0 -> u1) -> Recip u0 -> Recip u1
commute :: (C u0, C u1) => Mul u0 u1 -> Mul u1 u0
associateLeft :: (C u0, C u1, C u2) => Mul u0 (Mul u1 u2) -> Mul (Mul u0 u1) u2
associateRight :: (C u0, C u1, C u2) => Mul (Mul u0 u1) u2 -> Mul u0 (Mul u1 u2)
recipMul :: (C u0, C u1) => Recip (Mul u0 u1) -> Mul (Recip u0) (Recip u1)
mulRecip :: (C u0, C u1) => Mul (Recip u0) (Recip u1) -> Recip (Mul u0 u1)
identityLeft :: C u => Mul Scalar u -> u
identityRight :: C u => Mul u Scalar -> u
cancelLeft :: C u => Mul (Recip u) u -> Scalar
cancelRight :: C u => Mul u (Recip u) -> Scalar
invertRecip :: C u => Recip (Recip u) -> u
doubleRecip :: C u => u -> Recip (Recip u)
recipScalar :: Recip Scalar -> Scalar
class C dim => IsScalar dim where
 toScalar :: dim -> Scalar fromScalar :: Scalar -> dim
data Length = Length
data Time = Time
data Mass = Mass
data Charge = Charge
data Angle = Angle
data Temperature = Temperature
data Information = Information
length :: Length
time :: Time
mass :: Mass
charge :: Charge
angle :: Angle
temperature :: Temperature
information :: Information
type Frequency = Recip Time
frequency :: Frequency
data Voltage = Voltage
type VoltageAnalytical = Mul (Mul (Sqr Length) Mass) (Recip (Mul (Sqr Time) Charge))
voltage :: Voltage
unpackVoltage :: Voltage -> VoltageAnalytical
packVoltage :: VoltageAnalytical -> Voltage
Documentation
 class Show a => C a Source Instances
 C Voltage C Information C Temperature C Angle C Charge C Mass C Time C Length C Scalar C a => C (Recip a) (C a, C b) => C (Mul a b)
 noValue :: C a => a Source
Type constructors
 data Scalar Source
Constructors
 Scalar Instances
 Show Scalar IsScalar Scalar C Scalar
 data Mul a b Source
Constructors
 Mul Instances
 (Show a, Show b) => Show (Mul a b) (C a, C b) => C (Mul a b)
 data Recip a Source
Constructors
 Recip Instances
 Show a => Show (Recip a) C a => C (Recip a)
 type Sqr a = Mul a a Source
 appPrec :: Int Source
 scalar :: Scalar Source
 mul :: (C a, C b) => a -> b -> Mul a b Source
 recip :: C a => a -> Recip a Source
 (%*%) :: (C a, C b) => a -> b -> Mul a b Source
 (%/%) :: (C a, C b) => a -> b -> Mul a (Recip b) Source
Rewrites
 applyLeftMul :: (C u0, C u1, C v) => (u0 -> u1) -> Mul u0 v -> Mul u1 v Source
 applyRightMul :: (C u0, C u1, C v) => (u0 -> u1) -> Mul v u0 -> Mul v u1 Source
 applyRecip :: (C u0, C u1) => (u0 -> u1) -> Recip u0 -> Recip u1 Source
 commute :: (C u0, C u1) => Mul u0 u1 -> Mul u1 u0 Source
 associateLeft :: (C u0, C u1, C u2) => Mul u0 (Mul u1 u2) -> Mul (Mul u0 u1) u2 Source
 associateRight :: (C u0, C u1, C u2) => Mul (Mul u0 u1) u2 -> Mul u0 (Mul u1 u2) Source
 recipMul :: (C u0, C u1) => Recip (Mul u0 u1) -> Mul (Recip u0) (Recip u1) Source
 mulRecip :: (C u0, C u1) => Mul (Recip u0) (Recip u1) -> Recip (Mul u0 u1) Source
 identityLeft :: C u => Mul Scalar u -> u Source
 identityRight :: C u => Mul u Scalar -> u Source
 cancelLeft :: C u => Mul (Recip u) u -> Scalar Source
 cancelRight :: C u => Mul u (Recip u) -> Scalar Source
 invertRecip :: C u => Recip (Recip u) -> u Source
 doubleRecip :: C u => u -> Recip (Recip u) Source
 recipScalar :: Recip Scalar -> Scalar Source
Example dimensions
Scalar
 class C dim => IsScalar dim where Source
This class allows defining instances that are exclusively for Scalar dimension. You won't want to define instances by yourself.
Methods
 toScalar :: dim -> Scalar Source
 fromScalar :: Scalar -> dim Source Instances
 IsScalar Scalar
Basis dimensions
 data Length Source
Constructors
 Length Instances
 Show Length C Length
 data Time Source
Constructors
 Time Instances
 Show Time C Time
 data Mass Source
Constructors
 Mass Instances
 Show Mass C Mass
 data Charge Source
Constructors
 Charge Instances
 Show Charge C Charge
 data Angle Source
Constructors
 Angle Instances
 Show Angle C Angle
 data Temperature Source
Constructors
 Temperature Instances
 Show Temperature C Temperature
 data Information Source
Constructors
 Information Instances
 Show Information C Information
 length :: Length Source
 time :: Time Source
 mass :: Mass Source
 charge :: Charge Source
 angle :: Angle Source
 temperature :: Temperature Source
 information :: Information Source
Derived dimensions
 type Frequency = Recip Time Source
 frequency :: Frequency Source
 data Voltage Source
Constructors
 Voltage Instances
 Show Voltage C Voltage
 type VoltageAnalytical = Mul (Mul (Sqr Length) Mass) (Recip (Mul (Sqr Time) Charge)) Source
 voltage :: Voltage Source
 unpackVoltage :: Voltage -> VoltageAnalytical Source
 packVoltage :: VoltageAnalytical -> Voltage Source