Bot releases are visible (Hide)
This release brings a new Torque
module (thanks @gampleman!) plus one new function: Quantity.sign
, for getting the sign of a quantity.
Published by ianmackenzie over 3 years ago
This release brings a number of useful new functions to the Quantity
module.
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
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
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
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
Published by ianmackenzie over 3 years ago
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
.)
Published by ianmackenzie about 4 years ago
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
.
Published by ianmackenzie over 4 years ago
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.
Published by ianmackenzie over 4 years ago
This release fixes one small docs typo in the AngularSpeed
module; thanks @objarni for pointing it out!
Published by ianmackenzie over 4 years ago
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
Published by ianmackenzie over 4 years ago
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.
Published by ianmackenzie over 4 years ago
Version 2.3.0 of elm-units
brings a variety of handy new features.
Quantity
functionsThere 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
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)
Molarity
moduleFinally, 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.
Published by ianmackenzie about 5 years ago
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.
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!
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 functionsA 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
.
Published by ianmackenzie over 5 years ago
This release of elm-units
comes with just one user-visible change, the addition of a range
function for generating evenly-spaced values:
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
--> ]
Not visible is a ton of work that went into refactoring elm-units
internals to collect all conversion factors into one place. We now have a single nicely-readable Constants.elm
file with all the various conversion factors, for easy reuse and auditability. Thanks to @katjam for all her work on #23!
Published by ianmackenzie over 5 years ago
Fix to API docs link in README (thanks @katjam!)
Published by ianmackenzie almost 6 years ago
Add release notes link to README
Published by ianmackenzie almost 6 years ago
elm-units
2.0 is out! This release adds several new quantity types, improves support for multiplication of different types of quantities, and adds a few more useful functions to the Quantity
module.
To update code using elm-units
1.0 to 2.0, it should be sufficient to replace
Quantity.times
with Quantity.for
Quantity.product
with the new Quantity.times
Quantity.scaleBy
with Quantity.multiplyBy
For example:
----- 1.0 -----
length =
speed |> Quantity.times duration
area =
Quantity.product length width
halfLength =
Quantity.scaleBy 0.5 length
----- 2.0 -----
length =
speed |> Quantity.for duration
area =
length |> Quantity.times width
halfLength =
Quantity.multiplyBy 0.5 length
See Improved product support below for details.
This release adds support for several new quantity types:
Volume
(cubic meters) - thanks @katjam!Density
(kilograms per cubic meter) - thanks @katjam!AngularSpeed
(radians per second) - thanks @katjam!AngularAcceleration
(radians per second squared) - thanks @katjam!Capacitance
(farads) - thanks @ukarim!Inductance
(henries) - thanks @ukarim!SubstanceAmount
(moles) - thanks @ukarim!Support for products of two quantities is now generalized and improved. Previously it was possible to square a quantity using Quantity.squared
or multiply two quantities with the same units using Quantity.product
(both of which gave you a result in Squared units
), but there was no way to multiply two quantities with different units. This is now supported - for example, it is now possible to multiply an Area
by a Length
to get a Volume
, or a Mass
by an Acceleration
to get a Force
. It is also now possible to divide these products, for example divide a Force
by a Mass
to get an Acceleration
.
This has led to a couple of breaking changes. First of all, the existing Quantity.times
(used when working with rates of change) has been renamed to Quantity.for
, and Quantity.times
is now used for multiplying quantities together, replacing the old Quantity.product
. For example:
area =
width |> Quantity.times length
volume =
area |> Quantity.times depth
force =
mass |> Quantity.times acceleration
In addition, for consistency with divideBy
, scaleBy
has been renamed to multiplyBy
. There are now three 'families' of multiplication/division functions for use in different contexts:
multiplyBy
and divideBy
are used to multiply (scale) or divide a Quantity
by a plain Int
or Float
times
, over
and over_
are used to work with quantities that are products of other quantities, like Area
or Volume
per
, at
, at_
and for
are used to work with rates of change, like Speed
or or Current
See Multiplication and division in the README for more details.
The new products support is made possible by a new Product units1 units2
units type. This has led to the redefinition of some existing units types:
Squared units
has been redefined as Product units units
Cubed units
has been redefined as Product (Product units units) units
Joules
has been redefined as Product Newtons Meters
Newtons
has been changed from Rate Joules Meters
to Product Kilograms MetersPerSecondSquared
Quantity
functionsA few new functions have been added to the Quantity
module:
Quantity.lessThanOrEqualTo
and Quantity.greaterThanOrEqualTo
to go with the existing Quantity.lessThan
and Quantity.greaterThan
Quantity.interpolateFrom
to interpolate from one value to anotherQuantity.midpoint
to find the midpoint between two quantitiesQuantity.sortBy
to sort an arbitrary list of values by a derived quantityPublished by ianmackenzie about 6 years ago
elm-units
1.0 has been released! Check out the README for a fairly comprehensive introduction to the package, and don't be afraid to reach out if you have questions/comments/suggestions.
Big thanks to all those who helped with initial development of the package:
(Sincere apologies to anyone I've missed.)