tomahawkins / engineering-units

A numeric type to automatically manage engineering units in Haskell.
Other
6 stars 2 forks source link

Add type separation between quantities and units #2

Open fluffynukeit opened 10 years ago

fluffynukeit commented 10 years ago

Presently there is no type separation between quantities and units. This is something the dimensional package achieves with phantom types, and I think it would be useful in engineering-units.

For instance, the following are all valid expressions (including additions from PR #1 ).

cm * cm -- 1 cm2, good
cm / s -- 1 cm per second, good
2 * 2 :: Value -- 4 dimensionless, good
2 / 2 :: Value -- 1 dimensionless, good
1 * cm  -- 1 cm, good
cm * 1 -- 1 cm, bad
_c * 1 --  0.01 dimensionless, (add prefix to value??) bad

I think the type system should prevent the "bad" usages listed above. I propose the following:

data Value phant = ...
data DUnit
data DQuantity
type Unit = Value DUnit
type Quantity = Value DQuantity

Prefixes then operate on units: _c :: Value Unit -> Value Unit Num and Fractional instances for Unit can be used to construct new units e.g. kg * m / s Num and Fractional instances for Quantity can be used to do math: ( 10 [ kg) * (2 [ m) / (3 [ s) Quantity types are created by tagging a numeric value with a Unit using [. I picked this function because it's similar to the notation NIST uses for units, and the notation I've seen used in academia: [m]. Really it could be almost anything else reasonable.

One of the reasons I like the type separation between Units and Quantities is that units have value on their own. I'd like to use the units like this data DataArray = DataArray Unit (Vector Double) to associate an array of data with the units it is measured in.

I can whip this up anytime if you like this direction. I'm going to test it out on my fork and reference the changes here when it's ready.

fluffynukeit commented 10 years ago

I gave a first crack at this as a proof of concept in fluffynukeit/engineering-units@e81b9cb. I changed the terminology some to match NIST better. Specifically, length, time, etc are quantities; a numeric value is just a double; a value is a numeric value combined with units. I also had to use different operators than the ones I proposed originally because [ is reserved. I think the ones I picked are logical, but they contribute a lot to line noise because they are so similar to * and /, so there's still room for improvement.

This commit could use some additional polish in the doc and organization once it's decided whether these changes are desired.