txt: ## mix.md
  class Mix
  
  Immutable collection of distinct objects with Real weights
  
  ```raku
  class Mix does Mixy { }
  ```
  
  A `Mix` is an immutable collection of distinct elements in no particular order that each have a real-number weight assigned to them. (For *mutable* mixes, see [`MixHash`](/type/MixHash) instead.)
  
  `Mix`es are often used for performing weighted random selections - see [.roll](/routine/roll).
  
  Objects/values of any type are allowed as mix elements. Within a `Mix`, items that would compare positively with the [===](/routine/===) operator are considered the same element, with a combined weight.
  
  ```raku
  my $recipe = (butter => 0.22, sugar => 0.1,
                flour => 0.275, sugar => 0.02).Mix;
  
  say $recipe.elems;      # OUTPUT: «3␤»
  say $recipe.keys.sort;  # OUTPUT: «butter flour sugar␤»
  say $recipe.pairs.sort; # OUTPUT: «"butter" => 0.22 "flour" => 0.275 "sugar" => 0.12␤»
  say $recipe.total;      # OUTPUT: «0.615␤»
  
  ```
  
  `Mix`es 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 numeric weight for keys that are elements of the mix, and `0` for keys that aren't:
  
  ```raku
  my $recipe = (butter => 0.22, sugar => 0.1,
                flour => 0.275, sugar => 0.02).Mix;
  say $recipe<butter>;     # OUTPUT: «0.22␤»
  say $recipe<sugar>;      # OUTPUT: «0.12␤»
  say $recipe<chocolate>;  # OUTPUT: «0␤»
  ```
  
  # [Creating `Mix` objects](#class_Mix "go to top of document")[§](#Creating_Mix_objects "direct link")
  
  `Mix`es can be composed using the [mix](#sub_mix) subroutine (or `Mix.new`, for which it is a shorthand). Any positional parameters, regardless of their type, become elements of the mix - with a weight of `1` for each time the parameter occurred:
  
  ```raku
  my $n = mix "a", "a", "b" => 0, 3.14, π, π; # The Pair is a single element
  say $n.keys.map: *.^name; # OUTPUT: «(Rat Pair Num Str)␤»
  say $n.pairs;
  # OUTPUT: «(3.14 => 1 (b => 0) => 1 3.141592653589793 => 2 a => 2)␤»
  ```
  
  Alternatively, the `.Mix` coercer (or its functional form, `Mix()`) can be called on an existing object to coerce it to a `Mix`. Its semantics depend on the type and contents of the object. In general it evaluates the object in list context and creates a mix with the resulting items as elements, although for Hash-like objects or Pair items, only the keys become elements of the mix, and the (cumulative) values become the associated numeric weights:
  
  ```raku
  my $n = ("a", "a", "b" => 0, "c" => 3.14).Mix;
  say $n.keys.map(&WHAT);  # OUTPUT: «((Str) (Str))␤»
  say $n.pairs;            # OUTPUT: «(a => 2 c => 3.14)␤»
  ```
  
  Elements with a 0 value, as `b` above, are simply eliminated from the `Mix`.
  
  Alternatively, since `Mix`es are [`Associative`](/type/Associative), we can use the `%` sigil to declare them; in that case, we can employ `is` to declare their type:
  
  ```raku
  my %n is Mix = ("a", "a", "b" => 0, "c" => 3.14);
  say %n.^name; # OUTPUT: «Mix␤»
  say %n;       # OUTPUT: «Mix(a(2) c(3.14))␤»
  ```
  
  Since 6.d (2019.03 and later) it is also possible to specify the type of values you would like to allow in a `Mix`. This can either be done when calling `.new`:
  
  ```raku
  # only allow strings
  my $n = Mix[Str].new: <a b b c c c>;
  ```
  
  or using the masquerading syntax:
  
  ```raku
  # only allow strings
  my %m is Mix[Str] = <a b b c c c>;
  say %m<b>;  # OUTPUT: «2␤»
  say %m<d>;  # OUTPUT: «0␤»
  
  # only allow whole numbers
  my %m is Mix[Int] = <a b b c c c>;
  # Type check failed in binding; expected Int but got Str ("a")
  ```
  
  # [Operators](#class_Mix "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, `Mix`.
  
  Examples:
  
  ```raku
  my $this-mix = (sugar => ⅓, spice => ¼, all-things-nice => ¾);
  my $that-mix = ( sugar => 1, spice => 2);
  
  say $that-mix (<) $this-mix;     # OUTPUT: «True␤»
  say $that-mix (^) $this-mix;     # OUTPUT: «Set(all-things-nice)␤»
  say $that-mix (+) $this-mix;     # OUTPUT: «Bag(spice(2) sugar)␤»
  
  # Unicode versions:
  say $that-mix ⊂ $this-mix;     # OUTPUT: «True␤»
  say $that-mix ⊖ $this-mix;     # OUTPUT: «Set(all-things-nice)␤»
  say $that-mix ⊎ $this-mix;     # OUTPUT: «Bag(spice(2) sugar)␤»
  
  ```
  
  ## [sub mix](#class_Mix "go to top of document")[§](#sub_mix "direct link")
  
  ```raku
  sub mix(*@args --> Mix)
  ```
  
  Creates a new `Mix` from `@args`.
  
  # [Methods](#class_Mix "go to top of document")[§](#Methods "direct link")
  
  ## [method Bag](#class_Mix "go to top of document")[§](#method_Bag "direct link")
  
  ```raku
  method Bag (--> Bag:D)
  ```
  
  Coerces the `Mix` to a [`Bag`](/type/Bag). The weights are convert to [`Int`](/type/Int), which means the number of keys in the resulting [`Bag`](/type/Bag) can be fewer than in the original `Mix`, if any of the weights are negative or truncate to zero.
  
  ## [method BagHash](#class_Mix "go to top of document")[§](#method_BagHash "direct link")
  
  ```raku
  method BagHash (--> BagHash:D)
  ```
  
  Coerces the `Mix` to a [`BagHash`](/type/BagHash). The weights are convert to [`Int`](/type/Int), which means the number of keys in the resulting [`BagHash`](/type/BagHash) can be fewer than in the original `Mix`, if any of the weights are negative or truncate to zero.
  
  ## [method reverse](#class_Mix "go to top of document")[§](#method_reverse "direct link")
  
  *Note*: This method is inherited from [Any](/type/Any#routine_reverse), however, `Mix`es do not have an inherent order and you should not trust it returning a consistent output.
  
  ## [method total](#class_Mix "go to top of document")[§](#method_total "direct link")
  
  ```raku
  method total(Mix:D: --> Real)
  ```
  
  Returns the sum of all the weights
  
  ```raku
  say mix('a', 'b', 'c', 'a', 'a', 'd').total == 6;  # OUTPUT: «True␤»
  say %(a => 5.6, b => 2.4).Mix.total == 8;          # OUTPUT: «True␤»
  ```
  
  ## [Note on order](#class_Mix "go to top of document")[§](#Note_on_order "direct link")
  
  Same as the other elements in the [Bag/Mix suite](/language/setbagmix), order is not guaranteed or consistent and you shouldn't rely on methods like `reverse` above returning always the same result.
  
  # [See Also](#class_Mix "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 `Mix`
  
  
  
  raku-type-graph
  
  
  
  Mix
  Mix
  
  
  Any
  Any
  
  
  Mix->Any
  
  
  
  Mixy
  Mixy
  
  
  Mix->Mixy
  
  
  
  Mu
  Mu
  
  
  Any->Mu
  
  
  
  Associative
  Associative
  
  
  QuantHash
  QuantHash
  
  
  QuantHash->Associative
  
  
  
  Baggy
  Baggy
  
  
  Baggy->QuantHash
  
  
  
  Mixy->Baggy
  
  [Expand chart above](/assets/typegraphs/Mix.svg)
  