Set
Sets are immutable collections of distinct elements. Mutation methods (suffixed !) return a new set and rebind the receiver variable — they do not modify in place. Membership is structural equality, the same equality == and Map keys use, so records and tuples are compared by value. == between two sets needs no overload of its own for the same reason: each flavour keeps its backing canonical — sorted and duplicate free, or a map — so comparing the records structurally already IS set equality.
Two flavours, differing only in how they store their elements:
Set sorted, so iteration is in ascending element order and the
elements must be Orderable.
UnorderedSet hash-backed, so membership does not pay for ordering and
the elements need only be comparable. Iteration order is
unspecified — never write a test against it.
Both wrap structures the runtime already has (a list and a map), so no set is opaque: .items is always a real list you can hand to anything.
Those two backings are also the ones the BEAM's own set libraries use — a Set is laid out exactly like an ordsets term and an UnorderedSet exactly like a sets v2 term — so the operations here can be routed to the native BIFs later without changing what a set IS. What rules out adopting gb_sets instead is the other backend: a tree-walk interpreter cannot produce an opaque BEAM term, and a set that only one backend can build is not a set the prelude can offer.
record Set<A>
The invariant every Set method preserves: items is sorted and duplicate free. Build one with Set.from rather than by hand — the record literal does no deduplication. Reading .items back is the field itself, so handing a set's elements to list code costs nothing:
Set.from([3, 1, 2]).items # => [1, 2, 3]
Fields
items[A]optional
Implements Enumerable, Foldable, Monoid, Showable, Blankable.
Methods
reduce Enumerable Foldable
reduce(acc, f)
Enumerable primitive: fold over the elements in ascending order. Collection-producing operations come from Enumerable and traversal queries from Foldable; the set-returning ones are overridden below, because Enumerable's defaults answer with a list.
contains?
contains?(value: A) -> Bool
Returns true if value is a member.
Examples
Set.from([1, 2, 3]).contains?(2) # => true
count Foldable
count : Integer
The number of distinct elements.
Examples
Set.from([1, 1, 2]).count # => 2
add
add(value: A) -> Set<A>
Returns a new set with value added. No-op if it is already a member. Use add! to rebind the receiver variable.
Examples
Set.from([1, 2]).add(3) # => Set(1, 2, 3)
delete
delete(value: A) -> Set<A>
Returns a new set without value. No-op if it is not a member. Use delete! to rebind the receiver variable.
Examples
Set.from([1, 2, 3]).delete(2) # => Set(1, 3)
union
union(other: Set<A>) -> Set<A>
Every element of either set.
Examples
Set.from([1, 2]).union(Set.from([2, 3])) # => Set(1, 2, 3)
intersect
intersect(other: Set<A>) -> Set<A>
The elements both sets share.
Examples
Set.from([1, 2, 3]).intersect(Set.from([2, 3, 4])) # => Set(2, 3)
difference
difference(other: Set<A>) -> Set<A>
The elements of this set that other does not have.
Examples
Set.from([1, 2, 3]).difference(Set.from([2])) # => Set(1, 3)
symmetricDifference
symmetricDifference(other: Set<A>) -> Set<A>
The elements in exactly one of the two sets.
Examples
Set.from([1, 2]).symmetricDifference(Set.from([2, 3])) # => Set(1, 3)
subset?
subset?(other: Set<A>) -> Bool
Returns true if every element of this set is in other.
Examples
Set.from([1, 2]).subset?(Set.from([1, 2, 3])) # => true
disjoint?
disjoint?(other: Set<A>) -> Bool
Returns true if the two sets share no element.
Examples
Set.from([1, 2]).disjoint?(Set.from([3])) # => true
+
+(other: Set<A>) -> Set<A>
+ unions, with either another set or a plain list — xs + [y] is the everyday way to add one element without naming a method.
Examples
Set.from([1, 2]) + [3] # => Set(1, 2, 3)
Set.from([1]) + Set.from([2]) # => Set(1, 2)
-
-(other: Set<A>) -> Set<A>
- removes, taking either another set or a plain list.
Examples
Set.from([1, 2, 3]) - [2] # => Set(1, 3)
map Enumerable
map(f: (A -> B)) -> Set<B>
Set overrides the collection-returning HOFs: Enumerable's defaults answer with a list, and mapping a set should give back a set. map may collapse elements — Set.from([1, -1]).map { |x| x.abs } has one member, not two.
Examples
Set.from([1, 2, 3]).map { |x| x * 2 } # => Set(2, 4, 6)
filter Enumerable
filter(pred: (A -> Bool)) -> Set<A>
Returns a new set keeping only the elements pred accepts.
Examples
Set.from([1, 2, 3]).filter { |x| x > 1 } # => Set(2, 3)
From Enumerable
mapIndexed- Transforms each item together with its 0-based position, collecting the results into a list.
flatMap- Maps each item to a list and concatenates the results.
collect- Maps each item through
f(returning anOptional), keeping and unwrapping theJust(y)results and droppingNone.
From Foldable
each- Applies
fto each item for its side effects. eachIndexed- Applies
fto each item together with its 0-based position, for side effects. all?- True if every item satisfies
pred. any?- True if at least one item satisfies
pred. find- The first item satisfying
predwrapped in Just, or None.
From Monoid
repeat- Combines this value with itself
ntimes.
From Showable
record UnorderedSet<A>
The invariant every UnorderedSet method preserves: slots maps each member to true and holds nothing else. Its keys ARE the elements.
Fields
slots{A: Bool}optional
Implements Enumerable, Foldable, Monoid, Showable, Blankable.
Methods
reduce Enumerable Foldable
reduce(acc, f)
Enumerable primitive: fold over the elements. The order is whatever the underlying map hands back — unspecified, and not to be relied on.
contains?
contains?(value: A) -> Bool
Returns true if value is a member. This is the operation the flavour exists for: a map lookup, with no ordering to maintain.
Examples
UnorderedSet.from([1, 2, 3]).contains?(2) # => true
items
items : [A]
The elements as a list, in unspecified order.
Examples
UnorderedSet.from([1, 2, 3]).items.sort # => [1, 2, 3]
add
add(value: A) -> UnorderedSet<A>
Returns a new set with value added. Use add! to rebind the receiver.
delete
delete(value: A) -> UnorderedSet<A>
Returns a new set without value. Use delete! to rebind the receiver.
difference
difference(other: UnorderedSet<A>) -> UnorderedSet<A>
The elements of this set that other does not have.
symmetricDifference
symmetricDifference(other: UnorderedSet<A>) -> UnorderedSet<A>
The elements in exactly one of the two sets.
subset?
subset?(other: UnorderedSet<A>) -> Bool
Returns true if every element of this set is in other.
superset?
superset?(other: UnorderedSet<A>) -> Bool
Returns true if this set has every element of other.
-
-(other: UnorderedSet<A>) -> UnorderedSet<A>
- removes, taking either another set or a plain list.
map Enumerable
map(f: (A -> B)) -> UnorderedSet<B>
The collection-returning HOFs answer with a set, not a list.
filter Enumerable
filter(pred: (A -> Bool)) -> UnorderedSet<A>
reject
reject(pred: (A -> Bool)) -> UnorderedSet<A>
From Enumerable
mapIndexed- Transforms each item together with its 0-based position, collecting the results into a list.
flatMap- Maps each item to a list and concatenates the results.
collect- Maps each item through
f(returning anOptional), keeping and unwrapping theJust(y)results and droppingNone.
From Foldable
each- Applies
fto each item for its side effects. eachIndexed- Applies
fto each item together with its 0-based position, for side effects. all?- True if every item satisfies
pred. any?- True if at least one item satisfies
pred. find- The first item satisfying
predwrapped in Just, or None.
From Monoid
repeat- Combines this value with itself
ntimes.
From Showable
module Set
from
from(items: [A]) -> Set<A>
Builds a set from any list, discarding duplicates and sorting what is left. Deduplication goes through a Map rather than List.uniq: map keys are unique under exactly the structural equality a set wants, and each element costs one insertion instead of a scan of everything kept so far.
Examples
Set.from([3, 1, 2, 3]) # => Set(1, 2, 3)
Set.from("hello".chars) # => Set('e', 'h', 'l', 'o')
module UnorderedSet
from
from(items: [A]) -> UnorderedSet<A>
Builds an unordered set from any list, discarding duplicates. Nothing is sorted, so this does not require Orderable elements.
Examples
UnorderedSet.from([3, 1, 2, 3]).count # => 3