Releases: ianmackenzie/elm-units
2.10.0
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
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
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
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
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
2.5.0
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 Float
s):
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
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
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
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
.