=begin pod

=TITLE class SetHash

=SUBTITLE Mutable collection of distinct objects

    class SetHash does Setty { }

A C<SetHash> is a mutable set, meaning a collection of distinct elements in no
particular order. (For I<immutable> sets, see L<Set> instead.)

Objects/values of any type are allowed as set elements. Within a C<Set>, every
element is guaranteed to be unique (in the sense that no two elements would
compare positively with the L<===> operator):

=begin code
my $fruits = <peach apple orange apple apple>.SetHash;

say $fruits.elems;      # 3
say $fruits.keys.sort;  # apple orange peach
=end code

C<SetHash>es can be treated as object hashes using the C<{ }> postcircumfix
operator, which returns the value C<True> for keys that are elements of the set,
and C<False> for keys that aren't. Assigning a value that boolifies to C<True>
or C<False>, respectively, can be used to add or remove a set element:

=begin code
say $fruits<apple>;     # True
say $fruits<kiwi>;      # False

$fruits<apple kiwi> = False, True;
say $fruits.keys.sort;  # kiwi orange peach
=end code

=head1 Creating C<SetHash> objects

C<SetHash>es can be composed using C<SetHash.new>. Any positional parameters,
regardless of their type, become elements of the set:

    my $n = SetHash.new: "zero" => 0, "one" => 1, "two" => 2;
    say $n.keys.perl;        # ("zero" => 0, "one" => 1, "two" => 2).list
    say $n.keys.map(&WHAT);  # (Pair) (Pair) (Pair)

Alternatively, the C<.SetHash> coercer (or its functional form, C<SetHash()>)
can be called on an existing object to coerce it to a C<SetHash>. Its semantics
depend on the type and contents of the object. In general it evaluates the
object in list context and creates a set with the resulting items as elements,
although for Hash-like objects or Pair items, only the keys become elements of
the set - and keys mapped to values which boolify to C<False> are skipped:

    my $n = ("zero" => 0, "one" => 1, "two" => 2).SetHash;
    say $n.keys.perl;        # ("one", "two").list
    say $n.keys.map(&WHAT);  # (Str) (Str)

=head1 Operators

Perl 6 provides common set operators, which can take C<SetHash>es (or any other
collections) as input, although result sets are returned as immutable C<Set>s.
For example:

=begin code
my ($a, $b) = SetHash.new(1, 2, 3), SetHash.new(2, 4);

say $a (<) $b;  # False
say $a (&) $b;  # set(2)
say $a (^) $b;  # set(1, 3, 4)
say $a (|) $b;  # set(1, 2, 3, 4)

# Unicode versions:
say $a ⊂ $b;  # False
say $a ∩ $b;  # set(2)
say $a ⊖ $b;  # set(1, 3, 4)
say $a ∪ $b;  # set(1, 2, 3, 4)
=end code

See L<Set/Bag Operators|/language/setbagmix#Set/Bag Operators> for a
complete list of set operators with detailed explanations.

=head1 See Also

L<Sets, Bags, and Mixes|/language/setbagmix>

=end pod
