On September 30, 1999, a story broke that NASA’s $125,000,000 Mars Climate Orbiter zoomed out of orbit, hit the atmosphere and burned to a crisp. Why? Because parts of the system used metric units, and other parts used English units. As a rule, science is done with metric units; only tradition and old-fogeyness could cause such a goof.
Unit confusion has an obvious solution: education. Science courses, especially Physics and Chemistry, stress the conversion and explicit marking of units. “5” could mean “5 inches”, “5 centimeters”, or even “5 years”.
But education is just one way to treat the problem. Another is to force scientists, engineers, and programmers to explicitly mark units. Haskell can do this with its type system. It’s called SafeUnits.
data Distance = Cm Double | In Double deriving (Eq)
And you’re ninety percent done. Your code can manipulate centimeters, inches, or both, but any function that takes or returns a Distance must explicitly handle each unit type.
data Farad = Farad Double deriving (Eq) capacitance :: Distance -> Farad capacitance (Cm x) = Farad (1.113e-12 * x)
Now you can calculate the capacitance of centimeters, but only in centimeters like a good scientist. Haskell will complain if you try any other unit.
> capacitance (Cm 1) 1.0 cm of capacitance = 1.113e-12 Farad > capacitance (In 1) safeunits.hs: safeunits.hs:25:0-41: Non-exhaustive patterns in function capacitance
If you’ve ever raged over a problem that didn’t specify units, you’re among friends.
Caveat 1: SafeUnits does not make inch-capacitance calculation impossible; it simply raises an error for inch-capacitance until the functionality is added.
Caveat 2: Eq is automatically derived, but not Ord. Because comparing units of measurement (<, >) is not something the type system can do intuitively. Declare instances for that kind of functionality.
Caveat 3: SafeUnits does not prevent programmers from writing Cm 1 and thinking In 1
Caveat 4: SafeUnits does not prevent programmers from unboxing Cm 1 to 1 and manipulating the raw Doubles.
And that’s how to use Haskell’s type system as an explicit reminder and strict enforcer of units.
U JELLY NASA?
You might want to read Troll Science to recoop that loss.