convert-units: Arithmetic and type checked conversions between units.

[ bsd3, data, library, math, numeric, physics ] [ Propose Tags ] [ Report a vulnerability ]
Versions [RSS] 0
Change log CHANGELOG.md
Dependencies base (>=4.18 && <5), template-haskell (>=2.21.0) [details]
License BSD-3-Clause
Copyright BSD 3
Author Alice Rixte
Maintainer alice.rixte@u-bordeaux.fr
Category Physics, Data, Numeric, Math
Home page https://github.com/AliceRixte/convert-units#readme
Bug tracker https://github.com/AliceRixte/convert-units/issues
Source repo head: git clone https://github.com/AliceRixte/convert-units
Uploaded by AliceRixte at 2025-09-08T17:06:13Z
Distributions
Downloads 3 total (3 in the last 30 days)
Rating (no votes yet) [estimated by Bayesian average]
Your Rating
  • λ
  • λ
  • λ
Status Docs uploaded by user
Build status unknown [no reports yet]

Readme for convert-units-0

[back to package description]

convert-units

Haskell BSD3 License Hackage Nightly LTS

A Haskell library to convert between units, that will statically check the dimensions of the units being converted.

Conversions are usually as fast as manual multiplication by a conversion factor, thanks to heavy use of inlining.

Usage

You will need the TypeApplications extension:

>>> :set -XTypeApplications

Convert between units

You can use to or fromTo for conversions:

>>> t = Hour 8
>>> to @Minute t
Minute 480.0

>>> fromTo @Hour @Minute 8
Minute 480.0

User-friendly static errors when trying to convert between incompatible dimensions:

>>> fromTo @Minute @Meter 1
• Cannot convert unit ‘min’ to unit ‘m’ because their dimensions do not match.
      Dimension of ‘min’ is: T
      Dimension of ‘m’ is: L

There are two sorts of unit conversions:

  1. The regular ones
>>> fromTo @Celsius @Kelvin 0
Kelvin 273.15
  1. Conversion that only takes the conversion factor into account (and not potential offsets):
>>> fromTo' @Celsius @Kelvin 0
Kelvin 0.0

Pretty printing

>>> putQuantity (Celsius 25)
25 °C
>>> putQuantity (quantity @(Kilo Meter ./. Hour) 130)
130 km⋅hr⁻¹

Get info about some unit:

>>> putInfoU @Newton
Unit:       Newton
 abbr:      N
Dimension:  Mass .*. Length .*. Time.^-2
 abbr:      M⋅L⋅T⁻²
Normalized: Kilo Gram .*. Meter .*. Second.^-2
 abbr:      kg⋅m⋅s⁻²

Unit arithmetics

Multiplication by a scalar:

>>> 2 * Meter 4
Meter 8

You can multiply or divide two units:

>>> putQuantity $ Newton 1 .*. Meter 2
2 N⋅m
>>> v = Kilo (Meter 10) ./. Hour 2
>>> putQuantity v
5.0 km⋅hr⁻¹
>>> putQuantity $ to @(Meter ./. Second) v
1.3888888888888888 m⋅s⁻¹

Automatically simplify units by converting the right unit :

>>> putQuantity $ Kilo (Meter 2) .*~  Meter 3
6.0e-3 km²

or the left unit:

>>> putQuantity $ Kilo (Meter 2) ~*.  Meter 3
6000.0 m²

Convert to and from SI base units

>>> v = toBaseUnit (quantity @(Kilo Meter ./. Hour) 36)
>>> putQuantity v
10.0 m⋅s⁻¹

Make your own units, prefixes and dimensions

Make a new dimension with its associated base unit:

$(mkDim "Angle" "A" 1000)
$(mkBaseUnit "Radian" "rad" ''Angle)

Make a new unit convertible by multiplying with some factor:

$(mkUnit "Minute" "min" ''Time 60)

Make a new prefix:

$(mkPrefix "Micro" "µ" 1e-6)

Make a new unit with special conversion:

$(mkUnitNoFactor "Fahrenheit" "°F" ''Temperature)

instance Fractional a => ConversionFactor Fahrenheit a where
  factor = 5 / 9
  {-# INLINE factor #-}

instance Fractional a => ConvertibleUnit Fahrenheit a where
  toBaseUnit (Fahrenheit x) = Kelvin ((x + 459.67) * 5 / 9)
  {-# INLINE toBaseUnit #-}

  fromBaseUnit (Kelvin x) = Fahrenheit (x * 9 / 5 - 459.67)
  {-# INLINE fromBaseUnit #-}

Comparison with other Haskell unit libraries

There are other excellent units libraries out there, the two most used being:

Compared to these two libraries, convert-units offers

  • Greater flexibility for conversions that do not use conversion factors, for instance for logarithmic units (see logarithmic pitch units in Data.Unit.NonStd.Frequency for instance)
  • The possibility to add dimensions, such as Angle, Information (not yet implemented, see this wikipedia article), and so on ...
Feature convert-units dimensional units
Static dimension checking
Custom unit
Custom prefixes
Custom dimensions
Pretty-printing units
Offset-aware conversions (e.g. °C/K)
Any conversion