Algebra
Algebraic structures: combining values associatively.
Kex traits do not inherit from one another, so concrete types explicitly implement every structure whose laws they satisfy.
Monoid is "these two values combine, and there is a neutral one". Numbers, strings and lists all satisfy it, which is what lets repeat be written once:
"ab".repeat(3) # => "ababab"
[1].repeat(2) # => [1, 1]
5.repeat(3) # => 15
Ordering and comparison (Ordering, Comparable) live in comparable.kex.
trait Monoid
Types whose values combine associatively and have a neutral element.
Implemented by Integer (addition), String and List (concatenation), Map and both Set flavours (union), and Ordering ("first decision wins" — declared beside Ordering in comparable.kex).
Implemented by Integer, String, [A], Ordering, Map<K, V>, Queue<A>, Set<A>, UnorderedSet<A>, Stack<A>.
Required functions
An implementor writes these.
identity
identity : This
The neutral element: combining it with any value gives that value back.
combine must be associative and identity neutral on both sides.
Returns the identity
Examples
Integer.identity # => 0
String.identity # => ""
combine
combine(other: This) -> This
Combines this value with other.
Must be associative: a.combine(b).combine(c) and a.combine(b.combine(c)) have to agree.
Parameters
other- the value to combine with
Returns the combined value
Examples
5.combine(3) # => 8
"ab".combine("cd") # => "abcd"
[1].combine([2]) # => [1, 2]
Folding a list of values into one
parts.reduce(String.identity) { |acc, s| acc.combine(s) }
Provided functions
Every implementor gets these, written in terms of the required functions.
repeat
repeat(n: Integer) -> This
Combines this value with itself n times.
Repeating zero times gives the identity: "" for a string, 0 for an integer, [] for a list. A negative count is invalid and ends the program.
Parameters
n- how many copies to combine; must not be negative
Returns the repeated value
Examples
"ab".repeat(3) # => "ababab"
[1].repeat(2) # => [1, 1]
5.repeat(3) # => 15
"x".repeat(0) # => ""
Drawing a separator line
IO.printLine("-".repeat(40))
trait Group
A Monoid in which every value has an inverse that combines with it to give the identity.
Implemented by Integer, where the inverse is negation.
Implemented by Integer.
Required functions
An implementor writes these.
inverse
inverse : This
The value that combines with this one to give the identity.
Returns the inverse
Examples
5.inverse # => -5
5.combine(5.inverse) # => 0
extends Integer
More functions for Integer, added by this module.
Implements Monoid, Group over Integer for addition.
identity Monoid Group
0: the neutral element for addition.
Returns Integer — zero
Examples
Integer.identity # => 0
extends String
More functions for String, added by this module.
Implements Monoid.
extends [A]
More functions for List, added by this module.
Implements Monoid.
Implements Monoid over List<A> for concatenation.
identity Monoid
[]: the neutral element for concatenation.
Returns [A] — the empty list
Examples
[1].combine(List.identity) # => [1]
combine Monoid
combine(other: This) -> This
Concatenates other onto this list. Concatenation is the monoid operation for List.
Parameters
other- the list to append
Returns the concatenation
Examples
[1].combine([2, 3]) # => [1, 2, 3]
Flattening a list of lists
groups.reduce([]) { |acc, g| acc.combine(g) }