=begin pod

=TITLE role Setty

=SUBTITLE Collection of distinct objects

    role Setty does QuantHash { }

A role for collections which make sure that each element can only appear once.
See L<Set> and L<SetHash>.

=head1 Methods

=head2 method grab

    method grab($count = 1)

Removes and returns C<$count> elements chosen at random (without repetition)
from the set.

If C<*> is passed as C<$count>, or C<$count> is greater than or equal to the
size of the set, then all its elements are removed and returned in random order.

Only works on mutable sets; When used on an immutable set, it results in an
exception.

=head2 method grabpairs

    method grabpairs($count = 1)

Removes C<$count> elements chosen at random (without repetition) from the set,
and returns a list of C<Pair> objects whose keys are the grabbed elements and
whose values are C<True>.

If C<*> is passed as C<$count>, or C<$count> is greater than or equal to the
size of the set, then all its elements are removed and returned as C<Pair>s in
the aforementioned way in random order.

Only works on mutable sets; When used on an immutable set, it results in an
exception.

=head2 method pick

    multi method pick($count = 1)

Returns C<$count> elements chosen at random (without repetition) from the set.

If C<*> is passed as C<$count>, or C<$count> is greater than or equal to the
size of the set, then all its elements are returned in random order.

=head2 method roll

    multi method roll($count = 1)

Returns a lazy list of C<$count> elements, each randomly selected from the set.
Each random choice is made independently, like a separate die roll where each
die face is a set element.

If C<*> is passed as C<$count>, the list is infinite.

=head2 method keys

Defined as:

    multi method keys(Setty:D:) returns Seq:D

Returns a L<Seq|/type/Seq> of all elements of the set.

    my $s = Set.new(1, 2, 3);
    say $s.keys;                                      # (3 1 2)

=head2 method values

Defined as:

    multi method values(Setty:D:) returns Seq:D

Returns a L<Seq|/type/Seq> containing as many C<True> values as the set has elements.

    my $s = Set.new(1, 2, 3);
    say $s.values;                                    # (True True True)

=head2 method kv

Defined as:

    multi method kv(Setty:D:) returns Seq:D

Returns a L<Seq|/type/Seq> of the set's elements and C<True> values interleaved.

    my $s = Set.new(1, 2, 3);
    say $s.kv;                                        # (3 True 1 True 2 True)

=head2 method elems

    method elems(--> Int)

The number of elements of the set.

=head2 method total

    method total(--> Int)

The total of all the values of the C<QuantHash> object. For a C<Setty>
object, this is just the number of elements.

=head2 method default

Defined as:

    method default returns False

Returns the default value of the invocant, i.e. the value which is returned
when trying to access an element in the C<Setty> object which has not been
previously initialized or when accessing an element which has explicitly
been set to C<Nil> or C<False>.

    my $s1 = SetHash.new(1, 2, 3);
    say $s1{2};                                           # True
    $s1{2} = Nil;
    say $s1{2};                                           # False
    # access non initialized element
    say $s1{4};                                           # False

=head2 method ACCEPTS

    method ACCEPTS($other)

Returns C<True> if C<$other> and C<self> contain all the same elements,
and no others.

=head2 method Bag

Defined as:

    method Bag(Setty:D:) returns Bag:D

Returns a L<Bag|/type/Bag> containing the elements of the invocant.

    my Bag $b = Set.new(1, 2, 3).Bag;
    say $b;                                           # bag(3, 1, 2)

=head2 method BagHash

Defined as:

    method BagHash(Setty:D:) returns BagHash:D

Returns a L<BagHash|/type/BagHash> containing the elements of the invocant.

    my BagHash $b = Set.new(1, 2, 3).BagHash;
    say $b;                                           # BagHash.new(3, 1, 2)

=head2 method Bool

Defined as:

    multi method Bool(Setty:D:) returns Bool:D

Returns C<True> if the invocant contains at least one element.

    my $s1 = Set.new(1, 2, 3);
    say $s1.Bool;                                     # True

    my $s2 = $s1 ∩ Set.new(4, 5);                     # set intersection operator
    say $s2.Bool;                                     # False

=head1 See Also

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

=end pod
