Skip to content

Releases: ianmackenzie/elm-units

2.10.0

15 Jun 15:46
Compare
Choose a tag to compare

This release brings a new Torque module (thanks @gampleman!) plus one new function: Quantity.sign, for getting the sign of a quantity.

2.9.0

19 Apr 23:18
Compare
Choose a tag to compare

This release brings a number of useful new functions to the Quantity module.

Comparisons against zero

It's fairly common to check if a value is less than or greater than zero, for example to check if something is moving up or down:

if verticalSpeed |> Quantity.lessThan Quantity.zero then
    -- Falling down

else
    -- Moving up (or stationary)

A few new convenient shorthands have been added for these cases:

Quantity.lessThanZero : Quantity number units -> Bool
Quantity.greaterThanZero : Quantity number units -> Bool
Quantity.lessThanOrEqualToZero : Quantity number units -> Bool
Quantity.greaterThanOrEqualToZero : Quantity number units -> Bool

Non-infix versions of arithmetic operators

The existing arithmetic operators in elm-units are generally intended to be used in 'pipeline' or 'infix' form, for example

rotation =
    endAngle |> Quantity.minus startAngle

area =
    length |> Quantity.times width

speed =
    distance |> Quantity.per time

Sometimes, however, it is cleaner or more understandable to write these without a pipe, and there are now new functions that allow this style:

rotation =
    Quantity.difference endAngle startAngle

area =
    Quantity.product length width

speed =
    Quantity.rate distance time

Multiplying rates of change

Sometimes you have two rates of change and you want to combine them to get a new rate of change. For example, if you know distance per unit time (speed), and mass of CO₂ emitted per unit distance, then you can get mass of CO₂ emitted per unit time using the new Quantity.rateProduct:

speed =
    Length.kilometers 100 |> Quantity.per Duration.hour

emissionsPerKilometer =
    Mass.grams 200 |> Quantity.per Length.kilometer

Quantity.rateProduct speed emissionsPerKilometer
--> Mass.grams 5.555 |> Quantity.per Duration.second

Arithmetic on unitless quantities

When doing arithmetic on unitless quantities, specialized functions are needed to avoid the result having weird units like Product Unitless Meters. elm-units already has a few functions (such as timesUnitless and overUnitless) for these cases, but this release adds several more:

Quantity.reciprocal : Quantity Float Unitless -> Quantity Float Unitless
Quantity.squaredUnitless : Quantity number Unitless -> Quantity number Unitless
Quantity.sqrtUnitless : Quantity Float Unitless -> Quantity Float Unitless
Quantity.cubedUnitless : Quantity number Unitless -> Quantity number Unitless
Quantity.cbrtUnitless : Quantity Float Unitless -> Quantity Float Unitless

2.8.0

09 Apr 20:08
Compare
Choose a tag to compare

This release brings a couple of small improvements - first of all, the Volume module now has cubicCentimeters as an alias for milliliters thanks to @g-belmonte in #54:

Volume.cubicCentimeter : Volume
Volume.cubicCentimeters : Float -> Volume
Volume.inCubicCentimeters : Volume -> Float

Second, the Quantity module now has timesUnitless and overUnitless functions to smooth out some slightly annoying type-related wrinkles when multiplying and dividing by unitless quantities:

Quantity.timesUnitless : Quantity number Unitless -> Quantity number units -> Quantity number units
Quantity.overUnitless : Quantity Float Unitless -> Quantity Float units -> Quantity Float units

(For example, using timesUnitless lets you get a result with units type units instead of the Product Unitless units that you would get if you used the existing times.)

2.7.0

15 Sep 15:32
Compare
Choose a tag to compare

This release brings a few small new functions:

Angle.normalize : Angle -> Angle 
Quantity.unsafe : number -> Quantity number units
Quantity.unwrap : Quantity number units -> number

Angle.normalize is used to convert an arbitrary angle into the equivalent angle in the range -180 to +180 degrees; for example 330 degrees normalizes to -30 degrees. Note that you may need to be careful with roundoff error for angles near 180 degrees or -180 degrees; for example 180.0001 degrees will normalize to -179.9999 degrees which may not be what you expect.

Quantity.unsafe and Quantity.unwrap are equivalent to directly constructing/destructuring Quantity values and should generally be avoided if possible, but are useful in some low-level situations that may come up in packages that use elm-units.

2.6.0

27 Jun 03:28
Compare
Choose a tag to compare

This release brings a few new functions to the Pixels module:

Pixels.int : Int -> Quantity Int Pixels
Pixels.float : Float -> Quantity Float Pixels

Pixels.toInt : Quantity Int Pixels -> Int
Pixels.toFloat : Quantity Float Pixels -> Float

I find these a bit more readable/less awkward than the existing Pixels.pixels and Pixels.inPixels, but those two functions have the advantage of working with the generic number type instead of being specific to Int or Float - for example it is occasionally useful that a value like

screenWidth =
    Pixels.pixels 1920

can be passed to both functions that expect Quantity Int Pixels as well as ones that expect Quantity Float Pixels, without having to do any conversions such as Quantity.toFloatQuantity.

As a general rule, I suggest using Pixels.int/Pixels.float in most cases, and Pixels.pixels only if it makes the code shorter and cleaner.

2.5.1

12 Jun 01:33
Compare
Choose a tag to compare

This release fixes one small docs typo in the AngularSpeed module; thanks @objarni for pointing it out!

2.5.0

25 Apr 15:06
Compare
Choose a tag to compare

This release brings a few more features requested or contributed by the community. First of all, some additional functions for working with atomic-scale lengths, contributed by @ChrisWellsWood in #49:

Length.nanometers : Float -> Length
Length.inNanometers : Length -> Float

Length.angstroms : Float -> Length
Length.inAngstroms : Length -> Float

Length.nanometer : Length
Length.angstrom : Length

Next, a couple functions for using Duration values to offset Time.Posix values:

Duration.addTo : Time.Posix -> Duration -> Time.Posix
Duration.subtractFrom : Time.Posix -> Duration -> Time.Posix

(Note that these operations are lossy - a Time.Posix value is represented by an integer number of milliseconds, so it is only possible to offset by an integer numbers of milliseconds.)

Finally, some modulo/remainder functions to match Elm's built-in modBy and remainderBy functions, but also extended to work with Quantity Float units values (similar to how fractionalModBy from elm-community/basics-extra extends modBy to work with Floats):

Quantity.modBy : Quantity Int units -> Quantity Int units -> Quantity Int units
Quantity.remainderBy : Quantity Int units -> Quantity Int units -> Quantity Int units
Quantity.fractionalModBy : Quantity Float units -> Quantity Float units -> Quantity Float units
Quantity.fractionalRemainderBy : Quantity Float units -> Quantity Float units -> Quantity Float units

2.4.0

04 Apr 23:59
Compare
Choose a tag to compare

This release adds some CSS/typography units to the Length module:

Length.points : Float -> Length
Length.inPoints : Length -> Float

Length.picas : Float -> Length
Length.inPicas : Length -> Float

Length.cssPixels : Float -> Length
Length.inCssPixels : Length -> Float

Points and picas are standard typographical units equal to 1/72 and 1/6 of an inch respectively. Similarly, the CSS spec defines a pixel as nominally equal to 1/96 of an inch. Note the difference between Length.cssPixels 1 and the existing Pixels.pixels 1:

> Length.cssPixels 1
Quantity 0.0002645833333333333 : Quantity Float Meters

> Pixels.pixels 1
Quantity 1 : Quantity Float Pixels

That is, Length.cssPixels 1 is actually a physical measurement (the real-world size of one pixel on a 96 DPI monitor), while Pixels.pixels 1 is an abstract "one pixel" value.

Usually you will probably want to use Pixels.pixels, but Length.cssPixels may be useful if you are combining real-world and on-screen units. For example, using Length.cssPixels with the upcoming elm-3d-scene package will let you fairly naturally set up a 3D scene using pixel sizes (to get a specific on-screen size in pixels) while still being able to use proper physically-based lighting.

2.3.0

21 Feb 01:34
Compare
Choose a tag to compare

Version 2.3.0 of elm-units brings a variety of handy new features.

Quantity functions

There are now functions to get the maximum or minimum value in a List based on some derived Quantity:

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

Thanks @MartinSStewart for the suggestion! There is also now a Quantity.in_ function for doing conversions into units that aren't directly supported by elm-units:

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

Thanks @harrysarson for the idea! You might use it like this to get a speed in feet per minute:

Speed.metersPerSecond 5
    |> Quantity.in_ (Length.feet >> Quantity.per Duration.minute)
--> 984.252

Constants

The eagle-eyed reader may have noticed that Duration.minute in the above example is new. Partially to make the use of Quantity.in_ more convenient, but also because they're likely to be generally useful, this release defines a large number of unit constants in the Length, Duration, Angle, Mass, Area, Volume, Temperature and Pixels modules: Length.meter, Duration.minute, Volume.imperialGallon etc. This means you can write

Length.feet >> Quantity.per Duration.minute

instead of

Length.feet >> Quantity.per (Duration.minutes 1)

New Molarity module

Finally, thanks to @lenards in #44 for contributing a new Molarity module! Molarity represents concentration of a substance per unit volume and is useful in chemistry applications. Along with the new Molarity module, direct support for centimoles and decimoles were added to the existing SubstanceAmount module.

2.2.0

02 Aug 23:26
Compare
Choose a tag to compare

elm-units 2.2.0 brings three main changes: new modules for working with photometric units, support for working with angles in degrees/minutes/seconds form, and a couple new convenience functions for Quantity values.

Photometric units

This release brings new modules for dealing with different kinds of photometric quantities: SolidAngle, LuminousFlux, LuminousIntensity, Illuminance and Luminance. These kinds of quantities can be very confusing to think about - I've tried to describe them briefly in each module's documentation, but if you're new to the field then you'll probably have to do some reading of your own!

Angles in degrees, minutes and seconds

In some situations, such as when dealing with geographical data, it is common to represent angles as a number of degrees, minutes (1/60th of a degree) and seconds (1/60th of a minute). This release brings a handful of functions (and a new Angle.Sign type) to work with these kinds of values:

Angle.minutes : Float -> Angle
Angle.inMinutes : Angle -> Float
Angle.seconds : Float -> Angle
Angle.inSeconds : Angle -> Float
Angle.fromDms : { sign : Angle.Sign, degrees : Int, minutes : Int, seconds : Float } -> Angle
Angle.toDms : Angle -> { sign : Angle.Sign, degrees : Int, minutes : Int, seconds : Float }

Quantity convenience functions

A couple tiny convenience functions have been added to the Quantity module: twice, as a convenient shorthand for multiplyBy 2, and half as shorthand for multiplyBy 0.5.