kex docs Standard Library

Units

Numbers that carry a unit.

Writing 5.second or 90.minute gives you a Measure: a number, the unit it was written in, and the same quantity in that dimension's base unit. Adding, subtracting and converting all go through the canonical value, so the arithmetic is right regardless of which units the operands were written in, and mixing dimensions is an Error rather than a silently wrong number.

5.second.to(String)                     # => "5.0 s"
1.5.hour.to(String)                  # => "1.5 h"
(1.hour + 30.minute).map(~to(String))  # => Ok("1.5 h")
90.minute.convert(Hour)              # => Ok(1.5 h)

The time units (nanosecond through week) are in the prelude. Other dimensions live in opt-in modules under Units, and every one of them measures against the same machinery here.

A Measure is a measurement, not an elapsed span: 5.second describes a quantity, while Duration is what Time and Date use for a span between two moments.

trait Unit

The trait a unit implements: how it converts to its dimension's base unit, which dimension that is, and how it is written.

Implemented by UnitDefinition, TimeUnit, DataUnit, UnitDefinition, SIPrefix, SIUnit, UnitDefinition.

Required functions

An implementor writes these.

factor

factor : Float

How many base units one of this unit is: 60.0 for a minute, whose base unit is the second.

Returns the conversion factor

Examples
Minute.factor   # => 60.0

kind

kind : Atom

Which dimension this unit measures, as an atom. Only measures of the same kind can be added or converted between.

Returns the dimension tag

Examples
Second.kind   # => :time

symbol

symbol : String

How this unit is written when a measure is displayed.

Returns the unit's symbol

Examples
Minute.symbol   # => "min"

function measureKind

measureKind(measure: Measure) -> Atom

The dimension a measure belongs to.

Parameters
measure
the measure to inspect

Returns the dimension tag

Examples
measureKind(5.second)   # => :time

function measureSymbol

measureSymbol(measure: Measure) -> String

The symbol a measure displays with.

Parameters
measure
the measure to inspect

Returns the unit's symbol

Examples
measureSymbol(5.minute)   # => "min"

function measureFactor

measureFactor(measure: Measure) -> Float

The conversion factor of a measure's unit.

Parameters
measure
the measure to inspect

Returns the conversion factor

Examples
measureFactor(5.minute)   # => 60.0

record UnitDefinition

A unit described at run time rather than by a constructor.

Runtime-defined units are used for prefixes and units derived by arithmetic: s^2 from squaring a duration, a kilo- prefix applied to a base unit.

Fields

conversionFactor
Float
dimension
Atom
notation
String

Implements Unit.

Functions

factor Unit

How many base units one of this unit is.

Returns Float — the conversion factor

kind Unit

Which dimension this unit measures.

Returns Atom — the dimension tag

symbol Unit

How the unit is written.

Returns String — the unit's symbol

Defined in other modules

record Measure

A quantity with a unit.

A Measure is shared by every unit module. canonical stores the value in that dimension's base unit; its Unit controls its display. That split is what makes +1.hour + 30.minute+ correct and still print in hours.

Fields

canonical
Float
value
Float

Implements Showable.

Functions

factor

factor : Float

kind

kind : Atom

symbol

symbol : String

to

to(_) -> String

showValue Showable

showValue : String

Renders the measure as its value and unit, so IO.printLine and interpolation show 5.0 W rather than the record's fields. Inspecting it (the REPL's echo, inspected) still shows the record itself.

Returns the value and the unit's symbol

Examples
"drawn: ${1.volt * 5.ampere}"   # => "drawn: 5.0 W"

scale

scale(multiplier: Number) -> Measure

Formatting into a target display unit deliberately has NO prelude clause. A unit module (Units.SI, Units.Data, ...) supplies to(String, in:) for the units it owns, and reaching one requires importing it. A catch-all here would answer None for an un-imported module instead: a silently empty Optional in place of "you need using Units.SI".

Multiplies the measure by a plain number, keeping its unit.

The unit is unchanged, so this scales a quantity rather than converting it: three of a two-second interval is six seconds.

Parameters
multiplier
the factor to multiply by

Returns the scaled measure

Examples
2.second.scale(3).to(String)     # => "6.0 s"
1.hour.scale(0.5).to(String)  # => "0.5 h"

^

^(exponent: Number) -> Measure

Raises the measure to a power, recording the derived unit in its notation.

Raising a measure preserves its display unit while applying the power to its canonical value, display value, and conversion factor. The current Unit trait represents a dimension as one Atom, so the dimension remains the base kind; the notation records the derived unit (for example s^2).

Parameters
exponent
the power to raise to

Returns the raised measure

Examples
(2.second ^ 2).to(String)   # => "4.0 s^2"

convertTo

convertTo(unit: Unit) -> Result<Measure, String>

Converts the measure to another unit of the same dimension.

Answers Error when the dimensions differ: you cannot express seconds in bytes, and this says so rather than producing a wrong number.

Units from opt-in modules such as Units.SI and Units.Data can be used here too, provided their dimension matches.

Parameters
unit
the unit to convert to

Returns the converted measure, or why it could not be

Examples
1.day.convertTo(Hour).map { |m| m.to(String) }     # => Ok("24.0 h")
90.minute.convertTo(Hour).map { |m| m.to(String) } # => Ok("1.5 h")

convert

convert(unit: TimeUnit) -> Result<Measure, String>

Converts the measure to another time unit. The short spelling of convertTo, kept for prelude time measures.

Parameters
unit
the time unit to convert to

Returns the converted measure, or why it could not be

Examples
90.minute.convert(Hour).map { |m| m.to(String) }   # => Ok("1.5 h")

+

+(other: Measure) -> Result<Measure, String>

Adds two measures of the same dimension.

The units need not match: the sum goes through the canonical values, and comes back displayed in the LEFT operand's unit. Adding measures of different dimensions is an Error.

Parameters
other
the measure to add

Returns the sum, or why they could not be added

Examples
(1.hour + 30.minute).map { |m| m.to(String) }   # => Ok("1.5 h")
(30.minute + 1.hour).map { |m| m.to(String) }   # => Ok("90.0 min")

-

-(other: Measure) -> Result<Measure, String>

Subtracts a measure of the same dimension.

Like +++, the result is displayed in the left operand's unit, and mixing dimensions is an Error.

Parameters
other
the measure to subtract

Returns the difference, or why they could not be subtracted

Examples
(1.hour - 30.minute).map { |m| m.to(String) }   # => Ok("0.5 h")

Defined in other modules

record Duration

An elapsed span of time, in seconds.

Duration is an elapsed span used by Time, Date, and DateTime. A time Measure is deliberately not a Duration: 5.second describes a measurement.

Fields

seconds
Float

Defined in other modules

type TimeUnit

The time units, from nanoseconds to weeks. The base unit is the second.

Variants

  • Nanosecond
  • Microsecond
  • Millisecond
  • Second
  • Minute
  • Hour
  • Day
  • Week

Implements Unit.

Functions

factor Unit

factor(_)

symbol Unit

symbol(_)

extends Integer

More functions for Integer, added by this module.

Time-unit constructors on Integer: 5.second, 90.minute, 2.week.

Each answers a Measure whose display unit is the one you named, so 90.minute prints as minutes even though it is stored as 5400 seconds.

nanosecond

nanosecond : Measure

This many nanoseconds, as a Measure.

Returns the quantity, displayed in nanoseconds

Examples
100.nanosecond.to(String)   # => "100.0 ns"

microsecond

microsecond : Measure

This many microseconds, as a Measure.

Returns the quantity, displayed in microseconds

Examples
250.microsecond.to(String)   # => "250.0 μs"

millisecond

millisecond : Measure

This many milliseconds, as a Measure.

Returns the quantity, displayed in milliseconds

Examples
500.millisecond.to(String)   # => "500.0 ms"

second

second : Measure

This many seconds, as a Measure. Seconds are the base unit of time, so this is the one everything else converts through.

Returns the quantity, displayed in seconds

Examples
5.second.to(String)   # => "5.0 s"

minute

minute : Measure

This many minutes, as a Measure.

Returns the quantity, displayed in minutes

Examples
90.minute.convert(Hour)   # => Ok(1.5 h)

hour

hour : Measure

This many hours, as a Measure.

Returns the quantity, displayed in hours

Examples
(1.hour + 30.minute).map { |m| m.to(String) }   # => Ok("1.5 h")

day

day : Measure

This many days, as a Measure.

Returns the quantity, displayed in days

Examples
1.day.convertTo(Hour).map { |m| m.to(String) }   # => Ok("24.0 h")

week

week : Measure

This many weeks, as a Measure.

Returns the quantity, displayed in weeks

Examples
2.week.to(String)   # => "2.0 wk"

timeMeasure

timeMeasure(unit: TimeUnit) -> Measure

extends Float

More functions for Float, added by this module.

The same time-unit constructors on Float, for fractional quantities: 1.5.hour, 0.25.second.

nanosecond

nanosecond : Measure

This many nanoseconds, as a Measure.

Returns the quantity, displayed in nanoseconds

microsecond

microsecond : Measure

This many microseconds, as a Measure.

Returns the quantity, displayed in microseconds

millisecond

millisecond : Measure

This many milliseconds, as a Measure.

Returns the quantity, displayed in milliseconds

Examples
2.5.millisecond.to(String)   # => "2.5 ms"

second

second : Measure

This many seconds, as a Measure.

Returns the quantity, displayed in seconds

Examples
0.25.second.to(String)   # => "0.25 s"

minute

minute : Measure

This many minutes, as a Measure.

Returns the quantity, displayed in minutes

hour

hour : Measure

This many hours, as a Measure.

Returns the quantity, displayed in hours

Examples
1.5.hour.to(String)   # => "1.5 h"

day

day : Measure

This many days, as a Measure.

Returns the quantity, displayed in days

week

week : Measure

This many weeks, as a Measure.

Returns the quantity, displayed in weeks

timeMeasure

timeMeasure(unit: TimeUnit) -> Measure

module Units

Time-unit constructors, also available directly from the prelude.

Units.Hour and Hour name the same constructor: they match the same patterns and compare equal. Use the qualified spelling to make the unit family explicit.

90.minute.convert(Units.Hour)   # => Ok(1.5 h)

Nanosecond constant

Microsecond constant

Millisecond constant

Second constant

Minute constant

Hour constant

Day constant

Week constant

Submodules

  • Units.Data Data sizes: bytes, kilobytes, and their binary counterparts.
  • Units.Dynamic Runtime dimensional quantities. Unit dimensions use nominal Type identities, and all arithmetic composes the same normalized exponent maps.
  • Units.SI SI units: metres, grams, watts, volts and the rest, with prefixes and dimensional arithmetic.