Difference between revisions of "Physical units"

From HaskellWiki
Jump to navigation Jump to search
(darcs.haskell.org -> code.haskell.org)
(6 intermediate revisions by 4 users not shown)
Line 6: Line 6:
   
 
* NumericPrelude also contains an implementation of values equipped with physical units. However all unit checking is made dynamically, that is expressions like <hask>1 * meter < 2 * second</hask> are accepted by the Haskell compiler but lead to a runtime error. This design allows the programmer to process values from IO world with units, that are unknown at compile time, but it prohibits catching unit errors at compile time. Units are handled as integer vectors of exponents of base units. Computation with these vectors is rather simple, however formatting them is difficult. Formatting and parsing values with units is supported. A small library of SI units is provided.
 
* NumericPrelude also contains an implementation of values equipped with physical units. However all unit checking is made dynamically, that is expressions like <hask>1 * meter < 2 * second</hask> are accepted by the Haskell compiler but lead to a runtime error. This design allows the programmer to process values from IO world with units, that are unknown at compile time, but it prohibits catching unit errors at compile time. Units are handled as integer vectors of exponents of base units. Computation with these vectors is rather simple, however formatting them is difficult. Formatting and parsing values with units is supported. A small library of SI units is provided.
: http://code.haskell.org/numericprelude/src/Number/Physical.hs
+
: http://code.haskell.org/numeric-prelude/src/Number/Physical.hs
: http://code.haskell.org/numericprelude/src/Number/SI.hs
+
: http://code.haskell.org/numeric-prelude/src/Number/SI.hs
   
:Get with <code>darcs get http://code.haskell.org/numericprelude/</code>
+
:Get with <code>darcs get http://code.haskell.org/numeric-prelude/</code>
   
  +
* The {{HackagePackage|id=quantities}} package uses an expression parser to create units. For example:
* poor man's type level [http://code.haskell.org/numericprelude/src/Number/DimensionTerm.hs physical dimensions] in [[Numeric Prelude]]
 
  +
:<code>>>> fromString "(1m + 1ft + 2 yard + 50in) * 5 / (8 km/h) => minute"
  +
:Right 0.16513500000000006 minute</code>
  +
  +
:Of course, this is not verified with the type checker. It uses a custom error type to report issues like undefined units or improper conversions.
  +
 
* poor man's type level [http://code.haskell.org/numeric-prelude/src/Number/DimensionTerm.hs physical dimensions] in [[Numeric Prelude]]
  +
  +
* See also the [http://www.cis.upenn.edu/~eir/packages/units/ units] package, which uses type families to implement a domain-specific type system for dimension-checked programming. It works only with GHC 7.8+.
   
 
* [[CalDims]]
 
* [[CalDims]]
   
  +
* {{HackagePackage|id=unittyped}}
  +
  +
* {{HackagePackage|id=Measure}} - Encompasses a few units, currently has build failure on ghc >= 7.0.
  +
  +
* {{HackagePackage|id=time-units}} - for time units only.
  +
  +
* [https://github.com/aavogt/DimMat DimMat] - statically typed units for some operations provided by {{HackagePackage|id=hmatrix}}, where the scalars have the same types as {{HackagePackage|id=dimensional-tf}}
   
 
[[Category:Mathematics]]
 
[[Category:Mathematics]]

Revision as of 14:51, 16 April 2014

How would one go about modeling units (seconds, meters, meters per second, etc) in Haskell? I'm particularly interested in getting the typechecker to verify proper usage, and do not want to restrict it to any particular numeric representation (i.e. both integral seconds and fractional seconds). If this can in fact be done, it could also be used to model coordinate system axes in, say, Geometric Algebra.

  • It can. Look at Dimensionalized numbers for a toy implementation. I've thought a bit about the Geometric Algebra case, but I can't see a good way of handling it without forcing a choice of basis. I'm also not sure how it would work -- the whole point of GA is to incorporate areas, lengths, volumes, etc. into one number type. I suppose we could use this type of technique to segregate GA spaces with different dimensions or even metrics. --AaronDenney
  • A (non-toy) implementation of statically checked physical dimensions with a complete set of dimensions (but limited number of predefined units) is Dimensional. I apologize for coming up with the same name as Aaron and am on the lookout for a new one. I cannot comment on the applicability to GA. --Bjorn
  • NumericPrelude also contains an implementation of values equipped with physical units. However all unit checking is made dynamically, that is expressions like 1 * meter < 2 * second are accepted by the Haskell compiler but lead to a runtime error. This design allows the programmer to process values from IO world with units, that are unknown at compile time, but it prohibits catching unit errors at compile time. Units are handled as integer vectors of exponents of base units. Computation with these vectors is rather simple, however formatting them is difficult. Formatting and parsing values with units is supported. A small library of SI units is provided.
http://code.haskell.org/numeric-prelude/src/Number/Physical.hs
http://code.haskell.org/numeric-prelude/src/Number/SI.hs
Get with darcs get http://code.haskell.org/numeric-prelude/
  • The quantities package uses an expression parser to create units. For example:
>>> fromString "(1m + 1ft + 2 yard + 50in) * 5 / (8 km/h) => minute"
Right 0.16513500000000006 minute
Of course, this is not verified with the type checker. It uses a custom error type to report issues like undefined units or improper conversions.
  • See also the units package, which uses type families to implement a domain-specific type system for dimension-checked programming. It works only with GHC 7.8+.
  • Measure - Encompasses a few units, currently has build failure on ghc >= 7.0.