rio-0.1.22.0: A standard library for Haskell

Safe Haskell | Safe-Inferred
Language | Haskell2010

RIO.HashMap

Contents

- Construction
- Basic interface
- Combine
  - Union
- Transformations
- Difference and intersection
- Folds
- Filter
- Conversions
  - Lists

Description

Strict `Map` with hashed keys. Import as:

    import qualified RIO.HashMap as HM

This module does not export any partial functions. For those, see RIO.HashMap.Partial

Synopsis

- data HashMap k v
- empty :: HashMap k v
- singleton :: Hashable k => k -> v -> HashMap k v
- null :: HashMap k v -> Bool
- size :: HashMap k v -> Int
- member :: (Eq k, Hashable k) => k -> HashMap k a -> Bool
- lookup :: (Eq k, Hashable k) => k -> HashMap k v -> Maybe v
- lookupDefault :: (Eq k, Hashable k) => v -> k -> HashMap k v -> v
- insert :: (Eq k, Hashable k) => k -> v -> HashMap k v -> HashMap k v
- insertWith :: (Eq k, Hashable k) => (v -> v -> v) -> k -> v -> HashMap k v -> HashMap k v
- delete :: (Eq k, Hashable k) => k -> HashMap k v -> HashMap k v
- adjust :: (Eq k, Hashable k) => (v -> v) -> k -> HashMap k v -> HashMap k v
- update :: (Eq k, Hashable k) => (a -> Maybe a) -> k -> HashMap k a -> HashMap k a
- alter :: (Eq k, Hashable k) => (Maybe v -> Maybe v) -> k -> HashMap k v -> HashMap k v
- union :: (Eq k, Hashable k) => HashMap k v -> HashMap k v -> HashMap k v
- unionWith :: (Eq k, Hashable k) => (v -> v -> v) -> HashMap k v -> HashMap k v -> HashMap k v
- unionWithKey :: (Eq k, Hashable k) => (k -> v -> v -> v) -> HashMap k v -> HashMap k v -> HashMap k v
- unions :: (Eq k, Hashable k) => [HashMap k v] -> HashMap k v
- map :: (v1 -> v2) -> HashMap k v1 -> HashMap k v2
- mapWithKey :: (k -> v1 -> v2) -> HashMap k v1 -> HashMap k v2
- traverseWithKey :: Applicative f => (k -> v1 -> f v2) -> HashMap k v1 -> f (HashMap k v2)
- difference :: (Eq k, Hashable k) => HashMap k v -> HashMap k w -> HashMap k v
- differenceWith :: (Eq k, Hashable k) => (v -> w -> Maybe v) -> HashMap k v -> HashMap k w -> HashMap k v
- intersection :: (Eq k, Hashable k) => HashMap k v -> HashMap k w -> HashMap k v
- intersectionWith :: (Eq k, Hashable k) => (v1 -> v2 -> v3) -> HashMap k v1 -> HashMap k v2 -> HashMap k v3
- intersectionWithKey :: (Eq k, Hashable k) => (k -> v1 -> v2 -> v3) -> HashMap k v1 -> HashMap k v2 -> HashMap k v3
- foldl' :: (a -> v -> a) -> a -> HashMap k v -> a
- foldlWithKey' :: (a -> k -> v -> a) -> a -> HashMap k v -> a
- foldr :: (v -> a -> a) -> a -> HashMap k v -> a
- foldrWithKey :: (k -> v -> a -> a) -> a -> HashMap k v -> a
- filter :: (v -> Bool) -> HashMap k v -> HashMap k v
- filterWithKey :: (k -> v -> Bool) -> HashMap k v -> HashMap k v
- mapMaybe :: (v1 -> Maybe v2) -> HashMap k v1 -> HashMap k v2
- mapMaybeWithKey :: (k -> v1 -> Maybe v2) -> HashMap k v1 -> HashMap k v2
- keys :: HashMap k v -> [k]
- elems :: HashMap k v -> [v]
- toList :: HashMap k v -> [(k, v)]
- fromList :: (Eq k, Hashable k) => [(k, v)] -> HashMap k v
- fromListWith :: (Eq k, Hashable k) => (v -> v -> v) -> [(k, v)] -> HashMap k v

# Documentation

data HashMap k v #

A map from keys to values. A map cannot contain duplicate keys; each key can map to at most one value.

#### Instances

Instances details

Bifoldable HashMap | Since: unordered-containers-0.2.11
Instance details Defined in Data.HashMap.Internal Methods bifold :: Monoid m => HashMap m m -> m # bifoldMap :: Monoid m => (a -> m) -> (b -> m) -> HashMap a b -> m # bifoldr :: (a -> c -> c) -> (b -> c -> c) -> c -> HashMap a b -> c # bifoldl :: (c -> a -> c) -> (c -> b -> c) -> c -> HashMap a b -> c #
Eq2 HashMap |
Instance details Defined in Data.HashMap.Internal Methods liftEq2 :: (a -> b -> Bool) -> (c -> d -> Bool) -> HashMap a c -> HashMap b d -> Bool
Ord2 HashMap |
Instance details Defined in Data.HashMap.Internal Methods liftCompare2 :: (a -> b -> Ordering) -> (c -> d -> Ordering) -> HashMap a c -> HashMap b d -> Ordering
Show2 HashMap |
Instance details Defined in Data.HashMap.Internal Methods liftShowsPrec2 :: (Int -> a -> ShowS) -> ([a] -> ShowS) -> (Int -> b -> ShowS) -> ([b] -> ShowS) -> Int -> HashMap a b -> ShowS liftShowList2 :: (Int -> a -> ShowS) -> ([a] -> ShowS) -> (Int -> b -> ShowS) -> ([b] -> ShowS) -> [HashMap a b] -> ShowS
NFData2 HashMap | Since: unordered-containers-0.2.14.0
Instance details Defined in Data.HashMap.Internal Methods liftRnf2 :: (a -> ()) -> (b -> ()) -> HashMap a b -> ()
Hashable2 HashMap |
Instance details Defined in Data.HashMap.Internal Methods liftHashWithSalt2 :: (Int -> a -> Int) -> (Int -> b -> Int) -> Int -> HashMap a b -> Int #
(Lift k, Lift v) => Lift (HashMap k v :: Type) | Since: unordered-containers-0.2.17.0
Instance details Defined in Data.HashMap.Internal Methods lift :: Quote m => HashMap k v -> m Exp liftTyped :: forall (m :: Type -> Type). Quote m => HashMap k v -> Code m (HashMap k v)
Foldable (HashMap k) |

Instance details

Defined in Data.HashMap.Internal

Methods

fold :: Monoid m => HashMap k m -> m #

foldMap :: Monoid m => (a -> m) -> HashMap k a -> m #

foldMap' :: Monoid m => (a -> m) -> HashMap k a -> m

foldr :: (a -> b -> b) -> b -> HashMap k a -> b #

foldr' :: (a -> b -> b) -> b -> HashMap k a -> b

foldl :: (b -> a -> b) -> b -> HashMap k a -> b #

foldl' :: (b -> a -> b) -> b -> HashMap k a -> b #

foldr1 :: (a -> a -> a) -> HashMap k a -> a #

foldl1 :: (a -> a -> a) -> HashMap k a -> a #

toList :: HashMap k a -> [a] #

null :: HashMap k a -> Bool #

length :: HashMap k a -> Int #

elem :: Eq a => a -> HashMap k a -> Bool #

maximum :: Ord a => HashMap k a -> a #

minimum :: Ord a => HashMap k a -> a #

sum :: Num a => HashMap k a -> a #

product :: Num a => HashMap k a -> a #

Eq k => Eq1 (HashMap k) |
Instance details Defined in Data.HashMap.Internal Methods liftEq :: (a -> b -> Bool) -> HashMap k a -> HashMap k b -> Bool
Ord k => Ord1 (HashMap k) |
Instance details Defined in Data.HashMap.Internal Methods liftCompare :: (a -> b -> Ordering) -> HashMap k a -> HashMap k b -> Ordering
(Eq k, Hashable k, Read k) => Read1 (HashMap k) |
Instance details Defined in Data.HashMap.Internal Methods liftReadsPrec :: (Int -> ReadS a) -> ReadS [a] -> Int -> ReadS (HashMap k a) liftReadList :: (Int -> ReadS a) -> ReadS [a] -> ReadS [HashMap k a] liftReadPrec :: ReadPrec a -> ReadPrec [a] -> ReadPrec (HashMap k a) liftReadListPrec :: ReadPrec a -> ReadPrec [a] -> ReadPrec [HashMap k a]
Show k => Show1 (HashMap k) |
Instance details Defined in Data.HashMap.Internal Methods liftShowsPrec :: (Int -> a -> ShowS) -> ([a] -> ShowS) -> Int -> HashMap k a -> ShowS liftShowList :: (Int -> a -> ShowS) -> ([a] -> ShowS) -> [HashMap k a] -> ShowS
Traversable (HashMap k) |
Instance details Defined in Data.HashMap.Internal Methods traverse :: Applicative f => (a -> f b) -> HashMap k a -> f (HashMap k b) # sequenceA :: Applicative f => HashMap k (f a) -> f (HashMap k a) # mapM :: Monad m => (a -> m b) -> HashMap k a -> m (HashMap k b) # sequence :: Monad m => HashMap k (m a) -> m (HashMap k a) #
Functor (HashMap k) |
Instance details Defined in Data.HashMap.Internal Methods fmap :: (a -> b) -> HashMap k a -> HashMap k b # (<$) :: a -> HashMap k b -> HashMap k a #
NFData k => NFData1 (HashMap k) | Since: unordered-containers-0.2.14.0
Instance details Defined in Data.HashMap.Internal Methods liftRnf :: (a -> ()) -> HashMap k a -> ()
Hashable k => Hashable1 (HashMap k) |
Instance details Defined in Data.HashMap.Internal Methods liftHashWithSalt :: (Int -> a -> Int) -> Int -> HashMap k a -> Int #
(Data k, Data v, Eq k, Hashable k) => Data (HashMap k v) |

Instance details

Defined in Data.HashMap.Internal

Methods

gfoldl :: (forall d b. Data d => c (d -> b) -> d -> c b) -> (forall g. g -> c g) -> HashMap k v -> c (HashMap k v) #

gunfold :: (forall b r. Data b => c (b -> r) -> c r) -> (forall r. r -> c r) -> Constr -> c (HashMap k v) #

toConstr :: HashMap k v -> Constr #

dataTypeOf :: HashMap k v -> DataType #

dataCast1 :: Typeable t => (forall d. Data d => c (t d)) -> Maybe (c (HashMap k v)) #

dataCast2 :: Typeable t => (forall d e. (Data d, Data e) => c (t d e)) -> Maybe (c (HashMap k v)) #

gmapT :: (forall b. Data b => b -> b) -> HashMap k v -> HashMap k v #

gmapQl :: (r -> r' -> r) -> r -> (forall d. Data d => d -> r') -> HashMap k v -> r #

gmapQr :: forall r r'. (r' -> r -> r) -> r -> (forall d. Data d => d -> r') -> HashMap k v -> r #

gmapQ :: (forall d. Data d => d -> u) -> HashMap k v -> [u] #

gmapQi :: Int -> (forall d. Data d => d -> u) -> HashMap k v -> u #

gmapM :: Monad m => (forall d. Data d => d -> m d) -> HashMap k v -> m (HashMap k v) #

gmapMp :: MonadPlus m => (forall d. Data d => d -> m d) -> HashMap k v -> m (HashMap k v) #

gmapMo :: MonadPlus m => (forall d. Data d => d -> m d) -> HashMap k v -> m (HashMap k v) #

(Eq k, Hashable k) => Monoid (HashMap k v)

`mempty` = `empty`

`mappend` = `union`

If a key occurs in both maps, the mapping from the first will be the mapping in the result.

#### Examples

Expand

    >>> mappend (fromList [(1,'a'),(2,'b')]) (fromList [(2,'c'),(3,'d')])
    fromList [(1,'a'),(2,'b'),(3,'d')]

Instance details Defined in Data.HashMap.Internal Methods mempty :: HashMap k v # mappend :: HashMap k v -> HashMap k v -> HashMap k v # mconcat :: [HashMap k v] -> HashMap k v #

(Eq k, Hashable k) => Semigroup (HashMap k v)

`<>` = `union`

If a key occurs in both maps, the mapping from the first will be the mapping in the result.

#### Examples

Expand

    >>> fromList [(1,'a'),(2,'b')] <> fromList [(2,'c'),(3,'d')]
    fromList [(1,'a'),(2,'b'),(3,'d')]

Instance details Defined in Data.HashMap.Internal Methods (<>) :: HashMap k v -> HashMap k v -> HashMap k v # sconcat :: NonEmpty (HashMap k v) -> HashMap k v stimes :: Integral b => b -> HashMap k v -> HashMap k v
(Eq k, Hashable k) => IsList (HashMap k v) |
Instance details Defined in Data.HashMap.Internal Associated Types type Item (HashMap k v) Methods fromList :: [Item (HashMap k v)] -> HashMap k v fromListN :: Int -> [Item (HashMap k v)] -> HashMap k v toList :: HashMap k v -> [Item (HashMap k v)]
(Eq k, Hashable k, Read k, Read e) => Read (HashMap k e) |
Instance details Defined in Data.HashMap.Internal Methods readsPrec :: Int -> ReadS (HashMap k e) readList :: ReadS [HashMap k e] readPrec :: ReadPrec (HashMap k e) readListPrec :: ReadPrec [HashMap k e]
(Show k, Show v) => Show (HashMap k v) |
Instance details Defined in Data.HashMap.Internal Methods showsPrec :: Int -> HashMap k v -> ShowS show :: HashMap k v -> String # showList :: [HashMap k v] -> ShowS
(NFData k, NFData v) => NFData (HashMap k v) |
Instance details Defined in Data.HashMap.Internal Methods rnf :: HashMap k v -> () #

(Eq k, Eq v) => Eq (HashMap k v)

Note that, in the presence of hash collisions, equal `HashMap`s may behave differently, i.e. substitutivity may be violated:

    >>> data D = A | B deriving (Eq, Show)
    >>> instance Hashable D where hashWithSalt salt _d = salt

    >>> x = fromList [(A,1), (B,2)]
    >>> y = fromList [(B,2), (A,1)]

    >>> x == y
    True
    >>> toList x
    [(A,1),(B,2)]
    >>> toList y
    [(B,2),(A,1)]

In general, the lack of substitutivity can be observed with any function that depends on the key ordering, such as folds and traversals.

Instance details Defined in Data.HashMap.Internal Methods (==) :: HashMap k v -> HashMap k v -> Bool # (/=) :: HashMap k v -> HashMap k v -> Bool #
(Ord k, Ord v) => Ord (HashMap k v) | The ordering is total and consistent with the `Eq` instance. However, nothing else about the ordering is specified, and it may change from version to version of either this package or of hashable.
Instance details Defined in Data.HashMap.Internal Methods compare :: HashMap k v -> HashMap k v -> Ordering # (<) :: HashMap k v -> HashMap k v -> Bool # (<=) :: HashMap k v -> HashMap k v -> Bool # (>) :: HashMap k v -> HashMap k v -> Bool # (>=) :: HashMap k v -> HashMap k v -> Bool # max :: HashMap k v -> HashMap k v -> HashMap k v # min :: HashMap k v -> HashMap k v -> HashMap k v #
(Hashable k, Hashable v) => Hashable (HashMap k v) |
Instance details Defined in Data.HashMap.Internal Methods hashWithSalt :: Int -> HashMap k v -> Int # hash :: HashMap k v -> Int #
type Item (HashMap k v) |
Instance details Defined in Data.HashMap.Internal type Item (HashMap k v) = (k, v)

# Construction

empty :: HashMap k v #

\(O(1)\) Construct an empty map.

singleton :: Hashable k => k -> v -> HashMap k v #

\(O(1)\) Construct a map with a single element.

# Basic interface

null :: HashMap k v -> Bool #

\(O(1)\) Return `True` if this map is empty, `False` otherwise.

size :: HashMap k v -> Int #

\(O(n)\) Return the number of key-value mappings in this map.

member :: (Eq k, Hashable k) => k -> HashMap k a -> Bool #

\(O(\log n)\) Return `True` if the specified key is present in the map, `False` otherwise.

lookup :: (Eq k, Hashable k) => k -> HashMap k v -> Maybe v #

\(O(\log n)\) Return the value to which the specified key is mapped, or `Nothing` if this map contains no mapping for the key.

lookupDefault #

Arguments

:: (Eq k, Hashable k) |
=> v | Default value to return.
-> k |
-> HashMap k v |
-> v |

\(O(\log n)\) Return the value to which the specified key is mapped, or the default value if this map contains no mapping for the key.

DEPRECATED: lookupDefault is deprecated as of version 0.2.11, replaced by `findWithDefault`.

insert :: (Eq k, Hashable k) => k -> v -> HashMap k v -> HashMap k v #

\(O(\log n)\) Associate the specified value with the specified key in this map. If this map previously contained a mapping for the key, the old value is replaced.

insertWith :: (Eq k, Hashable k) => (v -> v -> v) -> k -> v -> HashMap k v -> HashMap k v #

\(O(\log n)\) Associate the value with the key in this map. If this map previously contained a mapping for the key, the old value is replaced by the result of applying the given function to the new and old value. Example:

    insertWith f k v map
      where f new old = new + old

delete :: (Eq k, Hashable k) => k -> HashMap k v -> HashMap k v #

\(O(\log n)\) Remove the mapping for the specified key from this map if present.

adjust :: (Eq k, Hashable k) => (v -> v) -> k -> HashMap k v -> HashMap k v #

\(O(\log n)\) Adjust the value tied to a given key in this map only if it is present. Otherwise, leave the map alone.

update :: (Eq k, Hashable k) => (a -> Maybe a) -> k -> HashMap k a -> HashMap k a #

\(O(\log n)\) The expression `(`update` f k map)` updates the value `x` at `k` (if it is in the map). If `(f x)` is `Nothing`, the element is deleted. If it is `(`Just` y)`, the key `k` is bound to the new value `y`.

alter :: (Eq k, Hashable k) => (Maybe v -> Maybe v) -> k -> HashMap k v -> HashMap k v #

\(O(\log n)\) The expression `(`alter` f k map)` alters the value `x` at `k`, or absence thereof.

`alter` can be used to insert, delete, or update a value in a map. In short:

    lookup k (alter f k m) = f (lookup k m)

# Combine

## Union

union :: (Eq k, Hashable k) => HashMap k v -> HashMap k v -> HashMap k v #

\(O(n+m)\) The union of two maps. If a key occurs in both maps, the mapping from the first will be the mapping in the result.

#### Examples

Expand

    >>> union (fromList [(1,'a'),(2,'b')]) (fromList [(2,'c'),(3,'d')])
    fromList [(1,'a'),(2,'b'),(3,'d')]

unionWith :: (Eq k, Hashable k) => (v -> v -> v) -> HashMap k v -> HashMap k v -> HashMap k v #

\(O(n+m)\) The union of two maps. If a key occurs in both maps, the provided function (first argument) will be used to compute the result.

unionWithKey :: (Eq k, Hashable k) => (k -> v -> v -> v) -> HashMap k v -> HashMap k v -> HashMap k v #

\(O(n+m)\) The union of two maps. If a key occurs in both maps, the provided function (first argument) will be used to compute the result.

unions :: (Eq k, Hashable k) => [HashMap k v] -> HashMap k v #

Construct a set containing all elements from a list of sets.

# Transformations

map :: (v1 -> v2) -> HashMap k v1 -> HashMap k v2 #

\(O(n)\) Transform this map by applying a function to every value.

mapWithKey :: (k -> v1 -> v2) -> HashMap k v1 -> HashMap k v2 #

\(O(n)\) Transform this map by applying a function to every value.

traverseWithKey :: Applicative f => (k -> v1 -> f v2) -> HashMap k v1 -> f (HashMap k v2) #

\(O(n)\) Perform an `Applicative` action for each key-value pair in a `HashMap` and produce a `HashMap` of all the results. Each `HashMap` will be strict in all its values.

    traverseWithKey f = fmap (map id) . Data.HashMap.Lazy.traverseWithKey f

Note: the order in which the actions occur is unspecified. In particular, when the map contains hash collisions, the order in which the actions associated with the keys involved will depend in an unspecified way on their insertion order.

# Difference and intersection

difference :: (Eq k, Hashable k) => HashMap k v -> HashMap k w -> HashMap k v #

\(O(n \log m)\) Difference of two maps. Return elements of the first map not existing in the second.

differenceWith :: (Eq k, Hashable k) => (v -> w -> Maybe v) -> HashMap k v -> HashMap k w -> HashMap k v #

\(O(n \log m)\) Difference with a combining function. When two equal keys are encountered, the combining function is applied to the values of these keys. If it returns `Nothing`, the element is discarded (proper set difference). If it returns (``Just` y`), the element is updated with a new value `y`.

intersection :: (Eq k, Hashable k) => HashMap k v -> HashMap k w -> HashMap k v #

\(O(n \log m)\) Intersection of two maps. Return elements of the first map for keys existing in the second.

intersectionWith :: (Eq k, Hashable k) => (v1 -> v2 -> v3) -> HashMap k v1 -> HashMap k v2 -> HashMap k v3 #

\(O(n+m)\) Intersection of two maps. If a key occurs in both maps the provided function is used to combine the values from the two maps.

intersectionWithKey :: (Eq k, Hashable k) => (k -> v1 -> v2 -> v3) -> HashMap k v1 -> HashMap k v2 -> HashMap k v3 #

\(O(n+m)\) Intersection of two maps. If a key occurs in both maps the provided function is used to combine the values from the two maps.

# Folds

foldl' :: (a -> v -> a) -> a -> HashMap k v -> a #

\(O(n)\) Reduce this map by applying a binary operator to all elements, using the given starting value (typically the left-identity of the operator). Each application of the operator is evaluated before using the result in the next application. This function is strict in the starting value.

foldlWithKey' :: (a -> k -> v -> a) -> a -> HashMap k v -> a #

\(O(n)\) Reduce this map by applying a binary operator to all elements, using the given starting value (typically the left-identity of the operator). Each application of the operator is evaluated before using the result in the next application. This function is strict in the starting value.

foldr :: (v -> a -> a) -> a -> HashMap k v -> a #

\(O(n)\) Reduce this map by applying a binary operator to all elements, using the given starting value (typically the right-identity of the operator).

foldrWithKey :: (k -> v -> a -> a) -> a -> HashMap k v -> a #

\(O(n)\) Reduce this map by applying a binary operator to all elements, using the given starting value (typically the right-identity of the operator).

# Filter

filter :: (v -> Bool) -> HashMap k v -> HashMap k v #

\(O(n)\) Filter this map by retaining only elements which values satisfy a predicate.

filterWithKey :: (k -> v -> Bool) -> HashMap k v -> HashMap k v #

\(O(n)\) Filter this map by retaining only elements satisfying a predicate.

mapMaybe :: (v1 -> Maybe v2) -> HashMap k v1 -> HashMap k v2 #

\(O(n)\) Transform this map by applying a function to every value and retaining only some of them.

mapMaybeWithKey :: (k -> v1 -> Maybe v2) -> HashMap k v1 -> HashMap k v2 #

\(O(n)\) Transform this map by applying a function to every value and retaining only some of them.

# Conversions

keys :: HashMap k v -> [k] #

\(O(n)\) Return a list of this map's keys. The list is produced lazily.

elems :: HashMap k v -> [v] #

\(O(n)\) Return a list of this map's values. The list is produced lazily.

## Lists

toList :: HashMap k v -> [(k, v)] #

\(O(n)\) Return a list of this map's elements. The list is produced lazily. The order of its elements is unspecified.

fromList :: (Eq k, Hashable k) => [(k, v)] -> HashMap k v #

\(O(n \log n)\) Construct a map with the supplied mappings. If the list contains duplicate mappings, the later mappings take precedence.

fromListWith :: (Eq k, Hashable k) => (v -> v -> v) -> [(k, v)] -> HashMap k v #

\(O(n \log n)\) Construct a map from a list of elements. Uses the provided function `f` to merge duplicate entries with `(f newVal oldVal)`.

### Examples

Given a list `xs`, create a map with the number of occurrences of each element in `xs`:

    let xs = ['a', 'b', 'a']
    in fromListWith (+) [ (x, 1) | x <- xs ]

    = fromList [('a', 2), ('b', 1)]

Given a list of key-value pairs `xs :: [(k, v)]`, group all values by their keys and return a `HashMap k [v]`.

    let xs = ('a', 1), ('b', 2), ('a', 3)]
    in fromListWith (++) [ (k, [v]) | (k, v) <- xs ]

    = fromList [('a', [3, 1]), ('b', [2])]

Note that the lists in the resulting map contain elements in reverse order from their occurences in the original list.

More generally, duplicate entries are accumulated as follows; this matters when `f` is not commutative or not associative.

    fromListWith f [(k, a), (k, b), (k, c), (k, d)]
    = fromList [(k, f d (f c (f b a)))]