Set

Set k

Provides a set type which stores a collection of unique values, without any ordering

empty : {} -> Set *

Creates a new empty Set.

emptySet = Set.empty {}
countValues = Set.len emptySet

expect countValues == 0

withCapacity : U64 -> Set *

Return a set with space allocated for a number of entries. This may provide a performance optimization if you know how many entries will be inserted.

reserve : Set k, U64 -> Set k

Enlarge the set for at least capacity additional elements

releaseExcessCapacity : Set k -> Set k

Shrink the memory footprint of a set such that capacity is as small as possible. This function will require regenerating the metadata if the size changes. There will still be some overhead due to dictionary metadata always being a power of 2.

single : k -> Set k

Creates a new Set with a single value.

singleItemSet = Set.single "Apple"
countValues = Set.len singleItemSet

expect countValues == 1

insert : Set k, k -> Set k

Insert a value into a Set.

fewItemSet =
    Set.empty {}
    |> Set.insert "Apple"
    |> Set.insert "Pear"
    |> Set.insert "Banana"

countValues = Set.len fewItemSet

expect countValues == 3

len : Set * -> U64

Counts the number of values in a given Set.

fewItemSet =
    Set.empty {}
    |> Set.insert "Apple"
    |> Set.insert "Pear"
    |> Set.insert "Banana"

countValues = Set.len fewItemSet

expect countValues == 3

capacity : Set * -> U64

Returns the max number of elements the set can hold before requiring a rehash.

foodSet =
    Set.empty {}
    |> Set.insert "apple"

capacityOfSet = Set.capacity foodSet

isEmpty : Set * -> Bool

Check if the set is empty.

Set.isEmpty (Set.empty {} |> Set.insert 42)

Set.isEmpty (Set.empty {})

remove : Set k, k -> Set k

Removes the value from the given Set.

numbers =
    Set.empty {}
    |> Set.insert 10
    |> Set.insert 20
    |> Set.remove 10

has10 = Set.contains numbers 10
has20 = Set.contains numbers 20

expect has10 == Bool.false
expect has20 == Bool.true

contains : Set k, k -> Bool

Test if a value is in the Set.

Fruit : [Apple, Pear, Banana]

fruit : Set Fruit
fruit =
    Set.single Apple
    |> Set.insert Pear

hasApple = Set.contains fruit Apple
hasBanana = Set.contains fruit Banana

expect hasApple == Bool.true
expect hasBanana == Bool.false

toList : Set k -> List k

Retrieve the values in a Set as a List.

numbers : Set U64
numbers = Set.fromList [1,2,3,4,5]

values = [1,2,3,4,5]

expect Set.toList numbers == values

fromList : List k -> Set k

Create a Set from a List of values.

values =
    Set.empty {}
    |> Set.insert Banana
    |> Set.insert Apple
    |> Set.insert Pear

expect Set.fromList [Pear, Apple, Banana] == values

union : Set k, Set k -> Set k

Combine two Set collection by keeping the union of all the values pairs. This means that all of the values in both Sets will be combined.

set1 = Set.single Left
set2 = Set.single Right

expect Set.union set1 set2 == Set.fromList [Left, Right]

intersection : Set k, Set k -> Set k

Combine two Sets by keeping the intersection of all the values pairs. This means that we keep only those values that are in both Sets.

set1 = Set.fromList [Left, Other]
set2 = Set.fromList [Left, Right]

expect Set.intersection set1 set2 == Set.single Left

difference : Set k, Set k -> Set k

Remove the values in the first Set that are also in the second Set using the set difference of the values. This means that we will be left with only those values that are in the first and not in the second.

first = Set.fromList [Left, Right, Up, Down]
second = Set.fromList [Left, Right]

expect Set.difference first second == Set.fromList [Up, Down]

walk : Set k, state, (state, k -> state) -> state

Iterate through the values of a given Set and build a value.

values = Set.fromList ["March", "April", "May"]

startsWithLetterM = \month ->
    when Str.toUtf8 month is
        ['M', ..] -> Bool.true
        _ -> Bool.false

reduce = \state, k ->
    if startsWithLetterM k then
        state + 1
    else
        state

result = Set.walk values 0 reduce

expect result == 2

map : Set a, (a -> b) -> Set b

Convert each value in the set to something new, by calling a conversion function on each of them which receives the old value. Then return a new set containing the converted values.

joinMap : Set a, (a -> Set b) -> Set b

Like Set.map, except the transformation function wraps the return value in a set. At the end, all the sets get joined together (using Set.union) into one set.

You may know a similar function named concatMap in other languages.

walkUntil : Set k, state, (state, k -> [ Continue state, Break state ]) -> state

Iterate through the values of a given Set and build a value, can stop iterating part way through the collection.

numbers = Set.fromList [1,2,3,4,5,6,42,7,8,9,10]

find42 = \state, k ->
    if k == 42 then
        Break FoundTheAnswer
    else
        Continue state

result = Set.walkUntil numbers NotFound find42

expect result == FoundTheAnswer

keepIf : Set k, (k -> Bool) -> Set k

Run the given function on each element in the Set, and return a Set with just the elements for which the function returned Bool.true.

expect Set.fromList [1,2,3,4,5]
    |> Set.keepIf \k -> k >= 3
    |> Bool.isEq (Set.fromList [3,4,5])

dropIf : Set k, (k -> Bool) -> Set k

Run the given function on each element in the Set, and return a Set with just the elements for which the function returned Bool.false.

expect Set.fromList [1,2,3,4,5]
    |> Set.dropIf \k -> k >= 3
    |> Bool.isEq (Set.fromList [1,2])