Numberprelude
make Integer
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)
modulo
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.
modulo(n) : Integer -> Integer
Parameters
nInteger- the modulus
Returns: Integer — 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?
Returns true when the integer falls inside range, endpoints included.
in?(range) : Range<Integer> -> Bool
Parameters
rangeRange<Integer>- the inclusive range
Returns: Bool — 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
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.
times(block) : (Integer -> Void) -> Void
Parameters
fInteger -> Void- called once per iteration with the index
Returns: Void —
Examples
3.times { |i| IO.printLine(i) } # prints 0, then 1, then 2
Repeating an action
retries.times { |_| attemptConnection }
make Float
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)
in?
Returns true when the float falls inside range, endpoints included.
in?(range) : Range<Float> -> Bool
Parameters
rangeRange<Float>- the inclusive range
Returns: Bool — 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
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.
function parse
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.
parse(s) : String -> Result<Integer, ParseError>
parse(s) : String -> Integer -> Result<Integer, ParseError>
Parameters
sString- the text to parse
Returns: Result<Integer, ParseError> — 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
function parsePrefix
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.
parsePrefix(s) : String -> (Integer, String)?
Parameters
sString- the text to parse from
Returns: (Integer, String)? — 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.
function parse
Parses the whole string as a float.
The string must be entirely consumed; anything left over makes it an Error carrying a ParseError.
parse(s) : String -> Result<Float, ParseError>
Parameters
sString- the text to parse
Returns: Result<Float, ParseError> — 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)
function parsePrefix
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.
parsePrefix(s) : String -> (Float, String)?
Parameters
sString- the text to parse from
Returns: (Float, String)? — 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.
function parse
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.
parse(s) : String -> Result<Number, ParseError>
Parameters
sString- the text to parse
Returns: Result<Number, ParseError> — the number, or a described failure
Examples
Number.parse("42") # => Ok(42)
Number.parse("3.5") # => Ok(3.5)
Number.parse("x") # => Error(ParseError { ... })