kex docs Standard Library

Number

type Integer

Implements Monoid, Group, Blankable, Truthyable.

Whole numbers, of arbitrary size.

Integer has no width limit: factorials and cryptographic moduli are ordinary values, not a special big-number type you have to opt into.

Integer and Float are one numeric tower: they compare and order across the boundary, so 0 == 0.0 is true and [1, 2.5, 3].sort works. What differs is the arithmetic. / on two integers is integer division, and sqrt answers a Float because a square root generally is one.

7 / 2          # => 3      (integer division)
7.0 / 2.0      # => 3.5
16.sqrt        # => 4.0    (a Float, even from an Integer)
(-7).modulo(3) # => 2      (mathematical modulo, not C remainder)

even?

even? : Bool

Returns true when the integer is divisible by two. Zero is even, and negative numbers follow the same rule.

Returns true for an even integer

Examples
4.even?      # => true
3.even?      # => false
(-2).even?   # => true

Splitting a list into evens and odds

[1, 2, 3, 4].partition { |n| n.even? }   # => ([2, 4], [1, 3])

odd?

odd? : Bool

Returns true when the integer is not divisible by two. The opposite of even?.

Returns true for an odd integer

Examples
3.odd?   # => true
4.odd?   # => false

abs

abs : Integer

Returns the magnitude of the integer, discarding its sign.

Returns the absolute value

Examples
(-5).abs   # => 5
5.abs      # => 5

Distance between two positions

(a - b).abs

sqrt

sqrt : Float

Returns the square root as a Float.

The result is a Float even when the root is exact, because in general it is not. Round or floor it when you need an integer back.

Returns the square root

Examples
16.sqrt          # => 4.0
2.sqrt           # => 1.4142135623730951
16.sqrt.round    # => 4

modulo

modulo(n: Integer) -> Integer

Returns this modulo n.

The result takes the sign of n, which is mathematical modulo rather than the C-style remainder other languages give. That is what makes it safe for wrapping an index that may have gone negative.

Parameters
n
the modulus

Returns the remainder, with the sign of n

Examples
7.modulo(3)      # => 1
(-7).modulo(3)   # => 2

Wrapping an index around a list

let items = ["a", "b", "c"]
items.at((-1).modulo(items.count))   # => Just("c")

in?

in?(range: Range<Integer>) -> Bool

Returns true when the integer falls inside range, endpoints included.

Parameters
range
the inclusive range

Returns true when the integer is in range

Examples
5.in?(1..10)    # => true
11.in?(1..10)   # => false

Validating a port number

port.in?(1..65535)

times

times(block: (Integer -> Void)) -> Void

Calls f exactly this times, passing the 0-based iteration index.

This is the counting loop. When you want the numbers themselves rather than a count of repetitions, (1..n).items.each often reads better.

Parameters
f
called once per iteration with the index
Examples
3.times { |i| IO.printLine(i) }   # prints 0, then 1, then 2

Repeating an action

retries.times { |_| attemptConnection }

floor

floor : Integer

Returns the integer unchanged. Present so that code written against Number works whichever half of the tower it is handed.

Returns the same integer

Examples
7.floor   # => 7

ceil

ceil : Integer

Returns the integer unchanged. The Integer counterpart of Float.ceil.

Returns the same integer

Examples
7.ceil   # => 7

round

round : Integer

Returns the integer unchanged. The Integer counterpart of Float.round.

Returns the same integer

Examples
7.round   # => 7

From Monoid

repeat
Combines this value with itself n times.

Defined in other modules

type Float

Implements Blankable, Truthyable.

Double-precision floating-point numbers.

A Kex Float is always finite. An operation that would produce NaN or Infinity raises instead: the same rule the BEAM enforces, where those two values cannot exist at all. So a Float you are holding is always a real number, and there is no nan? to check for.

Float and Integer compare and order across the boundary; see Integer for the rest of the numeric tower.

3.7.floor      # => 3
3.7.round      # => 4
(-3.7).toInteger  # => -3   (truncates toward zero)

abs

abs : Float

Returns the magnitude of the float, discarding its sign.

Returns the absolute value

Examples
(-3.14).abs   # => 3.14
3.14.abs      # => 3.14

An approximate-equality test

(a - b).abs < 0.0001

sqrt

sqrt : Float

Returns the square root. Raises for a negative receiver, which has no real root.

Returns the square root

Examples
25.0.sqrt   # => 5.0
2.0.sqrt    # => 1.4142135623730951

in?

in?(range: Range<Float>) -> Bool

Returns true when the float falls inside range, endpoints included.

Parameters
range
the inclusive range

Returns true when the float is in range

Examples

Comparing directly is usually clearer for floats

let ratio = 0.75
ratio >= 0.0 && ratio <= 1.0   # => true

floor

floor : Integer

Returns the largest integer that is not greater than the float: it always rounds toward negative infinity, which is what separates it from toInteger for negative values.

Returns the floor

Examples
3.7.floor      # => 3
3.2.floor      # => 3
(-3.2).floor   # => -4

ceil

ceil : Integer

Returns the smallest integer that is not less than the float: it always rounds toward positive infinity.

Returns the ceiling

Examples
3.2.ceil       # => 4
3.0.ceil       # => 3
(-3.7).ceil    # => -3

How many pages of a fixed size a list needs

(items.count.to(Float).or(0.0) / 20.0).ceil

round

round : Integer

Returns the nearest integer, with halves rounding away from zero.

Returns the rounded value

Examples
3.2.round    # => 3
3.5.round    # => 4
3.7.round    # => 4

toInteger

toInteger : Integer

Truncates toward zero and returns the result as an Integer: it drops the fractional part rather than rounding, so it differs from both floor and round for negative values.

Returns the truncated value

Examples
3.7.toInteger      # => 3
(-3.7).toInteger   # => -3   (floor would give -4)

Defined in other modules

module Integer

Reading integers out of text.

Use parse when a failure needs explaining and "42".to(Integer) when it does not: to answers a plain Optional, parse answers a Result carrying a ParseError that says where it stopped and what it had read so far.

parse

parse(s: String) -> Result<Integer, ParseError>
parse(s: String, radix: Integer) -> Result<Integer, ParseError>

Parses the whole string as a base-10 integer.

The string must be entirely consumed: leading or trailing characters make it an Error, with a ParseError describing where parsing stopped. Use parsePrefix when a trailing remainder is expected.

Parameters
s
the text to parse

Returns the integer, or a described failure

Examples
Integer.parse("42")     # => Ok(42)
Integer.parse("-7")     # => Ok(-7)
Integer.parse("4x")     # => Error(ParseError { ... rest: "x" ... })

Reading a setting with a fallback

let port = Integer.parse(raw).or(8080)

Reporting why the input was rejected

match Integer.parse(raw) do
  Ok(n)    => IO.printLine("port ${n}")
  Error(e) => IO.printError("bad port: ${e.message}")
end

parsePrefix

parsePrefix(s: String) -> (Integer, String)?

Parses an integer from the front of the string and returns it together with whatever text was left over.

This is the building block for hand-written scanners: parse a number, keep going from the remainder. Answers None when the string does not begin with a number at all.

Parameters
s
the text to parse from

Returns the value and the unconsumed remainder

Examples
Integer.parsePrefix("42abc")   # => Just((42, "abc"))
Integer.parsePrefix("abc")     # => None

Reading a leading count off a line

match Integer.parsePrefix("3 items") do
  Just(pair) => do
    let (count, rest) = pair
    IO.printLine("${count} of${rest}")   # prints: 3 of items
  end
  None => IO.printError("no leading count")
end

module Float

Reading floating-point numbers out of text.

parse

parse(s: String) -> Result<Float, ParseError>

Parses the whole string as a float.

The string must be entirely consumed; anything left over makes it an Error carrying a ParseError.

Parameters
s
the text to parse

Returns the float, or a described failure

Examples
Float.parse("3.5")     # => Ok(3.5)
Float.parse("-0.25")   # => Ok(-0.25)
Float.parse("3.5m")    # => Error(ParseError { ... rest: "m" ... })

Averaging a column of text values

rows.map { |r| Float.parse(r).or(0.0) }.sum / rows.count.to(Float).or(1.0)

parsePrefix

parsePrefix(s: String) -> (Float, String)?

Parses a float from the front of the string and returns it together with the unconsumed remainder. Answers None when the string does not begin with a number.

Parameters
s
the text to parse from

Returns the value and the remainder

Examples
Float.parsePrefix("3.5rest")   # => Just((3.5, "rest"))
Float.parsePrefix("rest")      # => None

Splitting a measurement from its unit

Float.parsePrefix("12.5kg")   # => Just((12.5, "kg"))

module Number

Reading a number out of text without deciding in advance which half of the numeric tower it belongs to.

parse

parse(s: String) -> Result<Number, ParseError>

Parses the whole string as an Integer or a Float, whichever the text describes.

Use it when the input's shape is not known ahead of time: a config value, a CSV column that may hold either.

Parameters
s
the text to parse

Returns the number, or a described failure

Examples
Number.parse("42")     # => Ok(42)
Number.parse("3.5")    # => Ok(3.5)
Number.parse("x")      # => Error(ParseError { ... })