Math.Units


This package is a port and extension of the framework elm-units. Huge thanks to @ianmackenzie for creating the original package and writing much of the original documentation.

Note: This framework is currently in alpha development.

To use this framework you include the package through the namespace

open Math.Units

Math.Units

Release notes for 2.0 are here.

Math.Units is useful if you want to store, pass around, convert between, compare, or do arithmetic on:

It is aimed especially at engineering/scientific/technical applications but is designed to be generic enough to work well for other fields such as games and finance. The core of the package consists of a generic Quantity type and many concrete types such as Length, Angle, Duration, Temperature, and Speed, which you can use to add some nice type safety to data types and function signatures:

type Camera =
    { fieldOfView: Angle
      shutterSpeed: Duration
      minimumOperatingTemperature: Temperature }

let canOperateAt (temperature: Temperature) (camera: Camera) : bool =
    temperature
    |> Temperature.greaterThan camera.minimumOperatingTemperature

You can construct values of these types from any units you want, using provided functions such as:

Hint: hover over the function names to see the type values

Length.feet
Length.meters
Duration.seconds
Angle.degrees
Temperature.degreesFahrenheit

You can later convert back to plain numeric values, also in any units you want (which do not have to be the same units used when initially constructing the value!):

Length.inCentimeters
Length.inMiles
Duration.inHours
Angle.inRadians
Temperature.inDegreesCelsius

This means that (among other things!) you can use these functions to do simple unit conversions:

Duration.hours 3. |> Duration.inSeconds
10800.0
Length.feet 10. |> Length.inMeters
3.048
Speed.milesPerHour 60. |> Speed.inMetersPerSecond
26.8224
Temperature.degreesCelsius 30.
|> Temperature.inDegreesFahrenheit
86.0

Additionally, types like Length are actually type aliases of the form Quantity number units (Length is Quantity Float Meters, for example, meaning that it is internally stored as a number of meters), and there are many generic functions which let you work directly with any kind of Quantity values:

Length.feet 3.
|> Quantity.lessThan (Length.meters 1.)
true
Duration.hours 2.
|> Quantity.plus (Duration.minutes 30.)
|> Duration.inSeconds
9000.0
// Some functions can actually convert between units!
// Multiplying two Length values gives you an Area
Length.centimeters 60.
|> Quantity.times (Length.centimeters 80.)
0.48 Product`2
Quantity.sort [ Angle.radians 1.
                Angle.degrees 10.
                Angle.turns 0.5 ]
[0.17453292519943295 Radians; 1 Radians; 3.141592653589793 Radians]

Ultimately, what this does is let you pass around and manipulate Length, Duration or Temperature etc. values without having to worry about units. When you initially construct a Length, you need to specify what units you're using, but once that is done you can:

...and much more, all without having to care about units at all. All calculations will be done in an internally consistent way, and when you finally need to actually display a value on screen or encode to JSON, you can extract the final result in whatever units you want.

Table of contents

Installation

Assuming you have installed dotnet and started a new project, you can install Math.Units by running

dotnet add package Math.Units

in a command prompt inside your project directory.

Usage

Fundamentals

To take code that currently uses raw float values and convert it to using Math.Units types, there are three basic steps:

The Quantity type

All values produced by this package (with the exception of Temperature, which is a bit of a special case) are actually values of type Quantity, roughly defined as...

type Quantity<'Units>(quantity: float) =
    member this.Value = quantity

For example, Length is defined as

type Meters = Meters
type Length = Quantity<Meters>

This means that a Length is internally stored as a float number of Meters, but the choice of internal units can mostly be treated as an implementation detail.

Having a common Quantity type means that it is possible to define generic arithmetic and comparison operations that work on any kind of quantity; read on!

Basic arithmetic and comparison

You can do basic math with Quantity values:

// 6 feet 3 inches, converted to meters
Length.feet 6.
|> Quantity.plus (Length.inches 3.)
|> Length.inMeters
1.905
Duration.hours 1.
|> Quantity.minus (Duration.minutes 15.)
|> Duration.inMinutes
45.0
// pi radians plus 45 degrees is 5/8 of a full turn
Quantity.sum [ Angle.radians Math.PI
               Angle.degrees 45. ]
|> Angle.inTurns
0.625

Quantity values can be compared/sorted:

Length.meters 1.
|> Quantity.greaterThan (Length.feet 3.)
true
Quantity.compare (Length.meters 1.) (Length.feet 3.)
1
Quantity.max (Length.meters 1.) (Length.feet 3.)
1 Meters
Quantity.maximum [ Length.meters 1.
                   Length.feet 3. ]
Some 1 Meters
Quantity.sort [ Length.meters 1.
                Length.feet 3. ]
[0.9143999999999999 Meters; 1 Meters]

Multiplication and division

There are actually three different 'families' of multiplication and division functions in the Quantity module, used in different contexts:

For example, to calculate the area of a triangle:

// Area of a triangle with base of 2 feet and
// height of 8 inches
let baseSize = Length.feet 2.
let height = Length.inches 8.

Quantity.half (Quantity.product baseSize height)
|> Area.inSquareInches
96.0

Comprehensive support is provided for working with rates of change:

// How fast are we going if we travel 30 meters in
// 2 seconds?
let speed =
    Length.meters 30.
    |> Quantity.per (Duration.seconds 2.)
// How far do we go if we travel for 2 minutes
// at that speed?
Duration.minutes 2. // duration
|> Quantity.at speed // length per duration
|> Length.inKilometers // gives us a length!
1.8
// How long will it take to travel 20 km
// if we're driving at 60 mph?
Length.kilometers 20.
|> Quantity.at_ (Speed.milesPerHour 60.)
|> Duration.inMinutes
12.42742384
// How fast is "a mile a minute", in kilometers per hour?
Length.miles 1.
|> Quantity.per (Duration.minutes 1.)
|> Speed.inKilometersPerHour
96.56064
// Reverse engineer the speed of light from defined
// lengths/durations (the speed of light is 'one light
// year per year')
let speedOfLight =
    Length.lightYears 1.
    |> Quantity.per (Duration.julianYears 1.)

speedOfLight |> Speed.inMetersPerSecond
299792458.0
// One astronomical unit is the (average) distance from the
// Sun to the Earth. Roughly how long does it take light to
// reach the Earth from the Sun?
Length.astronomicalUnits 1.
|> Quantity.at_ speedOfLight
|> Duration.inMinutes
8.316746397

Note that the various functions above are not restricted to speed (length per unit time) - any units work:

let pixelDensity =
    Pixels.float 96.
    |> Quantity.per (Length.inches 1.)

Length.centimeters 3. // length
|> Quantity.at pixelDensity // pixels per length
|> Pixels.toFloat // gives us pixels!
113.3858268

Argument order

Note that several functions like Quantity.minus and Quantity.lessThan (and their Temperature equivalents) that mimic binary operators like - and < "take the second argument first"; for example,

Quantity.lessThan x y

means y < x, not x < y. This is done for a couple of reasons. First, so that use with |> works naturally; for example,

x |> Quantity.lessThan y

does mean x < y. The 'reversed' argument order also means that things like

List.map (Quantity.minus x) [ a; b; c ]

will work as expected - it will result in

[ a - x, b - x, c - x ]

instead of

[ x - a, x - b, x - c ]

which is what you would get if Quantity.minus took arguments in the 'normal' order.

There are, however, several functions that take arguments in 'normal' order, for example:

In general the function names try to match how you would use them in English; you would say "the difference of a and b" (and so Quantity.difference a b) but "a minus b" (and so a |> Quantity.minus b).

Custom Functions

Some calculations cannot be expressed using the built-in Quantity functions. Take kinetic energy E_k = 1/2 * m * v^2, for example - the Math.Units type system is not sophisticated enough to work out the units properly. Instead, you'd need to create a custom function like

let kineticEnergy (m: Mass) (v: Speed) : Energy =
    Quantity.create (0.5 * m.Value * v.Value * v.Value)

In the implementation of kineticEnergy, you're working with raw Float values so you need to be careful to make sure the units actually do work out. (The values will be in [SI units][https://en.wikipedia.org/wiki/International_System_of_Units] - meters, seconds etc.) Once the function has been implemented, though, it can be used in a completely type-safe way - callers can supply arguments using whatever units they have, and extract results in whatever units they want: [6]:

kineticEnergy (Mass.shortTons 1.5) (Speed.milesPerHour 60.)
|> Energy.inKilowattHours
0.1359720886

Custom Units

Math.Units defines many standard Unit Systems, but you can easily define your own! See [CustomUnits][#CustomUnits] for an example.

Understanding quantity types

The same quantity type can often be expressed in multiple different ways. Take the Volume type as an example. It is an alias for

Quantity<CubicMeters>

but expanding the CubicMeters type alias, this is equivalent to

Quantity<Meters Cubed>

which expands further to

Quantity<Product<Product<Meters, Meters>, Meters>>

which could also be written as

Quantity<Product<Meters Squared, Meters>>

or even

Quantity<Product<SquareMeters, Meters>>

and you may see any one of these forms pop up in compiler error messages.

API

[Full API documentation][reference/math-units.html] is available.

Climate action

This is a message from Ian Mackenzie but as the maintainer of this package I believe in this mantra and will follow through with his wishes on giving priority to issues regarding climate action.

I would like for the projects I work on to be as helpful as possible in addressing the climate crisis. If

please open a new issue, describe briefly what you're working on and I will treat that issue as high priority.

Contributing

Yes please! One of the best ways to contribute is to add a module for a new quantity type; I'll add a proper CONTRIBUTING.md at some point, but some brief guidelines in the meantime:

License

[elm-units BSD-3-Clause © Ian Mackenzie][https://github.com/ianmackenzie/elm-units/blob/master/LICENSE] [Math.Units BSD-3-Clause © Thomas Waters][https://github.com/evelios/Math.Unitsrblob/master/LICENSE]

namespace System
type Math = static member Abs: value: decimal -> decimal + 7 overloads static member Acos: d: float -> float static member Acosh: d: float -> float static member Asin: d: float -> float static member Asinh: d: float -> float static member Atan: d: float -> float static member Atan2: y: float * x: float -> float static member Atanh: d: float -> float static member BigMul: a: int * b: int -> int64 + 2 overloads static member BitDecrement: x: float -> float ...
<summary>Provides constants and static methods for trigonometric, logarithmic, and other common mathematical functions.</summary>
namespace Math.Units
type Camera = { fieldOfView: Angle shutterSpeed: Duration minimumOperatingTemperature: Temperature }
Camera.fieldOfView: Angle
Multiple items
module Angle from Math.Units
<category>Module: Unit System</category>
<summary> An <c>Angle</c> represents an angle in degrees, radians, or turns. It is stored as a number of radians. </summary>
<note> Angles are sometimes measured in degrees, minutes, and seconds, where 1 minute = 1/60th of a degree and 1 second = 1/60th of a minute. </note>
<example> You can construct an angle from your unit scheme. All of the following are equivalent. <code> Angle.radians Math.PI Angle.degrees 180. Angle.turns 0.5 </code></example>


--------------------
type Angle = Quantity<Radians>
<category>Unit System</category>
Camera.shutterSpeed: Duration
Multiple items
module Duration from Math.Units
<category>Module: Unit System</category>
A
<c>Duration</c>
 refers to an elapsed time in seconds, milliseconds, hours etc., as opposed to a specific instant in time (which would generally be represented by a
<see cref="System.DateTime" />
. value). It is stored as a number of seconds.


--------------------
type Duration = Quantity<Seconds>
<category>Unit System</category>
Camera.minimumOperatingTemperature: Temperature
Multiple items
module Temperature from Math.Units
<category>Module: Unit System</category>
<summary> Unlike other modules in <c>Math.Units</c>, this module contains two different primary types: <list type="bullet"><item><description><c>Temperature</c>, which is not actually a <c>Quantity</c> since temperatures don't really act like normal quantities. For example, it doesn't make sense to add two temperatures or find the ratio between them. </description></item><item><description><c>TemperatureDelta</c>, which represents the difference between two temperatures. A <c>TemperatureDelta</c><i>is</i> a <c>Quantity</c> since it does make sense to add two deltas to get a net delta, find the ratio between two deltas (one rise in temperature might be twice as much as another rise in temperature), etc. </description></item></list></summary>
<note> Since a <c>Temperature</c> value is not a <c>Quantity</c>, this module exposes specialized functions for doing the operations on <c>Temperature</c> values that <i>do</i> make sense, such as comparing two temperatures or sorting a list of temperatures. It's also possible to find the delta from one temperature to another using <c>Temperature.minus</c>, and then add a <c>TemperatureDelta</c> to a <c>Temperature</c> using <c>Temperature.plus</c>. </note>


--------------------
type Temperature = interface IComparable interface IComparable<Temperature> new: kelvin: float -> Temperature member Comparison: other: Temperature -> int member Equals: other: Temperature -> bool + 1 overload override GetHashCode: unit -> int member LessThan: other: Temperature -> bool override ToString: unit -> string static member (+) : lhs: Temperature * rhs: TemperatureDelta -> Temperature + 1 overload static member (-) : lhs: Temperature * rhs: Temperature -> TemperatureDelta ...
<category>Unit System</category>

--------------------
new: kelvin: float -> Temperature
val canOperateAt: temperature: Temperature -> camera: Camera -> bool
val temperature: Temperature
val camera: Camera
[<Struct>] type bool = Boolean
<summary>An abbreviation for the CLI type <see cref="T:System.Boolean" />.</summary>
<category>Basic Types</category>
val greaterThan: rhs: Temperature -> lhs: Temperature -> bool
<category>Operators</category>
<summary> This is meant to be used with pipe operators. <code> Temperature.inDegreesCelsius 30. |&gt; Temperature.greaterThan (Temperature.inDegreesCelsius 15.) </code></summary>
Multiple items
module Length from Math.Units
<category>Module: Unit System</category>
<summary> A <c>Length</c> represents a length in meters, feet, centimeters, miles etc. It is stored as a number of meters. </summary>


--------------------
type Length = Quantity<Meters>
<category>Unit System</category>
val feet: l: float -> Length
<category>Imperial</category>
val meters: m: float -> Length
<category index="2">Metric</category>
val seconds: numSeconds: float -> Duration
<category index="1">Conversions</category>
<summary> Construct a <c>Duration</c> from a given number of seconds. </summary>
val degrees: d: float -> Angle
<category>Degrees</category>
Create an angle from a number of degrees.
val degreesFahrenheit: numDegreesFahrenheit: float -> Temperature
<category>Temperature Conversions</category>
Construct a temperature from a number of degrees Fahrenheit.
val inCentimeters: l: Length -> float
<category>Metric</category>
val inMiles: l: Length -> float
<category>Imperial</category>
val inHours: duration: Duration -> float
<category>Conversions</category>
<summary> Convert a <c>Duration</c> to a value in hours. </summary>
<example><code> Duration.minutes 120 |&gt; Duration.inHours --&gt; 2 </code></example>
val inRadians: r: Angle -> float
<category>Radians</category>
Get a
<c>float</c>
 of the given angle in radians
val inDegreesCelsius: temperature: Temperature -> float
<category>Temperature Conversions</category>
Convert a temperature to a number of degrees Celsius.
val hours: numHours: float -> Duration
<category>Conversions</category>
<summary> Construct a <c>Duration</c> from a given number of hours. </summary>
<example><code> Duration.hours 1 --&gt; Duration.seconds 3600 </code></example>
val inSeconds: numSeconds: Duration -> float
<category>Conversions</category>
<summary> Convert a <c>1</c> to a value in seconds. </summary>
<example><code> Duration.milliseconds 10 |&gt; Duration.inSeconds --&gt; 0.01 </code></example>
val inMeters: l: Length -> float
<category>Metric</category>
Multiple items
module Speed from Math.Units
<category>Module: Unit System</category>
<summary> A <c>Speed</c> value represents a speed in meters per second, miles per hour etc. It is stored as a number of meters per second. </summary>
<note> Since <c>MetersPerSecond</c> is defined as <c>Rate Meters Seconds</c> (length per unit time), you can construct a <c>Speed</c> value using <c>Quantity.per</c>: <code> let speed = length |&gt; Quantity.per duration </code> You can also do rate-related calculations with <c>Speed</c> values to compute <c>Length</c> or <c>Duration</c>: <code> let length = speed |&gt; Quantity.for duration let alsoLength = duration |&gt; Quantity.at speed let duration = length |&gt; Quantity.at_ speed </code></note>


--------------------
type Speed = Quantity<MetersPerSecond>
<category>Unit System</category>
val milesPerHour: numMilesPerHour: float -> Speed
<category>Conversions</category>
Construct a speed from a number of miles per hour.
val inMetersPerSecond: numMetersPerSecond: Speed -> float
<category>Conversions</category>
Convert a speed to a number of meters per second.
val degreesCelsius: numDegreesCelsius: float -> Temperature
<category>Temperature Conversions</category>
Construct a temperature from a number of degrees Celsius.
val inDegreesFahrenheit: temperature: Temperature -> float
<category>Temperature Conversions</category>
Convert a temperature to a number of degrees Fahrenheit.
Multiple items
module Quantity from Math.Units
<category>Module: Unit System</category>

--------------------
type Quantity<'Units> = interface IComparable interface IComparable<Quantity<'Units>> new: quantity: float -> Quantity<'Units> member Comparison: other: Quantity<'Units> -> int member Equals: other: Quantity<'Units> -> bool + 1 overload override GetHashCode: unit -> int member LessThan: other: Quantity<'Units> -> bool override ToString: unit -> string static member (%) : q: Quantity<'Units> * modulus: Quantity<'Units> -> Quantity<'Units> static member ( * ) : q: Quantity<'Units> * scale: float -> Quantity<'Units> + 2 overloads ...
<category>Unit System</category>
<summary> A <c>Quantity</c> is effectively a <c>number</c> (an <c>Int</c> or <c>Float</c>) tagged with a <c>units</c> type. So a Quantity Float Meters is a <c>Float</c> number of <c>Meters</c> and a Quantity Int Pixels is an <c>Int</c> number of <c>Pixels</c>. When compiling with <c>elm make --optimize</c> the <c>Quantity</c> wrapper type will be compiled away, so the runtime performance should be comparable to using a raw <c>Float</c> or <c>Int</c>. </summary>


--------------------
new: quantity: float -> Quantity<'Units>
static member Quantity.lessThan: y: Quantity<'Units> -> x: Quantity<'Units> -> bool
static member Quantity.plus: y: Quantity<'Units> -> x: Quantity<'Units> -> Quantity<'Units>
val minutes: numMinutes: float -> Duration
<category>Conversions</category>
<summary> Construct a <c>Duration</c> from a given number of minutes. </summary>
<example><code> Duration.minutes 3 --&gt; Duration.seconds 180 </code></example>
val centimeters: l: float -> Length
<category>Metric</category>
static member Quantity.times: y: Quantity<'Units> -> x: Quantity<'Units> -> Quantity<Product<'Units,'Units>>
static member Quantity.sort: quantities: Quantity<'Units> list -> Quantity<'Units> list
val radians: r: float -> Angle
<category>Radians</category>
Create an angle from a number of radians.
val turns: numTurns: float -> Angle
<category>Turns</category>
Create an angle from a number of turns.
Multiple items
module Quantity from Math.Units
<category>Module: Unit System</category>

--------------------
type Quantity<'Units> = new: quantity: float -> Quantity<'Units> member Value: float

--------------------
new: quantity: float -> Quantity<'Units>
val quantity: float
Multiple items
val float: value: 'T -> float (requires member op_Explicit)
<summary>Converts the argument to 64-bit float. This is a direct conversion for all primitive numeric types. For strings, the input is converted using <c>Double.Parse()</c> with InvariantCulture settings. Otherwise the operation requires an appropriate static conversion method on the input type.</summary>
<param name="value">The input value.</param>
<returns>The converted float</returns>
<example id="float-example"><code lang="fsharp"></code></example>


--------------------
[<Struct>] type float = Double
<summary>An abbreviation for the CLI type <see cref="T:System.Double" />.</summary>
<category>Basic Types</category>


--------------------
type float<'Measure> = float
<summary>The type of double-precision floating point numbers, annotated with a unit of measure. The unit of measure is erased in compiled code and when values of this type are analyzed using reflection. The type is representationally equivalent to <see cref="T:System.Double" />.</summary>
<category index="6">Basic Types with Units of Measure</category>
val this: Quantity<'Units>
Multiple items
union case Meters.Meters: Meters

--------------------
type Meters = | Meters
Multiple items
module Length from Math.Units
<category>Module: Unit System</category>
<summary> A <c>Length</c> represents a length in meters, feet, centimeters, miles etc. It is stored as a number of meters. </summary>


--------------------
type Length = Quantity<Meters>
val inches: l: float -> Length
<category>Imperial</category>
static member Quantity.minus: y: Quantity<'Units> -> x: Quantity<'Units> -> Quantity<'Units>
val inMinutes: duration: Duration -> float
<category>Conversions</category>
<summary> Convert a <c>Duration</c> to a value in minutes. </summary>
<example><code> Duration.seconds 90 |&gt; Duration.inMinutes --&gt; 1.5 </code></example>
static member Quantity.sum: quantities: Quantity<'Units> list -> Quantity<'Units>
field Math.PI: float = 3.14159265359
val inTurns: angle: Angle -> float
<category>Turns</category>
Get a
<c>float</c>
 of the given angle in turns.
static member Quantity.greaterThan: y: Quantity<'Units> -> x: Quantity<'Units> -> bool
static member Quantity.compare: x: Quantity<'Units> -> y: Quantity<'Units> -> int
static member Quantity.max: x: Quantity<'Units> -> y: Quantity<'Units> -> Quantity<'Units>
static member Quantity.maximum: quantities: Quantity<'Units> list -> Quantity<'Units> option
val baseSize: Length
val height: Length
static member Quantity.half: quantity: Quantity<'Units> -> Quantity<'Units>
static member Quantity.product: x: Quantity<'Units> -> y: Quantity<'Units> -> Quantity<Product<'Units,'Units>>
Multiple items
module Area from Math.Units
<category>Module: Unit System</category>
<summary> An <c>Area</c> represents an area in square meters, square feet, acres, hectares etc. It is stored as a number of square meters. Note that you can construct an <c>Area</c> value directly using the functions in this module, but it also works to call <c>Quantity.squared</c> on a <c>Length</c> or <c>Quantity.times</c> on a pair of <c>Length</c>s. </summary>
<example> The following are all equivalent: <code> Area.squareFeet 100 Quantity.squared (Length.feet 10) Length.feet 25 |&gt; Quantity.times (Length.feet 4) </code></example>


--------------------
type Area = Quantity<SquareMeters>
<category>Unit System</category>
val inSquareInches: area: Area -> float
<category>Conversions</category>
Convert an area to a number of square inches.
val speed: Quantity<Rate<Meters,Seconds>>
static member Quantity.per: independentValue: Quantity<'Independent> -> dependentValue: Quantity<'Dependent> -> Quantity<Rate<'Dependent,'Independent>>
static member Quantity.at: rateOfChange: Quantity<Rate<'Dependent,'Independent>> -> independentValue: Quantity<'Independent> -> Quantity<'Dependent>
val inKilometers: l: Length -> float
<category>Metric</category>
val kilometers: l: float -> Length
<category>Metric</category>
static member Quantity.at_: rateOfChange: Quantity<Rate<'Dependent,'Independent>> -> dependentValue: Quantity<'Depenent> -> Quantity<'Independent>
val miles: l: float -> Length
<category>Imperial</category>
val inKilometersPerHour: speed: Speed -> float
<category>Conversions</category>
Convert a speed to a number of kilometers per hour.
val speedOfLight: Quantity<Rate<Meters,Seconds>>
val lightYears: l: float -> Length
<category>Astronomical</category>
val julianYears: numJulianYears: float -> Duration
<category>Conversions</category>
<summary> Construct a <c>Duration</c> from a given number of <see href="https://en.wikipedia.org/wiki/Julian_year_(astronomy)">Julian years</see> A Julian year is defined as exactly 365.25 days, the average length of a year in the historical Julian calendar. This is 10 minutes and 48 seconds longer than a Gregorian year (365.2425 days), which is the average length of a year in the modern Gregorian calendar, but the Julian year is a bit easier to remember and reason about and has the virtue of being the 'year' value used in the definition of a <see href="https://en.wikipedia.org/wiki/Light-year">light year</see>]. </summary>
<example><code> Duration.julianYears 1 --&gt; Duration.days 365.25 </code></example>
val astronomicalUnits: l: float -> Length
<category index="5">Astronomical</category>
val pixelDensity: Quantity<Rate<Pixel,Meters>>
Multiple items
module Pixels from Math.Units
<category>Module: Unit System</category>
<summary> Although most of the focus of <c>Math.Units</c> is on physical/scientific units, it's often useful to be able to safely convert back and forth between (for example) <c>Length</c> values in the real world and on-screen lengths in pixels. <para> This module provides a standard <c>Pixels</c> units type and basic functions for constructing/converting values of type <c>Quantity Int Pixels</c> or <c>Quantity Float Pixels</c>, which allows you to do things like represent conversions between real-world and on-screen lengths as rates of change. This in turn means that all the normal <c>Quantity</c> functions can be used to convert between pixels and other units, or even do type-safe math directly on pixel values. </para></summary>


--------------------
type Pixels = Quantity<Pixel>
<category>Unit System</category>
val float: numPixels: float -> Pixels
<category>Distance</category>
<summary> Construct a quantity representing a floating-point number of on-screen pixels: <code> let lineWeight = Pixels.float 1.5 </code></summary>
val toFloat: numPixels: Pixels -> float
<category>Distance</category>
<summary> Convert a floating-point number of pixels back into a plain <c>Float</c>: </summary>
<example><code> let pixelDensity = Pixels.float 96 |&gt; Quantity.per (Length.inches 1) Length.centimeters 1 |&gt; Quantity.at pixelDensity |&gt; Pixels.toFloat --&gt; 37.795275590551185 </code></example>
val x: Quantity<Unitless>
static member Quantity.unitless: value: float -> Quantity<Unitless>
val y: Quantity<Unitless>
val a: Quantity<Unitless>
val b: Quantity<Unitless>
val c: Quantity<Unitless>
Multiple items
module List from Microsoft.FSharp.Collections
<summary>Contains operations for working with values of type <see cref="T:Microsoft.FSharp.Collections.list`1" />.</summary>
<namespacedoc><summary>Operations for collections such as lists, arrays, sets, maps and sequences. See also <a href="https://docs.microsoft.com/dotnet/fsharp/language-reference/fsharp-collection-types">F# Collection Types</a> in the F# Language Guide. </summary></namespacedoc>


--------------------
type List<'T> = | op_Nil | op_ColonColon of Head: 'T * Tail: 'T list interface IReadOnlyList<'T> interface IReadOnlyCollection<'T> interface IEnumerable interface IEnumerable<'T> member GetReverseIndex: rank: int * offset: int -> int member GetSlice: startIndex: int option * endIndex: int option -> 'T list static member Cons: head: 'T * tail: 'T list -> 'T list member Head: 'T member IsEmpty: bool member Item: index: int -> 'T with get ...
<summary>The type of immutable singly-linked lists.</summary>
<remarks>Use the constructors <c>[]</c> and <c>::</c> (infix) to create values of this type, or the notation <c>[1;2;3]</c>. Use the values in the <c>List</c> module to manipulate values of this type, or pattern match against the values directly. </remarks>
<exclude />
val map: mapping: ('T -> 'U) -> list: 'T list -> 'U list
<summary>Builds a new collection whose elements are the results of applying the given function to each of the elements of the collection.</summary>
<param name="mapping">The function to transform elements from the input list.</param>
<param name="list">The input list.</param>
<returns>The list of transformed elements.</returns>
<example id="map-1"><code lang="fsharp"> let inputs = [ "a"; "bbb"; "cc" ] inputs |&gt; List.map (fun x -&gt; x.Length) </code> Evaluates to <c>[ 1; 3; 2 ]</c></example>
val kineticEnergy: m: Mass -> v: Speed -> Energy
val m: Mass
Multiple items
module Mass from Math.Units
<category>Module: Unit System</category>
<summary> A <c>Mass</c> represents a mass in kilograms, pounds, metric or imperial tons etc. It is stored as a number of kilograms. </summary>


--------------------
type Mass = Quantity<Kilograms>
<category>Unit System</category>
val v: Speed
Multiple items
module Energy from Math.Units
<category>Module: Unit System</category>
<summary> An <c>Energy</c> value represents an amount of energy (or work) in joules, kilowatt hours etc. It is stored as a number of joules. </summary>
<note><para> Since <c>Joules</c> is defined as <c>Product&lt;Newtons, Meters&gt;</c>, you can compute energy directly as a product of force and distance: </para><code> Force.newtons 5 |&gt; Quantity.times (Length.meters 4) --&gt; Energy.joules 20 </code></note>


--------------------
type Energy = Quantity<Joules>
<category>Unit System</category>
static member Quantity.create: value: float -> Quantity<'Units>
property Quantity.Value: float with get
val shortTons: numShortTons: float -> Mass
<category>Imperial</category>
<summary> Construct a mass from a number of <a href="https://en.wikipedia.org/wiki/Short_ton">short tons</a>. This is the 'ton' commonly used in the United States. <code> Mass.shortTons 1 --&gt; Mass.pounds 2000 </code></summary>
val inKilowattHours: energy: Energy -> float
<category>Conversions</category>
Convert an energy value to a number of kilowatt hours.
type CubicMeters = Cubed<Meters>
<category>Unit</category>
type Cubed<'Units> = Product<'Units,Product<'Units,'Units>>
<category>Unit Relation</category>
<summary> Represents a units type that is the cube of some other units type; for example, <c>Meters</c> is one units type (the units type of a <c>Length</c>) and <c>Cubed Meters</c> is another (the units type of an <c>Volume</c>). See the <c>Quantity.cubed</c> and <c>Quantity.cbrt</c> functions for examples of use. This is a special case of the <c>Product</c> units type. </summary>
Multiple items
union case Product.Product: 'Unit1 * 'Unit2 -> Product<'Unit1,'Unit2>

--------------------
type Product<'Unit1,'Unit2> = | Product of 'Unit1 * 'Unit2
<category>Unit Relation</category>
<summary> Represents a units type that is the product of two other units types. This is a more general form of <c>Squared</c> or <c>Cubed</c>. See <see cref="M:Math.Units.Quantity.product">Quantity.product</see>, <see cref="M:Math.Units.Quantity.times">Quantity.times</see>, <see cref="M:Math.Units.Quantity.over">Quantity.over</see> and <see cref="M:Math.Units.Quantity.over_">Quantity.over_</see> for how it can be used. </summary>
type Squared<'Units> = Product<'Units,'Units>
<category>Unit Relation</category>
<summary> Represents a units type that is the square of some other units type; for example, <c>Meters</c> is one units type (the units type of a <c>Length</c>) and <c>Squared Meters</c> is another (the units type of an <c>Area</c>). See the <see cref="Math.Units.Quantity.squared">Quantity.squared</see> and [<c>sqrt</c>](#sqrt) <see cref="Math.Units.Quantity.sqrt">Quantity.sqrt</see> functions for examples of use. This is a special case of the <c>Product</c> units type. </summary>
type SquareMeters = Squared<Meters>
<category>Unit</category>