txt: ## bag.md
  class Bag
  
  Immutable collection of distinct objects with integer weights
  
  ```raku
  class Bag does Baggy { }
  ```
  
  A `Bag` is an immutable bag/multiset implementing [`Associative`](/type/Associative), meaning a collection of distinct elements in no particular order that each have an integer weight assigned to them signifying how many copies of that element are considered "in the bag". (For *mutable* bags, see [`BagHash`](/type/BagHash) instead.)
  
  `Bag`s are often used for performing weighted random selections - see [.pick](/routine/pick) and [.roll](/routine/roll).
  
  Objects/values of any type are allowed as bag elements. Within a `Bag`, items that would compare positively with the [===](/routine/===) operator are considered the same element, with the number of how many there are as its weight. But you can also easily get back the expanded list of items (without the order):
  
  ```raku
  my $breakfast = bag <spam eggs spam spam bacon spam>;
  
  say $breakfast.elems;      # OUTPUT: «3␤»
  say $breakfast.keys.sort;  # OUTPUT: «bacon eggs spam␤»
  
  say $breakfast.total;      # OUTPUT: «6␤»
  say $breakfast.kxxv.sort;  # OUTPUT: «bacon eggs spam spam spam spam␤»
  
  ```
  
  `Bag`s can be treated as object hashes using the [`{ }` postcircumfix operator](/language/operators#postcircumfix_{_}), or the [`< >` postcircumfix operator](/language/operators#postcircumfix_<_>) for literal string keys, which returns the corresponding integer weight for keys that are elements of the bag, and `0` for keys that aren't:
  
  ```raku
  my $breakfast = bag <spam eggs spam spam bacon spam>;
  say $breakfast<bacon>;    # OUTPUT: «1␤»
  say $breakfast<spam>;     # OUTPUT: «4␤»
  say $breakfast<sausage>;  # OUTPUT: «0␤»
  ```
  
  # [Creating `Bag` objects](#class_Bag "go to top of document")[§](#Creating_Bag_objects "direct link")
  
  `Bag`s can be composed using the [bag](#sub_bag) subroutine (or `Bag.new`, for which it is a shorthand). Any positional parameters, regardless of their type, become elements of the bag:
  
  ```raku
  my $n = bag "a" => 0, "b" => 1, "c" => 2, "c" => 2;
  say $n.keys.raku;        # OUTPUT: «(:c(2), :b(1), :a(0)).Seq␤»
  say $n.keys.map(&WHAT);  # OUTPUT: «((Pair) (Pair) (Pair))␤»
  say $n.values.raku;      # OUTPUT: «(2, 1, 1).Seq␤»
  ```
  
  Alternatively, the `.Bag` coercer (or its functional form, `Bag()`) can be called on an existing object to coerce it to a `Bag`. Its semantics depend on the type and contents of the object. In general it evaluates the object in list context and creates a bag with the resulting items as elements, although for Hash-like objects or Pair items, only the keys become elements of the bag, and the (cumulative) values become the associated integer weights:
  
  ```raku
  my $n = ("a" => 0, "b" => 1, "c" => 2, "c" => 2).Bag;
  say $n.keys.raku;        # OUTPUT: «("b", "c").Seq␤»
  say $n.keys.map(&WHAT);  # OUTPUT: «((Str) (Str))␤»
  say $n.values.raku;      # OUTPUT: «(1, 4).Seq␤»
  ```
  
  Furthermore, you can get a `Bag` by using bag operators (see next section) on objects of other types such as [`List`](/type/List), which will act like they internally call `.Bag` on them before performing the operation. Be aware of the tight precedence of those operators though, which may require you to use parentheses around arguments:
  
  ```raku
  say (1..5) (+) 4;  # OUTPUT: «Bag(1 2 3 4(2) 5)␤»
  ```
  
  You can also create a `Bag` with the `.new` method.
  
  ```raku
  my $breakfast = Bag.new( <spam eggs spam spam bacon spam> );
  ```
  
  Since 6.d (2019.03 and later) you can also use this syntax for parameterization of the `Bag`, to specify which type of values are acceptable:
  
  ```raku
  # only allow strings (Str) in the Bag
  my $breakfast = Bag[Str].new( <spam eggs spam spam bacon spam> );
  
  # only allow whole numbers (Int) in the Bag
  my $breakfast = Bag[Int].new( <spam eggs spam spam bacon spam> );
  # Type check failed in binding; expected Int but got Str ("spam")
  ```
  
  Finally, you can create Bag masquerading as a hash by using the `is` trait:
  
  ```raku
  my %b is Bag = <a b c>;
  say %b<a>;  # OUTPUT: «True␤»
  say %b<d>;  # OUTPUT: «False␤»
  ```
  
  Since 6.d (2019.03 and later), this syntax also allows you to specify the type of values you would like to allow:
  
  ```raku
  # limit to strings
  my %b is Bag[Str] = <a b c>;
  say %b<a>;  # OUTPUT: «True␤»
  say %b<d>;  # OUTPUT: «False␤»
  
  # limit to whole numbers
  my %b is Bag[Int] = <a b c>;
  # Type check failed in binding; expected Int but got Str ("a")
  ```
  
  # [Operators](#class_Bag "go to top of document")[§](#Operators "direct link")
  
  See [Operators with set semantics](/language/setbagmix#Operators_with_set_semantics) for a complete list of "set operators" applicable to, among other types, `Bag`.
  
  Examples:
  
  ```raku
  my ($a, $b) = bag(2, 2, 4), bag(2, 3, 3, 4);
  
  say $a (<) $b;   # OUTPUT: «False␤»
  say $a (<=) $b;  # OUTPUT: «False␤»
  say $a (^) $b;   # OUTPUT: «Bag(3(2) 2)␤»
  say $a (+) $b;   # OUTPUT: «Bag(2(3) 4(2) 3(2))␤»
  
  # Unicode versions:
  say $a ⊂ $b;  # OUTPUT: «False␤»
  say $a ⊆ $b;  # OUTPUT: «False␤»
  say $a ⊖ $b;  # OUTPUT: «Bag(3(2) 2)␤»
  say $a ⊎ $b;  # OUTPUT: «Bag(2(3) 4(2) 3(2))␤»
  
  ```
  
  # [Subroutines](#class_Bag "go to top of document")[§](#Subroutines "direct link")
  
  ## [sub bag](#class_Bag "go to top of document")[§](#sub_bag "direct link")
  
  ```raku
  sub bag(*@args --> Bag)
  ```
  
  Creates a new `Bag` from `@args`.
  
  # [Note on `reverse` and ordering](#class_Bag "go to top of document")[§](#Note_on_reverse_and_ordering "direct link")
  
  This method is inherited from [`Any`](/type/Any#routine_reverse), however, [`Mix`](/type/Mix)es do not have an inherent order and you should not trust it returning a consistent output.
  
  # [See also](#class_Bag "go to top of document")[§](#See_also "direct link")
  
  [Sets, Bags, and Mixes](/language/setbagmix)
  
  # [Typegraph](# "go to top of document")[§](#typegraphrelations "direct link")
  
  Type relations for `Bag`
  
  
  
  raku-type-graph
  
  
  
  Bag
  Bag
  
  
  Any
  Any
  
  
  Bag->Any
  
  
  
  Baggy
  Baggy
  
  
  Bag->Baggy
  
  
  
  Mu
  Mu
  
  
  Any->Mu
  
  
  
  Associative
  Associative
  
  
  QuantHash
  QuantHash
  
  
  QuantHash->Associative
  
  
  
  Baggy->QuantHash
  
  [Expand chart above](/assets/typegraphs/Bag.svg)
  