Bag
A bag is also known as a multiset. It is a modificaiton of the concept of a set which allows for multiple instances of each element. Each item then also has a multiplicity, defined by the number of instances of that item in the multiset.
Bag a
empty : {} -> Bag *
Create an empty bag
single : a -> Bag a
Create a bag with a single instance of an item in it
repeat : a, Nat -> Bag a
Create a bag with multiple instances of an item in it
fromList : List k -> Bag k
Create a bag from a list.
expect bag = ["a", "a", "b"] |> Bag.fromList (bag |> Bag.count "a" == 2) && (bag |> Bag.count "b" == 1)
fromSet : Set k -> Bag k
Construct a bag from a set.
expect bag = Set.empty {} |> Set.insert "a" |> Set.insert "a" |> Set.insert "b" |> Bag.fromSet (bag |> Bag.count "a" == 1) && (bag |> Bag.count "b" == 1)
join : Bag k, Bag k -> Bag k
Join two bags together, adding the number of items in each bag.
union : Bag k, Bag k -> Bag k
Take the union of the two bags, defined by the biggest number of instances per item in both bags.
intersection : Bag k, Bag k -> Bag k
Take the intersection of the two bags, defined by the smallest number of instances per item in both bags. If an item is only present in one of the bags, the smallest number is zero and then it is not included in the resulting bag.
difference : Bag k, Bag k -> Bag k
Take the difference of the two bags, defined by removing the number of instances of the items in the second bag from the first bag.
size : Bag * -> Nat
Get the total number of items in the bag
isEmpty : Bag * -> Bool
Is the bag empty?
containsAny : Bag k, k -> Bool
Does the bag contain any of the item?
contains : Bag k, Nat, k -> Bool
Does the bag contain the given number, or more, of the item?
count : Bag k, k -> Nat
Get the number of instances (multiplicity) of the given item
includedIn : Bag k, Bag k -> Bool
Is the first bag included in the second bag? This is a modification of the concept of subset. Bag A is included in bag B if all the items in bag A have lower or equal multiplicity compared with the items in bag B.
insert : Bag a, Nat, a -> Bag a
Insert a number of instances of an item into a bag
remove : Bag k, Nat, k -> Bag k
Remove a number of instances of an item in the bag. If the same number or more of instances are removed than there are in the bag, remove all the items from the bag.
removeAll : Bag k, k -> Bag k
Remove all instances of an item from the bag.
toList : Bag k -> List k
Convert the bag to a list
expect empty {} |> insert 2 "a" |> insert 3 "b" |> toList == ["a", "a", "b", "b", "b"]
walk : Bag k, state, (state, k, Nat -> state) -> state
Walk the items of the bag and their multiplicities, threading state along the way.
scaleWith : Bag k, Nat -> Bag k
Rescale the multiplicities of the items with the given integer.
map : Bag a, (a -> b) -> Bag b
Map a function over the elements of the bag, combining the multiplicities of the new items appropriately.
joinMap : Bag a, (a -> Bag b) -> Bag b
Map a bag-creating function over the elements of the bag, joining all the resulting bags together. The resulting multiplicities in each bag are scaled with the original multiplicity of the item the bag is created from.
expect Bag.empty {} |> Bag.insert 2 "a" |> Bag.insert 3 "b" |> Bag.joinMap \s -> s |> Bag.repeat 3 == Bag.empty {} |> Bag.insert 6 "a" |> Bag.insert 9 "b"
keepIf : Bag a, ( ( a, Nat ) -> Bool) -> Bag a
Keep only items that fulfill the given predicative, which refers to both the item and its multiplicity.
dropIf : Bag a, ( ( a, Nat ) -> Bool) -> Bag a
Drop all items that fulfill the given predicative, which refers to both the item and its multiplicity.