Successfully reported this slideshow.
We use your LinkedIn profile and activity data to personalize ads and to show you more relevant ads. You can change your ad preferences anytime.                             Upcoming SlideShare
×

# Type-checking Polymorphic Units for Astrophysics Research in Haskell

1,161 views

Published on

Talk by Takayuki Muranushi (me) in Haskell Symposium 2014, ICFP. "Type-checking Polymorphic Units for Astrophysics Research in Haskell." c.f. http://www.cis.upenn.edu/~eir/papers/2014/units/units.pdf for the full paper.

Published in: Science
• Full Name
Comment goes here.

Are you sure you want to Yes No
Your message goes here • Be the first to comment

### Type-checking Polymorphic Units for Astrophysics Research in Haskell

1. 1. Experience Report: Type‐checking Polymorphic Units for Astrophysics Research in Haskell Takayuki Muranushi Advanced Institute for Computational Science, RIKEN takayuki.muranushi@riken.jp Richard A. Eisenberg University of Pennsylvania eir@cis.upenn.edu
2. 2. July 23, 1983 . • Air Canada Flight 143, a Boeing 767‐233 was departing Montreal to Edmonton. • The fuel gauge is not working. • The crews use a backup system and manually calculated the amount of fuel to be refueled.
3. 3. Manual calculation mass of fuel required density of fuel volume to be refueled ÷ ＝ [kg] [pound/L] [*L] The correct calculation mass of fuel required density of fuel volume to be refueled ÷ ＝ [kg] [kg/L] [L] Flight 143 took off with 22,300 pounds of fuel to Edmonton, where 22,300 kg was actually needed.
4. 4. • Flight 143 made an emergency landing on runway 32L of Gimli abandoned airport. • It was “Family Day” festival; go‐carts, campers, families and barbecues were on 32L. • No one was seriously hurt nor killed. Wade H. Nelson (1997)
5. 5. A same law of physics can be represented in many different units Mass of Density of fuel Volume to be fuel required Dimensions Level: Mass ÷ Density ＝ Volume [kg] [kg/L] [L] ÷ ＝ [lb.] ÷ [lb./L] ＝ [L] Units Level: ÷ ＝ refueled Quantity Level: quantity value = numerical value [ unit ] [kg] ÷ [lb./L] ＝ [L]
6. 6. “units‐of‐measure are to science what types are to programming” ‐‐‐ A. J. Kennedy • To avoid mistakes like Gimli Glider, we would like to use type system to enforce the correctness of the dimensions and units in our calculations. • Such correctness of “laws of physics” is more than just about specific set of units; we can represent one quantity in many different units, but they mean the same quantity.
7. 7. “units‐of‐measure are to science what types are to programming” ‐‐‐ A. J. Kennedy “Laws of physics are dimension‐monomorphic and unit‐polymorphic” ‐‐‐ T. Muranushi Dimensions Level: Mass ÷ Density ＝ Volume [kg] ÷ [kg/L] ＝ [L] [lb.] ÷ [lb./L] ＝ [L] Units Level:
8. 8. “units‐of‐measure are to science what types are to programming” ‐‐‐ A. J. Kennedy “Laws of physics are dimension‐monomorphic and unit‐polymorphic” ‐‐‐ T. Muranushi • We already have type system of units for many languages including C, F#, simulink and of course in Haskell; we already have polymorphism. Will they blend?
9. 9. Using `unittyped` by Thijs Alkemade, I started an attempt to encode knowledge of physics in Haskell.
10. 10. A unit‐monomorphic quantity function refuel :: Fractional f => Value Mass KiloGram f ‐> Value Density KiloGramPerLiter f ‐> Value Volume Liter f refuel gasMass gasDen = gasMass |/| gasDen A unit‐polymorphic version? refuel :: Fractional f => Value Mass uniMass f ‐‐ Here we replace the unit types ‐> Value Density uniDen f ‐‐ with type variables ‐> Value Volume uniVol f ‐‐ refuel gasMass gasDen = gasMass |/| gasDen This code doesn’t compile.
11. 11. This code refuel :: Fractional f => Value Mass uniMass f ‐> Value Density uniDen f ‐> Value Volume uniVol f refuel gasMass gasDen = gasMass |/| gasDen needs these annotations to compile: refuel :: (Fractional f, Convertible' Mass uniMass, Convertible' Density uniDen, Convertible' Volume uniVol, MapNeg negUniDen uniDen, ‐‐ negUniDen = 1 / uniDen MapMerge uniMass negUniDen uniVol ‐‐ uniMass * negUniDen = uniVol ) => Value Mass uniMass f ‐> Value Density uniDen f ‐> Value Volume uniVol f refuel gasMass gasDen = gasMass |/| gasDen
13. 13. ↑ ✈ Problem ↓ ✈ Solution
14. 14. Our solution:
15. 15. Quantity representation in `unittyped` Type constructor takes (dimensions) (units) (numerical value) λ> :t 88 *| mile |/| hour … :: Fractional f => Value '[ '(Length, POne), '(Time, NOne)] '[ '(Mile, POne), '(Hour, NOne)] f Quantity representation in `units` Type constructor takes (dimensions) (map from dimensions to units) (numerical value ) λ> :t 88 % mile :/ hour :: Fractional f => Qu Velocity SI f … :: Fractional f => Qu '[ '(Length, One), '(Time, MOne)] '[ '(Length, Meter), '(Time, Second), …] f
16. 16. System of Units as type argument • The map from dimensions to units represents a system of units; e.g. SI system, CGS (centimeter–gram–second) system, etc. λ> 88 % Miles :/ Hour :: Qu Velocity SI Float 39.33952 m/s λ> :info SI type SI = MkLCSU '[(Length, Meter), (Mass, Kilo :@ Gram), (Time, Second), (Current, Ampere), (Temperature, Kelvin), (AmountOfSubstance, Mole), (LuminousIntensity, Lumen)] λ> :info CGS type CGS = MkLCSU '[(Length, Centi :@ Meter), (Mass, Gram), (Time, Second)]
17. 17. [Def] A coherent system of unit ℓ ℓ = {u1, u2, … , un}∪ {u1 p u2 q …un r | p,q, … , r ∈ } base units units derived by products of base units • A Joule (1 [kg/m2s2]) is the coherent derived unit of energy in SI • An erg (1 [g/cm2s2] = 10-7J) is the coherent derived unit of energy in centimeter‐gram‐second system 1:1 mapping between dimensions and units [kg] ÷ [kg/m3] ＝ [m3] [SI mass]÷ [SI density] ＝ [SI volume]
18. 18. Unit‐polymorphic calculations in `units` refuel :: Fractional f => Qu Mass ℓ f ‐> Qu Density ℓ f ‐> Qu Volume ℓ f refuel gasMass gasDen = gasMass |/| gasDen • local coherent system of unit ℓ is the only one, unconstrained, type variable • The computation is nondimensionalized; can be carried out without details units. [kg] ÷ [kg/m3] ＝ [m3] [SI mass]÷ [SI density] ＝ [SI volume]
19. 19. • Unit polymorphism with fundeps gave rise to overwhelming complexes of constrained type variables refuel :: (Fractional f, Convertible' Mass umass, Convertible' Density uden, Convertible' Volume uvol, MapNeg negUden uden, MapMerge umass negUden uvol) => Value Mass umass f ‐> Value Density uden f ‐> Value Volume uvol f refuel gasMass gasDen = gasMass |/| gasDen • Take local coherent system of unit ℓ as only one free variable refuel :: Fractional f => Qu Mass ℓ f ‐> Qu Density ℓ f ‐> Qu Volume ℓ f refuel gasMass gasDen = gasMass |/| gasDen
20. 20. An application: Avoid over/underflow
21. 21. Exercise: How many Newtons is the Lennard-Jones force F between two argon atoms at distance 4Å, where Solution #1: ljForce :: Energy ℓ Float ‐> Length ℓ Float ‐> Length ℓ Float ‐> Force ℓ Float ljForce eps sigma r = (24 *| eps |*| sigma |ˆ pSix) |/| (r |ˆ pSeven) |‐|(48 *| eps |*| sigma |ˆ pTwelve) |/| (r |ˆ pThirteen) λ> let sigmaAr = 3.4e‐8 % Meter epsAr = 1.68e‐21 % Joule r = 4.0e‐8 % Meter λ> (ljForce epsAr sigmaAr r :: Force SI Float) # Newton NaN
22. 22. Exercise: How many Newtons is the Lennard-Jones force F between two argon atoms at distance 4Å, where Solution #2: ljForce :: Energy ℓ Float ‐> Length ℓ Float ‐> Length ℓ Float ‐> Force ℓ Float ljForce eps sigma r = (24 *| eps |*| sigma |ˆ pSix) |/| (r |ˆ pSeven) |‐|(48 *| eps |*| sigma |ˆ pTwelve) |/| (r |ˆ pThirteen) type CU = MkLCSU '[ '(Length, Angstrom), '(Mass, ProtonMass), '(Time, Pico :@ Second)] λ> (ljForce epsAr sigmaAr r :: Force CU Float) # Newton 9.3407324e‐14
23. 23. Astrophysics research in Haskell • A 27‐page astrophysics paper has been written in Haskell; its quantitative reasoning is powered by the units library.
24. 24. ↑ ✈ Experience ↓ ✈ Conclusion
25. 25. When you design type system of units consider unit polymorphism because, with unit polymorphism • We can faithfully express unit‐independent nature of laws of physics. • We can write quantity expressions, which users can later interpret in unit systems of their choice. • We can avoid overflows/ underflows by appropriately choosing system of units.
26. 26. • An easy way to implement unit polymorphism is to take local coherent system of unit ℓ as only one free variable refuel :: Fractional f => Qu Mass ℓ f ‐> Qu Density ℓ f ‐> Qu Volume ℓ f refuel gasMass gasDen = gasMass |/| gasDen
27. 27. In the paper • Extensibility • Quantity combinators • Value‐level units • Protect numerical values from manipulation Things came after paper • defaultLCSU • Template Haskell
28. 28. Comments • Haskell is such a cool language that allows something like `units` at all. Its type system is so programmable that these features can be built on top of, instead of being integrated in (like F#) or externally analyzed (like C) • As far as we know, `units` is the only practical system that supports unit polymorphism. • Heartfelt thanks to all people’s work that enabled GHC 7.8, and to Richard who implemented `units`.
29. 29. ↑ ✈ Thanks! ↓ ✈ Questions? cabal install units and enjoy unit polymorphism! refuel :: Fractional f => Qu Mass ℓ f ‐> Qu Density ℓ f ‐> Qu Volume ℓ f refuel gasMass gasDen = gasMass |/| gasDen