ianmackenzie / elm-units / Quantity


type Quantity number units
    = Quantity number

A Quantity is effectively a number (an Int or Float) tagged with a units type. So a

Quantity Float Meters

is a Float number of Meters and a

Quantity Int Pixels

is an Int number of Pixels. When compiling with elm make --optimize the Quantity wrapper type will be compiled away, so the runtime performance should be comparable to using a raw Float or Int.

Unit types

The Squared, Cubed, Product and Rate units types allow you to build up and work with composite units in a fairly flexible way.


type alias Squared units =
Product units units

Represents a units type that is the square of some other units type; for example, Meters is one units type (the units type of a Length) and Squared Meters is another (the units type of an Area). See the squared and sqrt functions for examples of use.

This is a special case of the Product units type.


type alias Cubed units =
Product (Product units units) units

Represents a units type that is the cube of some other units type; for example, Meters is one units type (the units type of a Length) and Cubed Meters is another (the units type of an Volume). See the cubed and cbrt functions for examples of use.

This is a special case of the Product units type.


type Product units1 units2

Represents a units type that is the product of two other units types. This is a more general form of Squared or Cubed. See product, times, over and over_ for how it can be used.


type Rate dependentUnits independentUnits

Represents the units type of a rate or quotient such as a speed (Rate Meters Seconds) or a pressure (Rate Newtons SquareMeters). See Working with rates for details.

Constants

zero : Quantity number units

A generic zero value. This can be treated as either an Int or Float quantity in any units type, similar to how Nothing can be treated as any kind of Maybe type and [] can be treated as any kind of List.

infinity : Quantity Basics.Float units

Alias for positiveInfinity.

positiveInfinity : Quantity Basics.Float units

A generic positive infinity value.

negativeInfinity : Quantity Basics.Float units

A generic negative infinity value.

Comparison

lessThan : Quantity number units -> Quantity number units -> Basics.Bool

Check if one quantity is less than another. Note the argument order!

oneMeter =
    Length.meters 1

Length.feet 1 |> Quantity.lessThan oneMeter
--> True

-- Same as:
Quantity.lessThan oneMeter (Length.feet 1)
--> True

List.filter (Quantity.lessThan oneMeter)
    [ Length.feet 1
    , Length.parsecs 1
    , Length.yards 1
    , Length.lightYears 1
    ]
--> [ Length.feet 1, Length.yards 1 ]

greaterThan : Quantity number units -> Quantity number units -> Basics.Bool

Check if one quantity is greater than another. Note the argument order!

oneMeter =
    Length.meters 1

Length.feet 1 |> Quantity.greaterThan oneMeter
--> False

-- Same as:
Quantity.greaterThan oneMeter (Length.feet 1)
--> False

List.filter (Quantity.greaterThan oneMeter)
    [ Length.feet 1
    , Length.parsecs 1
    , Length.yards 1
    , Length.lightYears 1
    ]
--> [ Length.parsecs 1, Length.lightYears 1 ]

lessThanOrEqualTo : Quantity number units -> Quantity number units -> Basics.Bool

Check if one quantity is less than or equal to another. Note the argument order!

greaterThanOrEqualTo : Quantity number units -> Quantity number units -> Basics.Bool

Check if one quantity is greater than or equal to another. Note the argument order!

lessThanZero : Quantity number units -> Basics.Bool

Short form for Quantity.lessThan Quantity.zero.

greaterThanZero : Quantity number units -> Basics.Bool

Short form for Quantity.greaterThan Quantity.zero.

lessThanOrEqualToZero : Quantity number units -> Basics.Bool

Short form for Quantity.lessThanOrEqualTo Quantity.zero.

greaterThanOrEqualToZero : Quantity number units -> Basics.Bool

Short form for Quantity.greaterThanOrEqualTo Quantity.zero.

compare : Quantity number units -> Quantity number units -> Basics.Order

Compare two quantities, returning an Order value indicating whether the first is less than, equal to or greater than the second.

Quantity.compare
    (Duration.minutes 90)
    (Duration.hours 1)
--> GT

Quantity.compare
    (Duration.minutes 60)
    (Duration.hours 1)
--> EQ

equalWithin : Quantity number units -> Quantity number units -> Quantity number units -> Basics.Bool

Check if two quantities are equal within a given absolute tolerance. The given tolerance must be greater than or equal to zero - if it is negative, then the result will always be false.

-- 3 feet is 91.44 centimeters or 0.9144 meters

Quantity.equalWithin (Length.centimeters 10)
    (Length.meters 1)
    (Length.feet 3)
--> True

Quantity.equalWithin (Length.centimeters 5)
    (Length.meters 1)
    (Length.feet 3)
--> False

max : Quantity number units -> Quantity number units -> Quantity number units

Find the maximum of two quantities.

Quantity.max (Duration.hours 2) (Duration.minutes 100)
--> Duration.hours 2

min : Quantity number units -> Quantity number units -> Quantity number units

Find the minimum of two quantities.

Quantity.min (Duration.hours 2) (Duration.minutes 100)
--> Duration.minutes 100

isNaN : Quantity Basics.Float units -> Basics.Bool

Check if a quantity's underlying value is NaN (not-a-number).

Quantity.isNan (Quantity.sqrt (Area.squareMeters -4))
--> True

Quantity.isNan (Quantity.sqrt (Area.squareMeters 4))
--> False

isInfinite : Quantity Basics.Float units -> Basics.Bool

Check if a quantity is positive or negative infinity.

Quantity.isInfinite
    (Length.meters 1
        |> Quantity.per (Duration.seconds 0)
    )
--> True

Quantity.isInfinite Quantity.negativeInfinity
--> True

Arithmetic

negate : Quantity number units -> Quantity number units

Negate a quantity!

Quantity.negate (Length.millimeters 10)
--> Length.millimeters -10

abs : Quantity number units -> Quantity number units

Get the absolute value of a quantity.

Quantity.abs (Duration.milliseconds -10)
--> Duration.milliseconds 10

plus : Quantity number units -> Quantity number units -> Quantity number units

Add two quantities.

Length.meters 1 |> Quantity.plus (Length.centimeters 5)
--> Length.centimeters 105

difference : Quantity number units -> Quantity number units -> Quantity number units

Subtract one quantity from another.

Quantity.difference
    (Duration.hours 1)
    (Duration.minutes 15)
--> Duration.minutes 45

minus : Quantity number units -> Quantity number units -> Quantity number units

An 'infix' version of difference, intended to be used in pipeline form;

Quantity.difference x y

can be written as

x |> Quantity.minus y

Note that unlike difference, this also means that partial application will 'do the right thing':

List.map (Quantity.minus fifteenMinutes)
    [ Duration.hours 1
    , Duration.hours 2
    , Duration.minutes 30
    ]
--> [ Duration.minutes 45
--> , Duration.minutes 105
--> , Duration.minutes 15
--> ]

multiplyBy : number -> Quantity number units -> Quantity number units

Scale a Quantity by a number.

Quantity.multiplyBy 1.5 (Duration.hours 1)
--> Duration.minutes 90

Note that there are other forms of multiplication!

divideBy : Basics.Float -> Quantity Basics.Float units -> Quantity Basics.Float units

Divide a Quantity by a Float.

Quantity.divideBy 2 (Duration.hours 1)
--> Duration.minutes 30

Note that there are other forms of division!

twice : Quantity number units -> Quantity number units

Convenient shorthand for Quantity.multiplyBy 2.

Quantity.twice (Duration.minutes 30)
--> Duration.hours 1

half : Quantity Basics.Float units -> Quantity Basics.Float units

Convenient shorthand for Quantity.multiplyBy 0.5.

Quantity.half (Length.meters 1)
--> Length.centimeters 50

ratio : Quantity Basics.Float units -> Quantity Basics.Float units -> Basics.Float

Find the ratio of two quantities with the same units.

Quantity.ratio (Length.miles 1) (Length.yards 1)
--> 1760

squared : Quantity number units -> Quantity number (Squared units)

Square a quantity with some units, resulting in a new quantity in Squared units:

Quantity.squared (Length.meters 5)
--> Area.squareMeters 25

See also squaredUnitless.

sqrt : Quantity Basics.Float (Squared units) -> Quantity Basics.Float units

Take a quantity in Squared units and return the square root of that quantity in plain units:

Quantity.sqrt (Area.hectares 1)
--> Length.meters 100

Getting fancier, you could write a 2D hypotenuse (magnitude) function that worked on any quantity type (length, speed, force...) as

hypotenuse :
    Quantity Float units
    -> Quantity Float units
    -> Quantity Float units
hypotenuse x y =
    Quantity.sqrt
        (Quantity.squared x
            |> Quantity.plus
                (Quantity.squared y)
        )

This works because:

See also sqrtUnitless.

cubed : Quantity number units -> Quantity number (Cubed units)

Cube a quantity with some units, resulting in a new quantity in Cubed units.

Quantity.cubed (Length.meters 5)
--> Volume.cubicMeters 125

See also cubedUnitless.

cbrt : Quantity Basics.Float (Cubed units) -> Quantity Basics.Float units

Take a quantity in Cubed units and return the cube root of that quantity in plain units.

Quantity.cbrt (Volume.liters 1)
--> Length.centimeters 10

See also cbrtUnitless.

Unitless quantities

Some specialized arithmetic functions for working with unitless quantities. squaredUnitless, sqrtUnitless, cubedUnitless and cbrtUnitless all behave just like their non-Unitless versions but return a Unitless result (instead of for example something meaningless like Squared Unitless).

squaredUnitless : Quantity number Unitless -> Quantity number Unitless

sqrtUnitless : Quantity Basics.Float Unitless -> Quantity Basics.Float Unitless

cubedUnitless : Quantity number Unitless -> Quantity number Unitless

cbrtUnitless : Quantity Basics.Float Unitless -> Quantity Basics.Float Unitless

reciprocal : Quantity Basics.Float Unitless -> Quantity Basics.Float Unitless

Find the inverse of a unitless value.

Quantity.reciprocal (Quantity.float 5)
--> Quantity.float 0.2

Working with products

product : Quantity number units1 -> Quantity number units2 -> Quantity number (Product units1 units2)

Multiply two quantities with units types units1 and units2 together, resulting in a quantity with units type Product units1 units2.

This works for any two units types, but one special case is worth pointing out. The units type of an Area is SquareMeters, which is a type alias for Squared Meters, which in turn expands to Product Meters Meters. This means that the product of two Lengths does in fact give you an Area:

-- This is the definition of an acre, I kid you not 😈
Quantity.product (Length.feet 66) (Length.feet 660)
--> Area.acres 1

We can also multiply an Area by a Length to get a Volume:

Quantity.product
    (Area.squareMeters 1)
    (Length.centimers 1)
--> Volume.liters 10

Note that there are other forms of multiplication!

times : Quantity number units2 -> Quantity number units1 -> Quantity number (Product units1 units2)

An 'infix' version of product, intended to be used in pipeline form;

Quantity.product a b

can be written as

a |> Quantity.times b

timesUnitless : Quantity number Unitless -> Quantity number units -> Quantity number units

If you use times or product to multiply one quantity by another unitless quantity, for example

quantity |> Quantity.times unitlessQuantity

then the result you'll get will have units type Product units Unitless. But this is silly and not super useful, since the product of units and Unitless should really just be units. That's what timesUnitless does - it's a special case of times for when you're multiplying by another unitless quantity, that leaves the units alone.

You can think of timesUnitless as shorthand for toFloat and multiplyBy; for Float-valued quantities,

quantity |> Quantity.timesUnitless unitlessQuantity

is equivalent to

quantity
    |> Quantity.multiplyBy
        (Quantity.toFloat unitlessQuantity)

over : Quantity Basics.Float units1 -> Quantity Basics.Float (Product units1 units2) -> Quantity Basics.Float units2

Divide a quantity in Product units1 units2 by a quantity in units1, resulting in another quantity in units2. For example, the units type of a Force is Product Kilograms MetersPerSecondSquared (mass times acceleration), so we could divide a force by a given mass to determine how fast that mass would be accelerated by the given force:

Force.newtons 100
    |> Quantity.over
        (Mass.kilograms 50)
--> Acceleration.metersPerSecondSquared 2

Note that there are other forms of division!

over_ : Quantity Basics.Float units2 -> Quantity Basics.Float (Product units1 units2) -> Quantity Basics.Float units1

Just like over but divide by a quantity in units2, resulting in another quantity in units1. For example, we could divide a force by a desired acceleration to determine how much mass could be accelerated at that rate:

Force.newtons 100
    |> Quantity.over_
        (Acceleration.metersPerSecondSquared 5)
--> Mass.kilograms 20

overUnitless : Quantity Basics.Float Unitless -> Quantity Basics.Float units -> Quantity Basics.Float units

Similar to timesUnitless, overUnitless lets you divide one quantity by a second unitless quantity without affecting the units;

quantity |> Quantity.overUnitless unitlessQuantity

is equivalent to

quantity
    |> Quantity.divideBy
        (Quantity.toFloat unitlessQuantity)

Working with rates

rate : Quantity Basics.Float dependentUnits -> Quantity Basics.Float independentUnits -> Quantity Basics.Float (Rate dependentUnits independentUnits)

Construct a rate of change by dividing a dependent quantity (numerator) by an independent quantity (denominator):

speed =
    Quantity.rate (Length.miles 1) Duration.minute

speed |> Speed.inMilesPerHour
--> 60

Note that we could directly use our rate of change value as a Speed! That is because many built-in quantity types are defined as rates of change, for example:

Note that there are other forms of division!

per : Quantity Basics.Float independentUnits -> Quantity Basics.Float dependentUnits -> Quantity Basics.Float (Rate dependentUnits independentUnits)

'Infix' version of rate, meant to be used in pipeline form;

Quantity.rate distance time

can be written as

distance |> Quantity.per time

at : Quantity number (Rate dependentUnits independentUnits) -> Quantity number independentUnits -> Quantity number dependentUnits

Multiply a rate of change by an independent quantity (the denominator in the rate) to get a total value:

Duration.minutes 30
    |> Quantity.at
        (Speed.kilometersPerHour 100)
--> Length.kilometers 50

Can be useful to define conversion functions from one unit to another, since if you define a rate then Quantity.at rate will give you a conversion function:

pixelDensity : Quantity Float (Rate Pixels Meters)
pixelDensity =
    Pixels.pixels 96 |> Quantity.per (Length.inches 1)

lengthToPixels : Length -> Quantity Float Pixels
lengthToPixels length =
    Quantity.at pixelDensity length

lengthToPixels (Length.inches 3)
--> Pixels.pixels 288

Eagle-eyed readers will note that using partial application you could also simply write

lengthToPixels =
    Quantity.at pixelDensity

Note that there are other forms of multiplication!

at_ : Quantity Basics.Float (Rate dependentUnits independentUnits) -> Quantity Basics.Float dependentUnits -> Quantity Basics.Float independentUnits

Given a rate and a dependent quantity (total value), determine the necessary amount of the independent quantity:

Length.kilometers 75
    |> Quantity.at_
        (Speed.kilometersPerHour 100)
--> Duration.minutes 45

Where at performs multiplication, at_ performs division - you multiply a speed by a duration to get a distance, but you divide a distance by a speed to get a duration.

Similar to at, at_ can be used to define an inverse conversion function:

pixelDensity : Quantity Float (Rate Pixels Meters)
pixelDensity =
    Pixels.pixels 96 |> Quantity.per (Length.inches 1)

pixelsToLength : Quantity Float Pixels -> Length
pixelsToLength pixels =
    Quantity.at_ pixelDensity pixels

pixelsToLength (Pixels.pixels 48)
--> Length.inches 0.5

for : Quantity number independentUnits -> Quantity number (Rate dependentUnits independentUnits) -> Quantity number dependentUnits

Same as at but with the argument order flipped, which may read better in some cases:

Speed.kilometersPerHour 100
    |> Quantity.for
        (Duration.minutes 30)
--> Length.kilometers 50

inverse : Quantity Basics.Float (Rate dependentUnits independentUnits) -> Quantity Basics.Float (Rate independentUnits dependentUnits)

Find the inverse of a given rate. May be useful if you are using a rate to define a conversion, and want to convert the other way;

Quantity.at (Quantity.inverse rate)

is equivalent to

Quantity.at_ rate

rateProduct : Quantity Basics.Float (Rate units2 units1) -> Quantity Basics.Float (Rate units3 units2) -> Quantity Basics.Float (Rate units3 units1)

Multiply two rates of change that 'cancel out' together, resulting in a new rate. For example, if you know the real-world speed of an on-screen object and the display resolution, then you can get the speed in pixels per second:

realWorldSpeed =
    Speed.metersPerSecond 0.1

resolution =
    Pixels.float 96 |> Quantity.per Length.inch

Quantity.rateProduct realWorldSpeed resolution
--> Pixels.pixelsPerSecond 377.95

That is, "length per duration" multiplyed by "pixels per length" gives you "pixels per duration".

Sometimes you can't directly multiply two rates to get what you want, in which case you may need to use inverse in combination with rateProduct. For example, if you know the on-screen speed of some object and the display resolution, then you can use those to get the real-world speed:

pixelSpeed =
    Pixels.pixelsPerSecond 500

resolution =
    Pixels.float 96 |> Quantity.per Length.inch

Quantity.rateProduct pixelSpeed
    (Quantity.inverse resolution)
--> Speed.metersPerSecond 0.1323

Modular arithmetic

modBy and remainderBy behave just like the modBy and remainderBy functions from Elm's built-in Basics module, but work on Quantity values instead of raw Ints. fractionalModBy and fractionalRemainderBy have the same behaviour but extended to Float-valued quantities.

import Pixels exposing (pixels)
import Length exposing (meters, centimeters)

Quantity.modBy (pixels 4) (pixels 11)
--> pixels 3

Quantity.fractionalModBy (meters 0.5)
    (centimeters 162.3)
--> centimeters 12.3

modBy : Quantity Basics.Int units -> Quantity Basics.Int units -> Quantity Basics.Int units

fractionalModBy : Quantity Basics.Float units -> Quantity Basics.Float units -> Quantity Basics.Float units

remainderBy : Quantity Basics.Int units -> Quantity Basics.Int units -> Quantity Basics.Int units

fractionalRemainderBy : Quantity Basics.Float units -> Quantity Basics.Float units -> Quantity Basics.Float units

Miscellaneous

clamp : Quantity number units -> Quantity number units -> Quantity number units -> Quantity number units

Given a lower and upper bound, clamp a given quantity to within those bounds. Say you wanted to clamp an angle to be between +/-30 degrees:

lowerBound =
    Angle.degrees -30

upperBound =
    Angle.degrees 30

Quantity.clamp lowerBound upperBound (Angle.degrees 5)
--> Angle.degrees 5

-- One radian is approximately 57 degrees
Quantity.clamp lowerBound upperBound (Angle.radians 1)
--> Angle.degrees 30

Quantity.clamp lowerBound upperBound (Angle.turns -0.5)
--> Angle.degrees -30

sign : Quantity Basics.Float units -> Basics.Float

Get the sign of a quantity. This will return 1, -1, 0 or NaN if the given quantity is positive, negative, zero or NaN respectively.

Quantity.sign (Length.meters 3)
--> 1

Quantity.sign (Length.meters -3)
--> -1

Quantity.sign (Length.meters 0)
--> 0

Quantity.sign Quantity.positiveInfinity
--> 1

Quantity.sign (Length.meters (0 / 0))
--> NaN

interpolateFrom : Quantity Basics.Float units -> Quantity Basics.Float units -> Basics.Float -> Quantity Basics.Float units

Interpolate from the first quantity to the second, based on a parameter that ranges from zero to one. Passing a parameter value of zero will return the start value and passing a parameter value of one will return the end value.

fiveMeters =
    Length.meters 5

tenMeters =
    Length.meters 10

Quantity.interpolateFrom fiveMeters tenMeters 0
--> Length.meters 5

Quantity.interpolateFrom fiveMeters tenMeters 1
--> Length.meters 10

Quantity.interpolateFrom fiveMeters tenMeters 0.6
--> Length.meters 8

The end value can be less than the start value:

Quantity.interpolateFrom tenMeters fiveMeters 0.1
--> Length.meters 9.5

Parameter values less than zero or greater than one can be used to extrapolate:

Quantity.interpolateFrom fiveMeters tenMeters 1.5
--> Length.meters 12.5

Quantity.interpolateFrom fiveMeters tenMeters -0.5
--> Length.meters 2.5

Quantity.interpolateFrom tenMeters fiveMeters -0.2
--> Length.meters 11

midpoint : Quantity Basics.Float units -> Quantity Basics.Float units -> Quantity Basics.Float units

Find the midpoint between two quantities.

Quantity.midpoint (Length.meters 5) (Length.meters 10)
--> Length.meters 7.5

range : { start : Quantity Basics.Float units, end : Quantity Basics.Float units, steps : Basics.Int } -> List (Quantity Basics.Float units)

Construct a range of evenly-spaced values given a start value, an end value and the number of steps to take from the start to the end. The first value in the returned list will be equal to start and the last value will be equal to end. Note that the number of returned values will be one greater than the number of steps!

Quantity.range
    { start = Length.meters 2
    , end = Length.meters 3
    , steps = 5
    }
--> [ Length.centimeters 200
--> , Length.centimeters 220
--> , Length.centimeters 240
--> , Length.centimeters 260
--> , Length.centimeters 280
--> , Length.centimeters 300
--> ]

The start and end values can be in either order:

Quantity.range
    { start = Duration.hours 1
    , end = Quantity.zero
    , steps = 4
    }
--> [ Duration.minutes 60
--> , Duration.minutes 45
--> , Duration.minutes 30
--> , Duration.minutes 15
--> , Duration.minutes 0
--> ]

Passing a negative or zero steps value will result in an empty list being returned.

If you need finer control over what values get generated, try combining interpolateFrom with the various functions in the elm-1d-parameter package. For example:

-- Same as using Quantity.range
Parameter1d.steps 4 <|
    Quantity.interpolateFrom
        (Length.meters 2)
        (Length.meters 3)
--> [ Length.centimeters 200
--> , Length.centimeters 225
--> , Length.centimeters 250
--> , Length.centimeters 275
--> , Length.centimeters 300
--> ]

-- Omit the last value
Parameter1d.leading 4 <|
    Quantity.interpolateFrom
        (Length.meters 2)
        (Length.meters 3)
--> [ Length.centimeters 200
--> , Length.centimeters 225
--> , Length.centimeters 250
--> , Length.centimeters 275
--> ]

in_ : (Basics.Float -> Quantity Basics.Float units) -> Quantity Basics.Float units -> Basics.Float

Generalized units conversion function that lets you convert to many kinds of units not directly supported by elm-units. The first argument is a function that constructs a value of the desired unit type, and the second is the quantity to convert. For example,

Speed.metersPerSecond 5
    |> Speed.inFeetPerSecond
--> 16.4042

is equivalent to

Speed.metersPerSecond 5
    |> Quantity.in_ Speed.feetPerSecond
--> 16.4042

More interestingly, if you wanted to get speed in some weirder unit like millimeters per minute (not directly supported by elm-units), you could do

Speed.metersPerSecond 5
    |> Quantity.in_
        (Length.millimeters
            >> Quantity.per (Duration.minutes 1)
        )
--> 300000

Internally,

Quantity.in_ someUnits someQuantity

is simply implemented as

Quantity.ratio someQuantity (someUnits 1)

Int/Float conversion

These functions only really make sense for quantities in units like pixels, cents or game tiles where an Int number of units is meaningful. For quantities like Length or Duration, it doesn't really make sense to round to an Int value since the underyling base unit is pretty arbitrary - should rounding a Duration give you an Int number of seconds, milliseconds, or something else? (The actual behavior is that quantities will generally get rounded to the nearest SI base unit, since that is how they are stored internally - for example, Length values will get rounded to the nearest meter regardless of whether they were constructed from a number of meters, centimeters, inches or light years.)

round : Quantity Basics.Float units -> Quantity Basics.Int units

Round a Float-valued quantity to the nearest Int. Note that this may not do what you expect.

Quantity.round (Pixels.pixels 3.5)
--> Pixels.pixels 4

floor : Quantity Basics.Float units -> Quantity Basics.Int units

Round a Float-valued quantity down to the nearest Int. Note that this may not do what you expect.

Quantity.floor (Pixels.pixels 2.9)
--> Pixels.pixels 2

Quantity.floor (Pixels.pixels -2.1)
--> Pixels.pixels -3

ceiling : Quantity Basics.Float units -> Quantity Basics.Int units

Round a Float-valued quantity up to the nearest Int. Note that this may not do what you expect.

Quantity.ceiling (Pixels.pixels 1.2)
--> Pixels.pixels 2

Quantity.ceiling (Pixels.pixels -2.1)
--> Pixels.pixels -2

truncate : Quantity Basics.Float units -> Quantity Basics.Int units

Round a Float-valued quantity towards zero. Note that this may not do what you expect.

Quantity.truncate (Pixels.pixels -2.8)
--> Pixels.pixels -2

toFloatQuantity : Quantity Basics.Int units -> Quantity Basics.Float units

Convert a Quantity Int units to a Quantity Float units with the same value. Useful when you have an Int-valued quantity and want to divide it by something, multiply it by a fractional value etc.

List functions

These functions act just like the corresponding functions in the built-in List module (or, int the case of minimumBy and maximumBy, the List.Extra module from elm-community/list-extra). They're necessary because the built-in List.sum only supports List Int and List Float, and the remaining functions only support built-in comparable types like Int, Float, String and tuples.

sum : List (Quantity number units) -> Quantity number units

Find the sum of a list of quantities.

Quantity.sum
    [ Length.meters 1
    , Length.centimeters 2
    , Length.millimeters 3
    ]
--> Length.meters 1.023

Quantity.sum []
--> Quantity.zero

minimum : List (Quantity number units) -> Maybe (Quantity number units)

Find the minimum value in a list of quantities. Returns Nothing if the list is empty.

Quantity.minimum
    [ Mass.kilograms 1
    , Mass.pounds 2
    , Mass.tonnes 3
    ]
--> Just (Mass.pounds 2)

maximum : List (Quantity number units) -> Maybe (Quantity number units)

Find the maximum value in a list of quantities. Returns Nothing if the list is empty.

Quantity.maximum
    [ Mass.kilograms 1
    , Mass.pounds 2
    , Mass.tonnes 3
    ]
--> Just (Mass.tonnes 3)

minimumBy : (a -> Quantity number units) -> List a -> Maybe a

Find the 'minimum' item in a list as measured by some derived Quantity:

people =
    [ { name = "Bob", height = Length.meters 1.6 }
    , { name = "Charlie", height = Length.meters 2.0 }
    , { name = "Alice", height = Length.meters 1.8 }
    ]

Quantity.minimumBy .height people
--> Just { name = "Bob", height = Length.meters 1.6 }

If the list is empty, returns Nothing. If multiple items in the list are tied, then the first one is returned.

maximumBy : (a -> Quantity number units) -> List a -> Maybe a

Find the 'maximum' item in a list as measured by some derived Quantity:

people =
    [ { name = "Bob", height = Length.meters 1.6 }
    , { name = "Charlie", height = Length.meters 2.0 }
    , { name = "Alice", height = Length.meters 1.8 }
    ]

Quantity.maximumBy .height people
--> Just { name = "Charlie", height = Length.meters 2.0 }

If the list is empty, returns Nothing. If multiple items in the list are tied, then the first one is returned.

sort : List (Quantity number units) -> List (Quantity number units)

Sort a list of quantities.

Quantity.sort
    [ Mass.kilograms 1
    , Mass.pounds 2
    , Mass.tonnes 3
    ]
--> [ Mass.pounds 2
--> , Mass.kilograms 1
--> , Mass.tonnes 3
--> ]

sortBy : (a -> Quantity number units) -> List a -> List a

Sort an arbitrary list of values by a derived Quantity. If you had

people =
    [ { name = "Bob", height = Length.meters 1.6 }
    , { name = "Charlie", height = Length.meters 2.0 }
    , { name = "Alice", height = Length.meters 1.8 }
    ]

then you could sort by name with

List.sortBy .name people
--> [ { name = "Alice", height = Length.meters 1.8 }
--> , { name = "Bob", height = Length.meters 1.6 }
--> , { name = "Charlie", height = Length.meters 2.0 }
--> ]

(nothing new there!), and sort by height with

Quantity.sortBy .height people
--> [ { name = "Bob", height = Length.meters 1.6 }
--> , { name = "Alice", height = Length.meters 1.8 }
--> , { name = "Charlie", height = Length.meters 2.0 }
--> ]

Unitless quantities

It is sometimes useful to be able to represent unitless quantities, especially when working with generic code (in most other cases, it is likely simpler and easier to just use Int or Float values directly). All the conversions in this section simply wrap or unwrap a Float or Int value into a Quantity value, and so should get compiled away entirely when using elm make --optimize.


type Unitless

A special units type representing 'no units'. A Quantity Int Unitless value is interchangeable with a simple Int, and a Quantity Float Unitless value is interchangeable with a simple Float.

int : Basics.Int -> Quantity Basics.Int Unitless

Convert a plain Int into a Quantity Int Unitless value.

toInt : Quantity Basics.Int Unitless -> Basics.Int

Convert a Quantity Int Unitless value into a plain Int.

float : Basics.Float -> Quantity Basics.Float Unitless

Convert a plain Float into a Quantity Float Unitless value.

toFloat : Quantity Basics.Float Unitless -> Basics.Float

Convert a Quantity Float Unitless value into a plain Float.

If you're looking for a function to convert a Quantity Int units to Quantity Float units, check out toFloatQuantity.

Unsafe conversions

These functions are equivalent to directly constructing or unwrapping Quantity values, and generally shouldn't be used outside of some specialized situations that can come up when authoring packages that use elm-units.

unsafe : number -> Quantity number units

unwrap : Quantity number units -> number