iyi

Standard library, 0.18.0

std/set

The set algebra the prelude's Set(T) does not have.

import std/set to use it. Source: src/std/set.iyi at v0.18.0.

The prelude's Set(T) (src/iyi/set.iyi) answers "have I seen this": add, includes?, delete, each, to_a, -, size, empty?. This module reopens that one type rather than defining a second one, so [1, 2].to_set | other works on the set the prelude hands out, and a program has one Set. It adds:

* union `|` (and `+`, the same thing), intersection `&`, symmetric
  difference `^`; `-` is the prelude's;
* the relations `subset_of?`, `proper_subset_of?`, `superset_of?`,
  `proper_superset_of?`, `disjoint?`, `intersects?`;
* `==` by membership (the prelude's `Object#==` is identity), and a
  `hash` that agrees with it, so a set can be a hash key;
* `<<`, `concat`, `dup`.

Every operator answers a new set, in this set's order first; nothing here moves the receiver except << and concat, which say so.

impl Enumerable for Set(T) lives in std/enumerable beside Array's — the module that owns the trait is the one R-3 lets say it — so with import std/enumerable a set also has map, select, sum, min, max, to_a and the rest. This module imports it, so a caller of std/set gets both.

Set(T)class, reopened

std/setiyi doc src/std/set.iyi
class ::Set(T)
  # Intersection: what is in both, in this set's order.
  def &(other : Set(U)) : Set(T) forall U
  # `+` is union: two sets added are one set.
  def +(other : Set(U)) : Set(T | U) forall U
  # Adds value and answers the set, for chaining: `set << 1 << 2`.
  def <<(value : T) : Set(T)
  # The same members, in any order, where one element type holds the
  # other, as tuples compare (src/iyi/object.iyi).
  def ==(other : Set(U)) : Bool forall U
  # Symmetric difference: what is in exactly one of the two.
  def ^(other : Set(U)) : Set(T | U) forall U
  # Adds every element of other; answers the set.
  def concat(other : Set(T)) : Set(T)
  # No element in common; two empty sets are disjoint.
  def disjoint?(other : Set(U)) : Bool forall U
  # A copy with the same elements in the same order.
  def dup : Set(T)
  # Whether value, of any type, is a member: one this set's type cannot
  # hold is not.
  protected def has_member?(value) : Bool
  # Equal sets hash alike, and unequal ones apart. Each member's hash goes
  # through splitmix64's finaliser before a wrapping sum, which does not
  # care about order the way the sets do not, and the size is folded in
  # after, as `Array#hash` folds it. The members' hashes summed as they
  # were put a set of small integers at their total, `Int32#hash` being the
  # value: {1, 4} and {2, 3} were one key, the 11,175 sets {i, j} with
  # i < j < 150 had 297 hashes between them, and a table of such keys grew
  # quadratically.
  def hash : Int32
  # At least one element in common.
  def intersects?(other : Set(U)) : Bool forall U
  # A subset that is not the same set.
  def proper_subset_of?(other : Set(U)) : Bool forall U
  def proper_superset_of?(other : Set(U)) : Bool forall U
  # Every element of this set is in other. The empty set is a subset of
  # every set, itself included.
  def subset_of?(other : Set(U)) : Bool forall U
  def superset_of?(other : Set(U)) : Bool forall U
  # Union: everything in either, this set's elements first. The other set
  # may be of another element type, as everything below may: the union of
  # a `Set(Int32)` and a `Set(Int32?)` is a `Set(Int32?)`, either way round.
  # Restricted to `Set(T)`, a set of the narrower type was taken for the
  # wider one and not back, and where the body then asked the narrower set
  # about a member of the wider type it failed to compile inside this file:
  # `Set(Int32?) == Set(Int32)`, `&`, `^`, `subset_of?` and the rest, while
  # `Set(Int32) == Set(Int32?)` answered false for the same members.
  def |(other : Set(U)) : Set(T | U) forall U
end