txt: ## mixhash.md
  class MixHash
  
  Mutable collection of distinct objects with Real weights
  
  ```raku
  class MixHash does Mixy { }
  ```
  
  A `MixHash` is a mutable mix, meaning a collection of distinct elements in no particular order that each have a real-number weight assigned to them. (For *immutable* mixes, see [`Mix`](/type/Mix) instead.)
  
  Objects/values of any type are allowed as mix elements. Within a `MixHash`, 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).MixHash;
  
  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␤»
  
  ```
  
  `MixHash`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. It can also be used to modify weights; Setting a weight to `0` automatically removes that element from the mix, and setting a weight to a non-zero number adds that element if it didn't already exist:
  
  ```raku
  my $recipe = (butter => 0.22, sugar => 0.1,
                flour => 0.275, sugar => 0.02).MixHash;
  
  say $recipe<butter>;     # OUTPUT: «0.22␤»
  say $recipe<sugar>;      # OUTPUT: «0.12␤»
  say $recipe<chocolate>;  # OUTPUT: «0␤»
  
  $recipe<butter> = 0;
  $recipe<chocolate> = 0.30;
  say $recipe.pairs;       # OUTPUT: «"sugar" => 0.12 "flour" => 0.275 "chocolate" => 0.3␤»
  
  ```
  
  # [Creating `MixHash` objects](#class_MixHash "go to top of document")[§](#Creating_MixHash_objects "direct link")
  
  `MixHash`es can be composed using `MixHash.new`. 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 = MixHash.new: "a", "a", "b" => 0, "c" => 3.14;
  say $n.keys.map(&WHAT);  # OUTPUT: «((Str) (Pair) (Pair))␤»
  say $n.pairs;            # OUTPUT: «(a => 2 (c => 3.14) => 1 (b => 0) => 1)␤»
  ```
  
  Alternatively, the `.MixHash` coercer (or its functional form, `MixHash()`) can be called on an existing object to coerce it to a `MixHash`. 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).MixHash;
  say $n.keys.map(&WHAT);  # OUTPUT: «((Str) (Str))␤»
  say $n.pairs;            # OUTPUT: «(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 `MixHash`. This can either be done when calling `.new`:
  
  ```raku
  # only allow strings
  my $n = MixHash[Str].new: <a b b c c c>;
  ```
  
  or using the masquerading syntax:
  
  ```raku
  # only allow strings
  my %mh is MixHash[Str] = <a b b c c c>;
  say %mh<b>;  # OUTPUT: «2␤»
  say %mh<d>;  # OUTPUT: «0␤»
  
  # only allow whole numbers
  my %mh is MixHash[Int] = <a b b c c c>;
  # Type check failed in binding; expected Int but got Str ("a")
  ```
  
  # [Operators](#class_MixHash "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, `MixHash`.
  
  Examples:
  
  ```raku
  my ($a, $b) = MixHash(2 => 2, 4), MixHash(2 => 1.5, 3 => 2, 4);
  
  say $a (<) $b;   # OUTPUT: «False␤»
  say $a (<=) $b;  # OUTPUT: «False␤»
  say $a (^) $b;   # OUTPUT: «MixHash(2(0.5) 3(2))␤»
  say $a (+) $b;   # OUTPUT: «MixHash(2(3.5) 4(2) 3(2))␤»
  
  # Unicode versions:
  say $a ⊂ $b;  # OUTPUT: «False␤»
  say $a ⊆ $b;  # OUTPUT: «False␤»
  say $a ⊖ $b;  # OUTPUT: «MixHash(2(0.5) 3(2))␤»
  say $a ⊎ $b;  # OUTPUT: «MixHash(2(3.5) 4(2) 3(2))␤»
  
  ```
  
  # [Note on `reverse` and ordering.](#class_MixHash "go to top of document")[§](#Note_on_reverse_and_ordering. "direct link")
  
  MixHash inherits `reverse` 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.
  
  If you sort a MixHash, the result is a list of pairs, at which point `reverse` makes perfect sense:
  
  ```raku
  my $a = MixHash.new(2, 2, 18, 3, 4);
  say $a;  # OUTPUT: «MixHash(18 2(2) 3 4)␤»
  
  say $a.sort;  # OUTPUT: «(2 => 2 3 => 1 4 => 1 18 => 1)␤»
  say $a.sort.reverse;  # OUTPUT: «(18 => 1 4 => 1 3 => 1 2 => 2)␤»
  
  ```
  
  # [Methods](#class_MixHash "go to top of document")[§](#Methods "direct link")
  
  ## [method Bag](#class_MixHash "go to top of document")[§](#method_Bag "direct link")
  
  ```raku
  method Bag (--> Bag:D)
  ```
  
  Coerces the `MixHash` to a [`Bag`](/type/Bag). The weights are converted to [`Int`](/type/Int), which means the number of keys in the resulting [`Bag`](/type/Bag) can be fewer than in the original `MixHash`, if any of the weights are negative or truncate to zero.
  
  ## [method BagHash](#class_MixHash "go to top of document")[§](#method_BagHash "direct link")
  
  ```raku
  method BagHash (--> BagHash:D)
  ```
  
  Coerces the `MixHash` to a [`BagHash`](/type/BagHash). The weights are converted to [`Int`](/type/Int), which means the number of keys in the resulting [`BagHash`](/type/BagHash) can be fewer than in the original `MixHash`, if any of the weights are negative or truncate to zero.
  
  # [See Also](#class_MixHash "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 `MixHash`
  
  
  
  raku-type-graph
  
  
  
  MixHash
  MixHash
  
  
  Any
  Any
  
  
  MixHash->Any
  
  
  
  Mixy
  Mixy
  
  
  MixHash->Mixy
  
  
  
  Mu
  Mu
  
  
  Any->Mu
  
  
  
  Associative
  Associative
  
  
  QuantHash
  QuantHash
  
  
  QuantHash->Associative
  
  
  
  Baggy
  Baggy
  
  
  Baggy->QuantHash
  
  
  
  Mixy->Baggy
  
  [Expand chart above](/assets/typegraphs/MixHash.svg)
  