elm-community / intdict / IntDict

IntDict

This module exposes the same API as Dict.

Technicalities

Since JavaScript's number type is kind of messed up, Elm's Int is not particularly well-behaved wrt. bitwise operations. Currently, JS supports 32 bit integers, so there is probably enough room for key picks. However, when sanitizing user input, it is mandatory that a prior isValidKey or one of the safe versions in IntDict.Safe is used! This is to prevent the overflow behavior.

This library is inspired by Haskells IntMap, which in turn implements Okasaki and Gill's Fast mergable integer maps.

As noted in the references, here are some runtimes:

O(min(n, W)): insert, update, remove, get, member

O(n + m): uniteWith, union, intersection, diff, merge

where n and m are the sizes of the first and second dictionary respectively and W is the number of bits in Int (so a constant with current value 32).

Dictionary equality with (==) is unreliable and should not be used.

Data


type IntDict v

A dictionary mapping Ints to values of a type v. Analogous to Dict Int v.

isValidKey : Basics.Int -> Basics.Bool

Validates that a given integer is usable as a key. This is necessary due to JavaScript's weird number type. Basically this assures that we can use the functions from Bitwise without risking integer overflow.

This function is a necessity for sanitizing user input! Alternatively, use the safe functions from IntDict.Safe which perform the check for you.

As with the current version of JavaScript (2015), only 32 bit signed integers are supported. If this ever changes, contact me! Certain parts of the implementation depend on this!

Build

empty : IntDict v

Create an empty dictionary.

singleton : Basics.Int -> v -> IntDict v

Create a dictionary with one key-value pair.

insert : Basics.Int -> v -> IntDict v -> IntDict v

Insert a key-value pair into a dictionary. Replaces value when there is a collision.

update : Basics.Int -> (Maybe v -> Maybe v) -> IntDict v -> IntDict v

Update the value of a dictionary for a specific key with a given function.

remove : Basics.Int -> IntDict v -> IntDict v

Remove a key-value pair from a dictionary. If the key is not found, no changes are made.

Query

isEmpty : IntDict v -> Basics.Bool

Check if the dictionary contains no items.

size : IntDict v -> Basics.Int

The number of items in the dictionary. O(1).

member : Basics.Int -> IntDict v -> Basics.Bool

Determine if a key is in a dictionary.

get : Basics.Int -> IntDict v -> Maybe v

Get the value associated with a key. If the key is not found, return Nothing. This is useful when you are not sure if a key will be in the dictionary.

before : Basics.Int -> IntDict v -> Maybe ( Basics.Int, v )

Find the key and value in the dictionary before the given key.

after : Basics.Int -> IntDict v -> Maybe ( Basics.Int, v )

Find the key and value in the dictionary after the given key.

findMin : IntDict v -> Maybe ( Basics.Int, v )

Find the minimum key and value in the dictionary.

findMax : IntDict v -> Maybe ( Basics.Int, v )

Find the maximum key and value in the dictionary.

Combine

uniteWith : (Basics.Int -> v -> v -> v) -> IntDict v -> IntDict v -> IntDict v

uniteWith merger l r combines two dictionaries. If there is a collision, merger is called with the conflicting key, the value from l and that from r.

union : IntDict v -> IntDict v -> IntDict v

Combine two dictionaries. If there is a collision, preference is given to the first dictionary.

intersect : IntDict a -> IntDict b -> IntDict a

Keep a key-value pair when its key appears in the second dictionary. Preference is given to values in the first dictionary.

diff : IntDict a -> IntDict b -> IntDict a

Keep a key-value pair when its key does not appear in the second dictionary.

merge : (Basics.Int -> a -> result -> result) -> (Basics.Int -> a -> b -> result -> result) -> (Basics.Int -> b -> result -> result) -> IntDict a -> IntDict b -> result -> result

The most general way of combining two dictionaries. You provide three accumulators for when a given key appears:

  1. Only in the left dictionary.
  2. In both dictionaries.
  3. Only in the right dictionary.

You then traverse all the keys from lowest to highest, building up whatever you want.

Note that uniteWith, union, intersect and diff could all be implemented in terms of this function. The only reason that's not the case is to have more sharing of substructure.

uniteWith merger l r =
    merge insert merger insert l r empty

union l r =
    merge insert (\k a _ d -> insert k a d) insert l r empty

intersect l r =
    merge (\_ _ d -> d) (\k a _ d -> insert k a d) (\_ _ d -> d) l r empty

diff l r =
    merge insert (\_ _ _ d -> d) (\_ _ d -> d) l r empty

Lists

keys : IntDict v -> List Basics.Int

Get all of the keys in a dictionary, sorted from lowest to highest.

values : IntDict v -> List v

Get all of the values in a dictionary, in the order of their keys.

toList : IntDict v -> List ( Basics.Int, v )

Convert a dictionary into an association list of key-value pairs, sorted by keys.

fromList : List ( Basics.Int, v ) -> IntDict v

Convert an association list into a dictionary.

Transform

map : (Basics.Int -> a -> b) -> IntDict a -> IntDict b

Apply a function to all values in a dictionary.

foldl : (Basics.Int -> v -> a -> a) -> a -> IntDict v -> a

Fold over the key-value pairs in a dictionary, in order from lowest key to highest key.

foldr : (Basics.Int -> v -> a -> a) -> a -> IntDict v -> a

Fold over the key-value pairs in a dictionary, in order from highest key to lowest key.

filter : (Basics.Int -> v -> Basics.Bool) -> IntDict v -> IntDict v

Keep a key-value pair when it satisfies a predicate.

partition : (Basics.Int -> v -> Basics.Bool) -> IntDict v -> ( IntDict v, IntDict v )

Partition a dictionary according to a predicate. The first dictionary contains all key-value pairs which satisfy the predicate, and the second contains the rest.

String representation

toString : IntDict v -> (v -> String) -> String

Generates a string representation similar to what toString generates for Dict. You must provide a function to convert your value type into a string.