    {-# LANGUAGE FlexibleInstances #-}
    {-# LANGUAGE ConstraintKinds #-}
    {-# LANGUAGE FlexibleContexts #-}
    {-# LANGUAGE TypeFamilies #-}
    {-# LANGUAGE MultiParamTypeClasses #-}
    {-# LANGUAGE CPP #-}
    {-# LANGUAGE TypeOperators #-}
    module Data.Containers where

    import Prelude hiding (lookup)
    import Data.Maybe (fromMaybe)
    import qualified Data.Map.Strict as Map
    import qualified Data.IntMap.Strict as IntMap
    import qualified Data.HashMap.Strict as HashMap
    import Data.Hashable (Hashable)
    import qualified Data.Set as Set
    import qualified Data.HashSet as HashSet
    import Data.Monoid (Monoid (..))
    import Data.MonoTraversable (MonoFunctor(..), MonoFoldable, MonoTraversable, Element, GrowingAppend, ofoldl', otoList)
    import Data.Function (on)
    import qualified Data.List as List
    import qualified Data.IntSet as IntSet

    import qualified Data.Text.Lazy as LText
    import qualified Data.Text as Text
    import qualified Data.ByteString.Lazy as LByteString
    import qualified Data.ByteString as ByteString
    import Control.Arrow ((***))
    import GHC.Exts (Constraint)

    -- | A container whose values are stored in Key-Value pairs.
    class (Data.Monoid.Monoid set, Semigroup set, MonoFoldable set, Eq (ContainerKey set), GrowingAppend set) => SetContainer set where
        -- | The type of the key
        type ContainerKey set

        -- | Check if there is a value with the supplied key
        -- in the container.
        member :: ContainerKey set -> set -> Bool

        -- | Check if there isn't a value with the supplied key
        -- in the container.
        notMember ::  ContainerKey set -> set -> Bool

        -- | Get the union of two containers.
        union :: set -> set -> set

        -- | Combine a collection of @SetContainer@s, with left-most values overriding
        -- when there are matching keys.
        --
        -- @since 1.0.0
        unions :: (MonoFoldable mono, Element mono ~ set) => mono -> set
        unions = (set -> Element mono -> set) -> set -> mono -> set
    forall mono a.
    MonoFoldable mono =>
    (a -> Element mono -> a) -> a -> mono -> a
    forall a. (a -> Element mono -> a) -> a -> mono -> a
    ofoldl' set -> set -> set
    set -> Element mono -> set
    forall set. SetContainer set => set -> set -> set
    union set
    forall a. Monoid a => a
    Data.Monoid.mempty
        {-# INLINE unions #-}

        -- | Get the difference of two containers.
        difference :: set -> set -> set

        -- | Get the intersection of two containers.
        intersection :: set -> set -> set

        -- | Get a list of all of the keys in the container.
        keys :: set -> [ContainerKey set]

    -- | This instance uses the functions from "Data.Map.Strict".
    instance Ord k => SetContainer (Map.Map k v) where
        type ContainerKey (Map.Map k v) = k
        member :: ContainerKey (Map k v) -> Map k v -> Bool
    member = k -> Map k v -> Bool
    ContainerKey (Map k v) -> Map k v -> Bool
    forall k a. Ord k => k -> Map k a -> Bool
    Map.member
        {-# INLINE member #-}
        notMember :: ContainerKey (Map k v) -> Map k v -> Bool
    notMember = k -> Map k v -> Bool
    ContainerKey (Map k v) -> Map k v -> Bool
    forall k a. Ord k => k -> Map k a -> Bool
    Map.notMember
        {-# INLINE notMember #-}
        union :: Map k v -> Map k v -> Map k v
    union = Map k v -> Map k v -> Map k v
    forall k v. Ord k => Map k v -> Map k v -> Map k v
    Map.union
        {-# INLINE union #-}
        unions :: forall mono.
    (MonoFoldable mono, Element mono ~ Map k v) =>
    mono -> Map k v
    unions = [Map k v] -> Map k v
    forall (f :: * -> *) k a.
    (Foldable f, Ord k) =>
    f (Map k a) -> Map k a
    Map.unions ([Map k v] -> Map k v) -> (mono -> [Map k v]) -> mono -> Map k v
    forall b c a. (b -> c) -> (a -> b) -> a -> c
    . mono -> [Map k v]
    mono -> [Element mono]
    forall mono. MonoFoldable mono => mono -> [Element mono]
    otoList
        {-# INLINE unions #-}
        difference :: Map k v -> Map k v -> Map k v
    difference = Map k v -> Map k v -> Map k v
    forall k a b. Ord k => Map k a -> Map k b -> Map k a
    Map.difference
        {-# INLINE difference #-}
        intersection :: Map k v -> Map k v -> Map k v
    intersection = Map k v -> Map k v -> Map k v
    forall k a b. Ord k => Map k a -> Map k b -> Map k a
    Map.intersection
        {-# INLINE intersection #-}
        keys :: Map k v -> [ContainerKey (Map k v)]
    keys = Map k v -> [k]
    Map k v -> [ContainerKey (Map k v)]
    forall k a. Map k a -> [k]
    Map.keys
        {-# INLINE keys #-}

    -- | This instance uses the functions from "Data.HashMap.Strict".
    instance (Eq key, Hashable key) => SetContainer (HashMap.HashMap key value) where
        type ContainerKey (HashMap.HashMap key value) = key
        member :: ContainerKey (HashMap key value) -> HashMap key value -> Bool
    member = key -> HashMap key value -> Bool
    ContainerKey (HashMap key value) -> HashMap key value -> Bool
    forall k a. (Eq k, Hashable k) => k -> HashMap k a -> Bool
    HashMap.member
        {-# INLINE member #-}
        notMember :: ContainerKey (HashMap key value) -> HashMap key value -> Bool
    notMember ContainerKey (HashMap key value)
    k = Bool -> Bool
    not (Bool -> Bool)
    -> (HashMap key value -> Bool) -> HashMap key value -> Bool
    forall b c a. (b -> c) -> (a -> b) -> a -> c
    . key -> HashMap key value -> Bool
    forall k a. (Eq k, Hashable k) => k -> HashMap k a -> Bool
    HashMap.member key
    ContainerKey (HashMap key value)
    k
        {-# INLINE notMember #-}
        union :: HashMap key value -> HashMap key value -> HashMap key value
    union = HashMap key value -> HashMap key value -> HashMap key value
    forall k v. Eq k => HashMap k v -> HashMap k v -> HashMap k v
    HashMap.union
        {-# INLINE union #-}
        unions :: forall mono.
    (MonoFoldable mono, Element mono ~ HashMap key value) =>
    mono -> HashMap key value
    unions = [HashMap key value] -> HashMap key value
    forall k v. Eq k => [HashMap k v] -> HashMap k v
    HashMap.unions ([HashMap key value] -> HashMap key value)
    -> (mono -> [HashMap key value]) -> mono -> HashMap key value
    forall b c a. (b -> c) -> (a -> b) -> a -> c
    . mono -> [HashMap key value]
    mono -> [Element mono]
    forall mono. MonoFoldable mono => mono -> [Element mono]
    otoList
        {-# INLINE unions #-}
        difference :: HashMap key value -> HashMap key value -> HashMap key value
    difference = HashMap key value -> HashMap key value -> HashMap key value
    forall k v w.
    (Eq k, Hashable k) =>
    HashMap k v -> HashMap k w -> HashMap k v
    HashMap.difference
        {-# INLINE difference #-}
        intersection :: HashMap key value -> HashMap key value -> HashMap key value
    intersection = HashMap key value -> HashMap key value -> HashMap key value
    forall k v w. Eq k => HashMap k v -> HashMap k w -> HashMap k v
    HashMap.intersection
        {-# INLINE intersection #-}
        keys :: HashMap key value -> [ContainerKey (HashMap key value)]
    keys = HashMap key value -> [key]
    HashMap key value -> [ContainerKey (HashMap key value)]
    forall k v. HashMap k v -> [k]
    HashMap.keys
        {-# INLINE keys #-}

    -- | This instance uses the functions from "Data.IntMap.Strict".
    instance SetContainer (IntMap.IntMap value) where
        type ContainerKey (IntMap.IntMap value) = Int
        member :: ContainerKey (IntMap value) -> IntMap value -> Bool
    member = Int -> IntMap value -> Bool
    ContainerKey (IntMap value) -> IntMap value -> Bool
    forall a. Int -> IntMap a -> Bool
    IntMap.member
        {-# INLINE member #-}
        notMember :: ContainerKey (IntMap value) -> IntMap value -> Bool
    notMember = Int -> IntMap value -> Bool
    ContainerKey (IntMap value) -> IntMap value -> Bool
    forall a. Int -> IntMap a -> Bool
    IntMap.notMember
        {-# INLINE notMember #-}
        union :: IntMap value -> IntMap value -> IntMap value
    union = IntMap value -> IntMap value -> IntMap value
    forall value. IntMap value -> IntMap value -> IntMap value
    IntMap.union
        {-# INLINE union #-}
        unions :: forall mono.
    (MonoFoldable mono, Element mono ~ IntMap value) =>
    mono -> IntMap value
    unions = [IntMap value] -> IntMap value
    forall (f :: * -> *) a. Foldable f => f (IntMap a) -> IntMap a
    IntMap.unions ([IntMap value] -> IntMap value)
    -> (mono -> [IntMap value]) -> mono -> IntMap value
    forall b c a. (b -> c) -> (a -> b) -> a -> c
    . mono -> [IntMap value]
    mono -> [Element mono]
    forall mono. MonoFoldable mono => mono -> [Element mono]
    otoList
        {-# INLINE unions #-}
        difference :: IntMap value -> IntMap value -> IntMap value
    difference = IntMap value -> IntMap value -> IntMap value
    forall a b. IntMap a -> IntMap b -> IntMap a
    IntMap.difference
        {-# INLINE difference #-}
        intersection :: IntMap value -> IntMap value -> IntMap value
    intersection = IntMap value -> IntMap value -> IntMap value
    forall a b. IntMap a -> IntMap b -> IntMap a
    IntMap.intersection
        {-# INLINE intersection #-}
        keys :: IntMap value -> [ContainerKey (IntMap value)]
    keys = IntMap value -> [Int]
    IntMap value -> [ContainerKey (IntMap value)]
    forall a. IntMap a -> [Int]
    IntMap.keys
        {-# INLINE keys #-}

    instance Ord element => SetContainer (Set.Set element) where
        type ContainerKey (Set.Set element) = element
        member :: ContainerKey (Set element) -> Set element -> Bool
    member = element -> Set element -> Bool
    ContainerKey (Set element) -> Set element -> Bool
    forall a. Ord a => a -> Set a -> Bool
    Set.member
        {-# INLINE member #-}
        notMember :: ContainerKey (Set element) -> Set element -> Bool
    notMember = element -> Set element -> Bool
    ContainerKey (Set element) -> Set element -> Bool
    forall a. Ord a => a -> Set a -> Bool
    Set.notMember
        {-# INLINE notMember #-}
        union :: Set element -> Set element -> Set element
    union = Set element -> Set element -> Set element
    forall element.
    Ord element =>
    Set element -> Set element -> Set element
    Set.union
        {-# INLINE union #-}
        unions :: forall mono.
    (MonoFoldable mono, Element mono ~ Set element) =>
    mono -> Set element
    unions = [Set element] -> Set element
    forall (f :: * -> *) a. (Foldable f, Ord a) => f (Set a) -> Set a
    Set.unions ([Set element] -> Set element)
    -> (mono -> [Set element]) -> mono -> Set element
    forall b c a. (b -> c) -> (a -> b) -> a -> c
    . mono -> [Set element]
    mono -> [Element mono]
    forall mono. MonoFoldable mono => mono -> [Element mono]
    otoList
        {-# INLINE unions #-}
        difference :: Set element -> Set element -> Set element
    difference = Set element -> Set element -> Set element
    forall element.
    Ord element =>
    Set element -> Set element -> Set element
    Set.difference
        {-# INLINE difference #-}
        intersection :: Set element -> Set element -> Set element
    intersection = Set element -> Set element -> Set element
    forall element.
    Ord element =>
    Set element -> Set element -> Set element
    Set.intersection
        {-# INLINE intersection #-}
        keys :: Set element -> [ContainerKey (Set element)]
    keys = Set element -> [element]
    Set element -> [ContainerKey (Set element)]
    forall a. Set a -> [a]
    Set.toList
        {-# INLINE keys #-}

    instance (Eq element, Hashable element) => SetContainer (HashSet.HashSet element) where
        type ContainerKey (HashSet.HashSet element) = element
        member :: ContainerKey (HashSet element) -> HashSet element -> Bool
    member = element -> HashSet element -> Bool
    ContainerKey (HashSet element) -> HashSet element -> Bool
    forall a. (Eq a, Hashable a) => a -> HashSet a -> Bool
    HashSet.member
        {-# INLINE member #-}
        notMember :: ContainerKey (HashSet element) -> HashSet element -> Bool
    notMember ContainerKey (HashSet element)
    e = Bool -> Bool
    not (Bool -> Bool)
    -> (HashSet element -> Bool) -> HashSet element -> Bool
    forall b c a. (b -> c) -> (a -> b) -> a -> c
    . element -> HashSet element -> Bool
    forall a. (Eq a, Hashable a) => a -> HashSet a -> Bool
    HashSet.member element
    ContainerKey (HashSet element)
    e
        {-# INLINE notMember #-}
        union :: HashSet element -> HashSet element -> HashSet element
    union = HashSet element -> HashSet element -> HashSet element
    forall a. Eq a => HashSet a -> HashSet a -> HashSet a
    HashSet.union
        {-# INLINE union #-}
        difference :: HashSet element -> HashSet element -> HashSet element
    difference = HashSet element -> HashSet element -> HashSet element
    forall element.
    (Eq element, Hashable element) =>
    HashSet element -> HashSet element -> HashSet element
    HashSet.difference
        {-# INLINE difference #-}
        intersection :: HashSet element -> HashSet element -> HashSet element
    intersection = HashSet element -> HashSet element -> HashSet element
    forall a. Eq a => HashSet a -> HashSet a -> HashSet a
    HashSet.intersection
        {-# INLINE intersection #-}
        keys :: HashSet element -> [ContainerKey (HashSet element)]
    keys = HashSet element -> [element]
    HashSet element -> [ContainerKey (HashSet element)]
    forall a. HashSet a -> [a]
    HashSet.toList
        {-# INLINE keys #-}

    instance SetContainer IntSet.IntSet where
        type ContainerKey IntSet.IntSet = Int
        member :: ContainerKey IntSet -> IntSet -> Bool
    member = Int -> IntSet -> Bool
    ContainerKey IntSet -> IntSet -> Bool
    IntSet.member
        {-# INLINE member #-}
        notMember :: ContainerKey IntSet -> IntSet -> Bool
    notMember = Int -> IntSet -> Bool
    ContainerKey IntSet -> IntSet -> Bool
    IntSet.notMember
        {-# INLINE notMember #-}
        union :: IntSet -> IntSet -> IntSet
    union = IntSet -> IntSet -> IntSet
    IntSet.union
        {-# INLINE union #-}
        difference :: IntSet -> IntSet -> IntSet
    difference = IntSet -> IntSet -> IntSet
    IntSet.difference
        {-# INLINE difference #-}
        intersection :: IntSet -> IntSet -> IntSet
    intersection = IntSet -> IntSet -> IntSet
    IntSet.intersection
        {-# INLINE intersection #-}
        keys :: IntSet -> [ContainerKey IntSet]
    keys = IntSet -> [Int]
    IntSet -> [ContainerKey IntSet]
    IntSet.toList
        {-# INLINE keys #-}

    instance Eq key => SetContainer [(key, value)] where
        type ContainerKey [(key, value)] = key
        member :: ContainerKey [(key, value)] -> [(key, value)] -> Bool
    member ContainerKey [(key, value)]
    k = ((key, value) -> Bool) -> [(key, value)] -> Bool
    forall (t :: * -> *) a. Foldable t => (a -> Bool) -> t a -> Bool
    List.any ((ContainerKey [(key, value)] -> ContainerKey [(key, value)] -> Bool
    forall a. Eq a => a -> a -> Bool
    == ContainerKey [(key, value)]
    k) (key -> Bool) -> ((key, value) -> key) -> (key, value) -> Bool
    forall b c a. (b -> c) -> (a -> b) -> a -> c
    . (key, value) -> key
    forall a b. (a, b) -> a
    fst)
        {-# INLINE member #-}
        notMember :: ContainerKey [(key, value)] -> [(key, value)] -> Bool
    notMember ContainerKey [(key, value)]
    k = Bool -> Bool
    not (Bool -> Bool)
    -> ([(key, value)] -> Bool) -> [(key, value)] -> Bool
    forall b c a. (b -> c) -> (a -> b) -> a -> c
    . ContainerKey [(key, value)] -> [(key, value)] -> Bool
    forall set. SetContainer set => ContainerKey set -> set -> Bool
    member ContainerKey [(key, value)]
    k
        {-# INLINE notMember #-}
        union :: [(key, value)] -> [(key, value)] -> [(key, value)]
    union = ((key, value) -> (key, value) -> Bool)
    -> [(key, value)] -> [(key, value)] -> [(key, value)]
    forall a. (a -> a -> Bool) -> [a] -> [a] -> [a]
    List.unionBy (key -> key -> Bool
    forall a. Eq a => a -> a -> Bool
    (==) (key -> key -> Bool)
    -> ((key, value) -> key) -> (key, value) -> (key, value) -> Bool
    forall b c a. (b -> b -> c) -> (a -> b) -> a -> a -> c
    `on` (key, value) -> key
    forall a b. (a, b) -> a
    fst)
        {-# INLINE union #-}
        [(key, value)]
    x difference :: [(key, value)] -> [(key, value)] -> [(key, value)]
    `difference` [(key, value)]
    y =
            [(key, value)] -> [(key, value)]
    loop [(key, value)]
    x
          where
            loop :: [(key, value)] -> [(key, value)]
    loop [] = []
            loop ((key
    k, value
    v):[(key, value)]
    rest) =
                case ContainerKey [(key, value)]
    -> [(key, value)] -> Maybe (MapValue [(key, value)])
    forall map.
    IsMap map =>
    ContainerKey map -> map -> Maybe (MapValue map)
    lookup key
    ContainerKey [(key, value)]
    k [(key, value)]
    y of
                    Maybe (MapValue [(key, value)])
    Nothing -> (key
    k, value
    v) (key, value) -> [(key, value)] -> [(key, value)]
    forall a. a -> [a] -> [a]
    : [(key, value)] -> [(key, value)]
    loop [(key, value)]
    rest
                    Just MapValue [(key, value)]
    _ -> [(key, value)] -> [(key, value)]
    loop [(key, value)]
    rest
        intersection :: [(key, value)] -> [(key, value)] -> [(key, value)]
    intersection = ((key, value) -> (key, value) -> Bool)
    -> [(key, value)] -> [(key, value)] -> [(key, value)]
    forall a. (a -> a -> Bool) -> [a] -> [a] -> [a]
    List.intersectBy (key -> key -> Bool
    forall a. Eq a => a -> a -> Bool
    (==) (key -> key -> Bool)
    -> ((key, value) -> key) -> (key, value) -> (key, value) -> Bool
    forall b c a. (b -> b -> c) -> (a -> b) -> a -> a -> c
    `on` (key, value) -> key
    forall a b. (a, b) -> a
    fst)
        {-# INLINE intersection #-}
        keys :: [(key, value)] -> [ContainerKey [(key, value)]]
    keys = ((key, value) -> key) -> [(key, value)] -> [key]
    forall a b. (a -> b) -> [a] -> [b]
    map (key, value) -> key
    forall a b. (a, b) -> a
    fst
        {-# INLINE keys #-}

    -- | A guaranteed-polymorphic @Map@, which allows for more polymorphic versions
    -- of functions.
    class PolyMap map where
        -- | Get the difference between two maps, using the left map's values.
        differenceMap :: map value1 -> map value2 -> map value1
        {-
        differenceWithMap :: (value1 -> value2 -> Maybe value1)
                          -> map value1 -> map value2 -> map value1
        -}

        -- | Get the intersection of two maps, using the left map's values.
        intersectionMap :: map value1 -> map value2 -> map value1

        -- | Get the intersection of two maps with a supplied function
        -- that takes in the left map's value and the right map's value.
        intersectionWithMap :: (value1 -> value2 -> value3)
                            -> map value1 -> map value2 -> map value3

    -- | This instance uses the functions from "Data.Map.Strict".
    instance Ord key => PolyMap (Map.Map key) where
        differenceMap :: forall value1 value2.
    Map key value1 -> Map key value2 -> Map key value1
    differenceMap = Map key value1 -> Map key value2 -> Map key value1
    forall k a b. Ord k => Map k a -> Map k b -> Map k a
    Map.difference
        {-# INLINE differenceMap #-}
        --differenceWithMap = Map.differenceWith
        intersectionMap :: forall value1 value2.
    Map key value1 -> Map key value2 -> Map key value1
    intersectionMap = Map key value1 -> Map key value2 -> Map key value1
    forall k a b. Ord k => Map k a -> Map k b -> Map k a
    Map.intersection
        {-# INLINE intersectionMap #-}
        intersectionWithMap :: forall value1 value2 value3.
    (value1 -> value2 -> value3)
    -> Map key value1 -> Map key value2 -> Map key value3
    intersectionWithMap = (value1 -> value2 -> value3)
    -> Map key value1 -> Map key value2 -> Map key value3
    forall k a b c.
    Ord k =>
    (a -> b -> c) -> Map k a -> Map k b -> Map k c
    Map.intersectionWith
        {-# INLINE intersectionWithMap #-}

    -- | This instance uses the functions from "Data.HashMap.Strict".
    instance (Eq key, Hashable key) => PolyMap (HashMap.HashMap key) where
        differenceMap :: forall value1 value2.
    HashMap key value1 -> HashMap key value2 -> HashMap key value1
    differenceMap = HashMap key value1 -> HashMap key value2 -> HashMap key value1
    forall k v w.
    (Eq k, Hashable k) =>
    HashMap k v -> HashMap k w -> HashMap k v
    HashMap.difference
        {-# INLINE differenceMap #-}
        --differenceWithMap = HashMap.differenceWith
        intersectionMap :: forall value1 value2.
    HashMap key value1 -> HashMap key value2 -> HashMap key value1
    intersectionMap = HashMap key value1 -> HashMap key value2 -> HashMap key value1
    forall k v w. Eq k => HashMap k v -> HashMap k w -> HashMap k v
    HashMap.intersection
        {-# INLINE intersectionMap #-}
        intersectionWithMap :: forall value1 value2 value3.
    (value1 -> value2 -> value3)
    -> HashMap key value1 -> HashMap key value2 -> HashMap key value3
    intersectionWithMap = (value1 -> value2 -> value3)
    -> HashMap key value1 -> HashMap key value2 -> HashMap key value3
    forall k v1 v2 v3.
    Eq k =>
    (v1 -> v2 -> v3) -> HashMap k v1 -> HashMap k v2 -> HashMap k v3
    HashMap.intersectionWith
        {-# INLINE intersectionWithMap #-}

    -- | This instance uses the functions from "Data.IntMap.Strict".
    instance PolyMap IntMap.IntMap where
        differenceMap :: forall a b. IntMap a -> IntMap b -> IntMap a
    differenceMap = IntMap value1 -> IntMap value2 -> IntMap value1
    forall a b. IntMap a -> IntMap b -> IntMap a
    IntMap.difference
        {-# INLINE differenceMap #-}
        --differenceWithMap = IntMap.differenceWith
        intersectionMap :: forall a b. IntMap a -> IntMap b -> IntMap a
    intersectionMap = IntMap value1 -> IntMap value2 -> IntMap value1
    forall a b. IntMap a -> IntMap b -> IntMap a
    IntMap.intersection
        {-# INLINE intersectionMap #-}
        intersectionWithMap :: forall value1 value2 value3.
    (value1 -> value2 -> value3)
    -> IntMap value1 -> IntMap value2 -> IntMap value3
    intersectionWithMap = (value1 -> value2 -> value3)
    -> IntMap value1 -> IntMap value2 -> IntMap value3
    forall value1 value2 value3.
    (value1 -> value2 -> value3)
    -> IntMap value1 -> IntMap value2 -> IntMap value3
    IntMap.intersectionWith
        {-# INLINE intersectionWithMap #-}

    -- | A @Map@ type polymorphic in both its key and value.
    class BiPolyMap map where
        type BPMKeyConstraint map key :: Constraint
        mapKeysWith :: (BPMKeyConstraint map k1, BPMKeyConstraint map k2)
                    => (v -> v -> v) -- ^ combine values that now overlap
                    -> (k1 -> k2)
                    -> map k1 v
                    -> map k2 v
    instance BiPolyMap Map.Map where
        type BPMKeyConstraint Map.Map key = Ord key
        mapKeysWith :: forall k1 k2 v.
    (BPMKeyConstraint Map k1, BPMKeyConstraint Map k2) =>
    (v -> v -> v) -> (k1 -> k2) -> Map k1 v -> Map k2 v
    mapKeysWith = (v -> v -> v) -> (k1 -> k2) -> Map k1 v -> Map k2 v
    forall k2 a k1.
    Ord k2 =>
    (a -> a -> a) -> (k1 -> k2) -> Map k1 a -> Map k2 a
    Map.mapKeysWith
        {-# INLINE mapKeysWith #-}
    instance BiPolyMap HashMap.HashMap where
        type BPMKeyConstraint HashMap.HashMap key = (Hashable key, Eq key)
        mapKeysWith :: forall k1 k2 v.
    (BPMKeyConstraint HashMap k1, BPMKeyConstraint HashMap k2) =>
    (v -> v -> v) -> (k1 -> k2) -> HashMap k1 v -> HashMap k2 v
    mapKeysWith v -> v -> v
    g k1 -> k2
    f =
            [(k2, v)] -> HashMap k2 v
    [(ContainerKey (HashMap k2 v), MapValue (HashMap k2 v))]
    -> HashMap k2 v
    forall map. IsMap map => [(ContainerKey map, MapValue map)] -> map
    mapFromList ([(k2, v)] -> HashMap k2 v)
    -> (HashMap k1 v -> [(k2, v)]) -> HashMap k1 v -> HashMap k2 v
    forall b c a. (b -> c) -> (a -> b) -> a -> c
    . (MapValue [(k2, v)] -> MapValue [(k2, v)] -> MapValue [(k2, v)])
    -> [[(k2, v)]] -> [(k2, v)]
    forall map.
    IsMap map =>
    (MapValue map -> MapValue map -> MapValue map) -> [map] -> map
    unionsWith v -> v -> v
    MapValue [(k2, v)] -> MapValue [(k2, v)] -> MapValue [(k2, v)]
    g ([[(k2, v)]] -> [(k2, v)])
    -> (HashMap k1 v -> [[(k2, v)]]) -> HashMap k1 v -> [(k2, v)]
    forall b c a. (b -> c) -> (a -> b) -> a -> c
    . ((k1, v) -> [(k2, v)]) -> [(k1, v)] -> [[(k2, v)]]
    forall a b. (a -> b) -> [a] -> [b]
    map (k1, v) -> [(k2, v)]
    go ([(k1, v)] -> [[(k2, v)]])
    -> (HashMap k1 v -> [(k1, v)]) -> HashMap k1 v -> [[(k2, v)]]
    forall b c a. (b -> c) -> (a -> b) -> a -> c
    . HashMap k1 v -> [(k1, v)]
    HashMap k1 v
    -> [(ContainerKey (HashMap k1 v), MapValue (HashMap k1 v))]
    forall map. IsMap map => map -> [(ContainerKey map, MapValue map)]
    mapToList
          where
            go :: (k1, v) -> [(k2, v)]
    go (k1
    k, v
    v) = [(k1 -> k2
    f k1
    k, v
    v)]
        {-# INLINE mapKeysWith #-}

    -- | Polymorphic typeclass for interacting with different map types
    class (MonoTraversable map, SetContainer map) => IsMap map where
        -- | In some cases, 'MapValue' and 'Element' will be different, e.g., the
        -- 'IsMap' instance of associated lists.
        type MapValue map

        -- | Look up a value in a map with a specified key.
        lookup       :: ContainerKey map -> map -> Maybe (MapValue map)

        -- | Insert a key-value pair into a map.
        insertMap    :: ContainerKey map -> MapValue map -> map -> map

        -- | Delete a key-value pair of a map using a specified key.
        deleteMap    :: ContainerKey map -> map -> map

        -- | Create a map from a single key-value pair.
        singletonMap :: ContainerKey map -> MapValue map -> map

        -- | Convert a list of key-value pairs to a map
        mapFromList  :: [(ContainerKey map, MapValue map)] -> map

        -- | Convert a map to a list of key-value pairs.
        mapToList    :: map -> [(ContainerKey map, MapValue map)]

        -- | Like 'lookup', but uses a default value when the key does
        -- not exist in the map.
        findWithDefault :: MapValue map -> ContainerKey map -> map -> MapValue map
        findWithDefault MapValue map
    def ContainerKey map
    key = MapValue map -> Maybe (MapValue map) -> MapValue map
    forall a. a -> Maybe a -> a
    fromMaybe MapValue map
    def (Maybe (MapValue map) -> MapValue map)
    -> (map -> Maybe (MapValue map)) -> map -> MapValue map
    forall b c a. (b -> c) -> (a -> b) -> a -> c
    . ContainerKey map -> map -> Maybe (MapValue map)
    forall map.
    IsMap map =>
    ContainerKey map -> map -> Maybe (MapValue map)
    lookup ContainerKey map
    key

        -- | Insert a key-value pair into a map.
        --
        -- Inserts the value directly if the key does not exist in the map. Otherwise,
        -- apply a supplied function that accepts the new value and the previous value
        -- and insert that result into the map.
        insertWith :: (MapValue map -> MapValue map -> MapValue map)
                      -- ^ function that accepts the new value and the
                      -- previous value and returns the value that will be
                      -- set in the map.
                   -> ContainerKey map -- ^ key
                   -> MapValue map     -- ^ new value to insert
                   -> map              -- ^ input map
                   -> map              -- ^ resulting map
        insertWith MapValue map -> MapValue map -> MapValue map
    f ContainerKey map
    k MapValue map
    v map
    m =
            MapValue map
    v' MapValue map -> map -> map
    forall a b. a -> b -> b
    `seq` ContainerKey map -> MapValue map -> map -> map
    forall map.
    IsMap map =>
    ContainerKey map -> MapValue map -> map -> map
    insertMap ContainerKey map
    k MapValue map
    v' map
    m
          where
            v' :: MapValue map
    v' =
                case ContainerKey map -> map -> Maybe (MapValue map)
    forall map.
    IsMap map =>
    ContainerKey map -> map -> Maybe (MapValue map)
    lookup ContainerKey map
    k map
    m of
                    Maybe (MapValue map)
    Nothing -> MapValue map
    v
                    Just MapValue map
    vold -> MapValue map -> MapValue map -> MapValue map
    f MapValue map
    v MapValue map
    vold

        -- | Insert a key-value pair into a map.
        --
        -- Inserts the value directly if the key does not exist in the map. Otherwise,
        -- apply a supplied function that accepts the key, the new value, and the
        -- previous value and insert that result into the map.
        insertWithKey
            :: (ContainerKey map -> MapValue map -> MapValue map -> MapValue map)
               -- ^ function that accepts the key, the new value, and the
               -- previous value and returns the value that will be
               -- set in the map.
            -> ContainerKey map -- ^ key
            -> MapValue map     -- ^ new value to insert
            -> map              -- ^ input map
            -> map              -- ^ resulting map
        insertWithKey ContainerKey map -> MapValue map -> MapValue map -> MapValue map
    f ContainerKey map
    k MapValue map
    v map
    m =
            MapValue map
    v' MapValue map -> map -> map
    forall a b. a -> b -> b
    `seq` ContainerKey map -> MapValue map -> map -> map
    forall map.
    IsMap map =>
    ContainerKey map -> MapValue map -> map -> map
    insertMap ContainerKey map
    k MapValue map
    v' map
    m
          where
            v' :: MapValue map
    v' =
                case ContainerKey map -> map -> Maybe (MapValue map)
    forall map.
    IsMap map =>
    ContainerKey map -> map -> Maybe (MapValue map)
    lookup ContainerKey map
    k map
    m of
                    Maybe (MapValue map)
    Nothing -> MapValue map
    v
                    Just MapValue map
    vold -> ContainerKey map -> MapValue map -> MapValue map -> MapValue map
    f ContainerKey map
    k MapValue map
    v MapValue map
    vold

        -- | Insert a key-value pair into a map, return the previous key's value
        -- if it existed.
        --
        -- Inserts the value directly if the key does not exist in the map. Otherwise,
        -- apply a supplied function that accepts the key, the new value, and the
        -- previous value and insert that result into the map.
        insertLookupWithKey
            :: (ContainerKey map -> MapValue map -> MapValue map -> MapValue map)
               -- ^ function that accepts the key, the new value, and the
               -- previous value and returns the value that will be
               -- set in the map.
            -> ContainerKey map            -- ^ key
            -> MapValue map                -- ^ new value to insert
            -> map                         -- ^ input map
            -> (Maybe (MapValue map), map) -- ^ previous value and the resulting map
        insertLookupWithKey ContainerKey map -> MapValue map -> MapValue map -> MapValue map
    f ContainerKey map
    k MapValue map
    v map
    m =
            MapValue map
    v' MapValue map
    -> (Maybe (MapValue map), map) -> (Maybe (MapValue map), map)
    forall a b. a -> b -> b
    `seq` (Maybe (MapValue map)
    mold, ContainerKey map -> MapValue map -> map -> map
    forall map.
    IsMap map =>
    ContainerKey map -> MapValue map -> map -> map
    insertMap ContainerKey map
    k MapValue map
    v' map
    m)
          where
            (Maybe (MapValue map)
    mold, MapValue map
    v') =
                case ContainerKey map -> map -> Maybe (MapValue map)
    forall map.
    IsMap map =>
    ContainerKey map -> map -> Maybe (MapValue map)
    lookup ContainerKey map
    k map
    m of
                    Maybe (MapValue map)
    Nothing -> (Maybe (MapValue map)
    forall a. Maybe a
    Nothing, MapValue map
    v)
                    Just MapValue map
    vold -> (MapValue map -> Maybe (MapValue map)
    forall a. a -> Maybe a
    Just MapValue map
    vold, ContainerKey map -> MapValue map -> MapValue map -> MapValue map
    f ContainerKey map
    k MapValue map
    v MapValue map
    vold)

        -- | Apply a function to the value of a given key.
        --
        -- Returns the input map when the key-value pair does not exist.
        adjustMap
            :: (MapValue map -> MapValue map)
               -- ^ function to apply to the previous value
            -> ContainerKey map -- ^ key
            -> map              -- ^ input map
            -> map              -- ^ resulting map
        adjustMap MapValue map -> MapValue map
    f ContainerKey map
    k map
    m =
            case ContainerKey map -> map -> Maybe (MapValue map)
    forall map.
    IsMap map =>
    ContainerKey map -> map -> Maybe (MapValue map)
    lookup ContainerKey map
    k map
    m of
                Maybe (MapValue map)
    Nothing -> map
    m
                Just MapValue map
    v ->
                    let v' :: MapValue map
    v' = MapValue map -> MapValue map
    f MapValue map
    v
                     in MapValue map
    v' MapValue map -> map -> map
    forall a b. a -> b -> b
    `seq` ContainerKey map -> MapValue map -> map -> map
    forall map.
    IsMap map =>
    ContainerKey map -> MapValue map -> map -> map
    insertMap ContainerKey map
    k MapValue map
    v' map
    m

        -- | Equivalent to 'adjustMap', but the function accepts the key,
        -- as well as the previous value.
        adjustWithKey
            :: (ContainerKey map -> MapValue map -> MapValue map)
               -- ^ function that accepts the key and the previous value
               -- and returns the new value
            -> ContainerKey map -- ^ key
            -> map              -- ^ input map
            -> map              -- ^ resulting map
        adjustWithKey ContainerKey map -> MapValue map -> MapValue map
    f ContainerKey map
    k map
    m =
            case ContainerKey map -> map -> Maybe (MapValue map)
    forall map.
    IsMap map =>
    ContainerKey map -> map -> Maybe (MapValue map)
    lookup ContainerKey map
    k map
    m of
                Maybe (MapValue map)
    Nothing -> map
    m
                Just MapValue map
    v ->
                    let v' :: MapValue map
    v' = ContainerKey map -> MapValue map -> MapValue map
    f ContainerKey map
    k MapValue map
    v
                     in MapValue map
    v' MapValue map -> map -> map
    forall a b. a -> b -> b
    `seq` ContainerKey map -> MapValue map -> map -> map
    forall map.
    IsMap map =>
    ContainerKey map -> MapValue map -> map -> map
    insertMap ContainerKey map
    k MapValue map
    v' map
    m

        -- | Apply a function to the value of a given key.
        --
        -- If the function returns 'Nothing', this deletes the key-value pair.
        --
        -- Returns the input map when the key-value pair does not exist.
        updateMap
            :: (MapValue map -> Maybe (MapValue map))
               -- ^ function that accepts the previous value
               -- and returns the new value or 'Nothing'
            -> ContainerKey map -- ^ key
            -> map              -- ^ input map
            -> map              -- ^ resulting map
        updateMap MapValue map -> Maybe (MapValue map)
    f ContainerKey map
    k map
    m =
            case ContainerKey map -> map -> Maybe (MapValue map)
    forall map.
    IsMap map =>
    ContainerKey map -> map -> Maybe (MapValue map)
    lookup ContainerKey map
    k map
    m of
                Maybe (MapValue map)
    Nothing -> map
    m
                Just MapValue map
    v ->
                    case MapValue map -> Maybe (MapValue map)
    f MapValue map
    v of
                        Maybe (MapValue map)
    Nothing -> ContainerKey map -> map -> map
    forall map. IsMap map => ContainerKey map -> map -> map
    deleteMap ContainerKey map
    k map
    m
                        Just MapValue map
    v' -> MapValue map
    v' MapValue map -> map -> map
    forall a b. a -> b -> b
    `seq` ContainerKey map -> MapValue map -> map -> map
    forall map.
    IsMap map =>
    ContainerKey map -> MapValue map -> map -> map
    insertMap ContainerKey map
    k MapValue map
    v' map
    m

        -- | Equivalent to 'updateMap', but the function accepts the key,
        -- as well as the previous value.
        updateWithKey
            :: (ContainerKey map -> MapValue map -> Maybe (MapValue map))
               -- ^ function that accepts the key and the previous value
               -- and returns the new value or 'Nothing'
            -> ContainerKey map -- ^ key
            -> map              -- ^ input map
            -> map              -- ^ resulting map
        updateWithKey ContainerKey map -> MapValue map -> Maybe (MapValue map)
    f ContainerKey map
    k map
    m =
            case ContainerKey map -> map -> Maybe (MapValue map)
    forall map.
    IsMap map =>
    ContainerKey map -> map -> Maybe (MapValue map)
    lookup ContainerKey map
    k map
    m of
                Maybe (MapValue map)
    Nothing -> map
    m
                Just MapValue map
    v ->
                    case ContainerKey map -> MapValue map -> Maybe (MapValue map)
    f ContainerKey map
    k MapValue map
    v of
                        Maybe (MapValue map)
    Nothing -> ContainerKey map -> map -> map
    forall map. IsMap map => ContainerKey map -> map -> map
    deleteMap ContainerKey map
    k map
    m
                        Just MapValue map
    v' -> MapValue map
    v' MapValue map -> map -> map
    forall a b. a -> b -> b
    `seq` ContainerKey map -> MapValue map -> map -> map
    forall map.
    IsMap map =>
    ContainerKey map -> MapValue map -> map -> map
    insertMap ContainerKey map
    k MapValue map
    v' map
    m

        -- | Apply a function to the value of a given key.
        --
        -- If the map does not contain the key this returns 'Nothing'
        -- and the input map.
        --
        -- If the map does contain the key but the function returns 'Nothing',
        -- this returns the previous value and the map with the key-value pair removed.
        --
        -- If the map contains the key and the function returns a value,
        -- this returns the new value and the map with the key-value pair with the new value.
        updateLookupWithKey
            :: (ContainerKey map -> MapValue map -> Maybe (MapValue map))
               -- ^ function that accepts the key and the previous value
               -- and returns the new value or 'Nothing'
            -> ContainerKey map            -- ^ key
            -> map                         -- ^ input map
            -> (Maybe (MapValue map), map) -- ^ previous/new value and the resulting map
        updateLookupWithKey ContainerKey map -> MapValue map -> Maybe (MapValue map)
    f ContainerKey map
    k map
    m =
            case ContainerKey map -> map -> Maybe (MapValue map)
    forall map.
    IsMap map =>
    ContainerKey map -> map -> Maybe (MapValue map)
    lookup ContainerKey map
    k map
    m of
                Maybe (MapValue map)
    Nothing -> (Maybe (MapValue map)
    forall a. Maybe a
    Nothing, map
    m)
                Just MapValue map
    v ->
                    case ContainerKey map -> MapValue map -> Maybe (MapValue map)
    f ContainerKey map
    k MapValue map
    v of
                        Maybe (MapValue map)
    Nothing -> (MapValue map -> Maybe (MapValue map)
    forall a. a -> Maybe a
    Just MapValue map
    v, ContainerKey map -> map -> map
    forall map. IsMap map => ContainerKey map -> map -> map
    deleteMap ContainerKey map
    k map
    m)
                        Just MapValue map
    v' -> MapValue map
    v' MapValue map
    -> (Maybe (MapValue map), map) -> (Maybe (MapValue map), map)
    forall a b. a -> b -> b
    `seq` (MapValue map -> Maybe (MapValue map)
    forall a. a -> Maybe a
    Just MapValue map
    v', ContainerKey map -> MapValue map -> map -> map
    forall map.
    IsMap map =>
    ContainerKey map -> MapValue map -> map -> map
    insertMap ContainerKey map
    k MapValue map
    v' map
    m)

        -- | Update/Delete the value of a given key.
        --
        -- Applies a function to previous value of a given key, if it results in 'Nothing'
        -- delete the key-value pair from the map, otherwise replace the previous value
        -- with the new value.
        alterMap
            :: (Maybe (MapValue map) -> Maybe (MapValue map))
               -- ^ function that accepts the previous value and
               -- returns the new value or 'Nothing'
            -> ContainerKey map -- ^ key
            -> map              -- ^ input map
            -> map              -- ^ resulting map
        alterMap Maybe (MapValue map) -> Maybe (MapValue map)
    f ContainerKey map
    k map
    m =
            case Maybe (MapValue map) -> Maybe (MapValue map)
    f Maybe (MapValue map)
    mold of
                Maybe (MapValue map)
    Nothing ->
                    case Maybe (MapValue map)
    mold of
                        Maybe (MapValue map)
    Nothing -> map
    m
                        Just MapValue map
    _ -> ContainerKey map -> map -> map
    forall map. IsMap map => ContainerKey map -> map -> map
    deleteMap ContainerKey map
    k map
    m
                Just MapValue map
    v -> ContainerKey map -> MapValue map -> map -> map
    forall map.
    IsMap map =>
    ContainerKey map -> MapValue map -> map -> map
    insertMap ContainerKey map
    k MapValue map
    v map
    m
          where
            mold :: Maybe (MapValue map)
    mold = ContainerKey map -> map -> Maybe (MapValue map)
    forall map.
    IsMap map =>
    ContainerKey map -> map -> Maybe (MapValue map)
    lookup ContainerKey map
    k map
    m

        -- | Combine two maps.
        --
        -- When a key exists in both maps, apply a function
        -- to both of the values and use the result of that as the value
        -- of the key in the resulting map.
        unionWith
            :: (MapValue map -> MapValue map -> MapValue map)
               -- ^ function that accepts the first map's value and the second map's value
               -- and returns the new value that will be used
            -> map -- ^ first map
            -> map -- ^ second map
            -> map -- ^ resulting map
        unionWith MapValue map -> MapValue map -> MapValue map
    f map
    x map
    y =
            [(ContainerKey map, MapValue map)] -> map
    forall map. IsMap map => [(ContainerKey map, MapValue map)] -> map
    mapFromList ([(ContainerKey map, MapValue map)] -> map)
    -> [(ContainerKey map, MapValue map)] -> map
    forall a b. (a -> b) -> a -> b
    $ [(ContainerKey map, MapValue map)]
    -> [(ContainerKey map, MapValue map)]
    loop ([(ContainerKey map, MapValue map)]
     -> [(ContainerKey map, MapValue map)])
    -> [(ContainerKey map, MapValue map)]
    -> [(ContainerKey map, MapValue map)]
    forall a b. (a -> b) -> a -> b
    $ map -> [(ContainerKey map, MapValue map)]
    forall map. IsMap map => map -> [(ContainerKey map, MapValue map)]
    mapToList map
    x [(ContainerKey map, MapValue map)]
    -> [(ContainerKey map, MapValue map)]
    -> [(ContainerKey map, MapValue map)]
    forall a. [a] -> [a] -> [a]
    ++ map -> [(ContainerKey map, MapValue map)]
    forall map. IsMap map => map -> [(ContainerKey map, MapValue map)]
    mapToList map
    y
          where
            loop :: [(ContainerKey map, MapValue map)]
    -> [(ContainerKey map, MapValue map)]
    loop [] = []
            loop ((ContainerKey map
    k, MapValue map
    v):[(ContainerKey map, MapValue map)]
    rest) =
                case ContainerKey map
    -> [(ContainerKey map, MapValue map)] -> Maybe (MapValue map)
    forall a b. Eq a => a -> [(a, b)] -> Maybe b
    List.lookup ContainerKey map
    k [(ContainerKey map, MapValue map)]
    rest of
                    Maybe (MapValue map)
    Nothing -> (ContainerKey map
    k, MapValue map
    v) (ContainerKey map, MapValue map)
    -> [(ContainerKey map, MapValue map)]
    -> [(ContainerKey map, MapValue map)]
    forall a. a -> [a] -> [a]
    : [(ContainerKey map, MapValue map)]
    -> [(ContainerKey map, MapValue map)]
    loop [(ContainerKey map, MapValue map)]
    rest
                    Just MapValue map
    v' -> (ContainerKey map
    k, MapValue map -> MapValue map -> MapValue map
    f MapValue map
    v MapValue map
    v') (ContainerKey map, MapValue map)
    -> [(ContainerKey map, MapValue map)]
    -> [(ContainerKey map, MapValue map)]
    forall a. a -> [a] -> [a]
    : [(ContainerKey map, MapValue map)]
    -> [(ContainerKey map, MapValue map)]
    loop (ContainerKey [(ContainerKey map, MapValue map)]
    -> [(ContainerKey map, MapValue map)]
    -> [(ContainerKey map, MapValue map)]
    forall map. IsMap map => ContainerKey map -> map -> map
    deleteMap ContainerKey map
    ContainerKey [(ContainerKey map, MapValue map)]
    k [(ContainerKey map, MapValue map)]
    rest)

        -- Equivalent to 'unionWith', but the function accepts the key,
        -- as well as both of the map's values.
        unionWithKey
            :: (ContainerKey map -> MapValue map -> MapValue map -> MapValue map)
               -- ^ function that accepts the key, the first map's value and the
               -- second map's value and returns the new value that will be used
            -> map -- ^ first map
            -> map -- ^ second map
            -> map -- ^ resulting map
        unionWithKey ContainerKey map -> MapValue map -> MapValue map -> MapValue map
    f map
    x map
    y =
            [(ContainerKey map, MapValue map)] -> map
    forall map. IsMap map => [(ContainerKey map, MapValue map)] -> map
    mapFromList ([(ContainerKey map, MapValue map)] -> map)
    -> [(ContainerKey map, MapValue map)] -> map
    forall a b. (a -> b) -> a -> b
    $ [(ContainerKey map, MapValue map)]
    -> [(ContainerKey map, MapValue map)]
    loop ([(ContainerKey map, MapValue map)]
     -> [(ContainerKey map, MapValue map)])
    -> [(ContainerKey map, MapValue map)]
    -> [(ContainerKey map, MapValue map)]
    forall a b. (a -> b) -> a -> b
    $ map -> [(ContainerKey map, MapValue map)]
    forall map. IsMap map => map -> [(ContainerKey map, MapValue map)]
    mapToList map
    x [(ContainerKey map, MapValue map)]
    -> [(ContainerKey map, MapValue map)]
    -> [(ContainerKey map, MapValue map)]
    forall a. [a] -> [a] -> [a]
    ++ map -> [(ContainerKey map, MapValue map)]
    forall map. IsMap map => map -> [(ContainerKey map, MapValue map)]
    mapToList map
    y
          where
            loop :: [(ContainerKey map, MapValue map)]
    -> [(ContainerKey map, MapValue map)]
    loop [] = []
            loop ((ContainerKey map
    k, MapValue map
    v):[(ContainerKey map, MapValue map)]
    rest) =
                case ContainerKey map
    -> [(ContainerKey map, MapValue map)] -> Maybe (MapValue map)
    forall a b. Eq a => a -> [(a, b)] -> Maybe b
    List.lookup ContainerKey map
    k [(ContainerKey map, MapValue map)]
    rest of
                    Maybe (MapValue map)
    Nothing -> (ContainerKey map
    k, MapValue map
    v) (ContainerKey map, MapValue map)
    -> [(ContainerKey map, MapValue map)]
    -> [(ContainerKey map, MapValue map)]
    forall a. a -> [a] -> [a]
    : [(ContainerKey map, MapValue map)]
    -> [(ContainerKey map, MapValue map)]
    loop [(ContainerKey map, MapValue map)]
    rest
                    Just MapValue map
    v' -> (ContainerKey map
    k, ContainerKey map -> MapValue map -> MapValue map -> MapValue map
    f ContainerKey map
    k MapValue map
    v MapValue map
    v') (ContainerKey map, MapValue map)
    -> [(ContainerKey map, MapValue map)]
    -> [(ContainerKey map, MapValue map)]
    forall a. a -> [a] -> [a]
    : [(ContainerKey map, MapValue map)]
    -> [(ContainerKey map, MapValue map)]
    loop (ContainerKey [(ContainerKey map, MapValue map)]
    -> [(ContainerKey map, MapValue map)]
    -> [(ContainerKey map, MapValue map)]
    forall map. IsMap map => ContainerKey map -> map -> map
    deleteMap ContainerKey map
    ContainerKey [(ContainerKey map, MapValue map)]
    k [(ContainerKey map, MapValue map)]
    rest)

        -- | Combine a list of maps.
        --
        -- When a key exists in two different maps, apply a function
        -- to both of the values and use the result of that as the value
        -- of the key in the resulting map.
        unionsWith
            :: (MapValue map -> MapValue map -> MapValue map)
               -- ^ function that accepts the first map's value and the second map's value
               -- and returns the new value that will be used
            -> [map] -- ^ input list of maps
            -> map   -- ^ resulting map
        unionsWith MapValue map -> MapValue map -> MapValue map
    _ [] = map
    forall a. Monoid a => a
    mempty
        unionsWith MapValue map -> MapValue map -> MapValue map
    _ [map
    x] = map
    x
        unionsWith MapValue map -> MapValue map -> MapValue map
    f (map
    x:map
    y:[map]
    z) = (MapValue map -> MapValue map -> MapValue map) -> [map] -> map
    forall map.
    IsMap map =>
    (MapValue map -> MapValue map -> MapValue map) -> [map] -> map
    unionsWith MapValue map -> MapValue map -> MapValue map
    f ((MapValue map -> MapValue map -> MapValue map) -> map -> map -> map
    forall map.
    IsMap map =>
    (MapValue map -> MapValue map -> MapValue map) -> map -> map -> map
    unionWith MapValue map -> MapValue map -> MapValue map
    f map
    x map
    ymap -> [map] -> [map]
    forall a. a -> [a] -> [a]
    :[map]
    z)

        -- | Apply a function over every key-value pair of a map.
        mapWithKey
            :: (ContainerKey map -> MapValue map -> MapValue map)
               -- ^ function that accepts the key and the previous value
               -- and returns the new value
            -> map -- ^ input map
            -> map -- ^ resulting map
        mapWithKey ContainerKey map -> MapValue map -> MapValue map
    f =
            [(ContainerKey map, MapValue map)] -> map
    forall map. IsMap map => [(ContainerKey map, MapValue map)] -> map
    mapFromList ([(ContainerKey map, MapValue map)] -> map)
    -> (map -> [(ContainerKey map, MapValue map)]) -> map -> map
    forall b c a. (b -> c) -> (a -> b) -> a -> c
    . ((ContainerKey map, MapValue map)
     -> (ContainerKey map, MapValue map))
    -> [(ContainerKey map, MapValue map)]
    -> [(ContainerKey map, MapValue map)]
    forall a b. (a -> b) -> [a] -> [b]
    map (ContainerKey map, MapValue map)
    -> (ContainerKey map, MapValue map)
    go ([(ContainerKey map, MapValue map)]
     -> [(ContainerKey map, MapValue map)])
    -> (map -> [(ContainerKey map, MapValue map)])
    -> map
    -> [(ContainerKey map, MapValue map)]
    forall b c a. (b -> c) -> (a -> b) -> a -> c
    . map -> [(ContainerKey map, MapValue map)]
    forall map. IsMap map => map -> [(ContainerKey map, MapValue map)]
    mapToList
          where
            go :: (ContainerKey map, MapValue map)
    -> (ContainerKey map, MapValue map)
    go (ContainerKey map
    k, MapValue map
    v) = (ContainerKey map
    k, ContainerKey map -> MapValue map -> MapValue map
    f ContainerKey map
    k MapValue map
    v)

        -- | Apply a function over every key of a pair and run
        -- 'unionsWith' over the results.
        omapKeysWith
            :: (MapValue map -> MapValue map -> MapValue map)
               -- ^ function that accepts the first map's value and the second map's value
               -- and returns the new value that will be used
            -> (ContainerKey map -> ContainerKey map)
               -- ^ function that accepts the previous key and
               -- returns the new key
            -> map -- ^ input map
            -> map -- ^ resulting map
        omapKeysWith MapValue map -> MapValue map -> MapValue map
    g ContainerKey map -> ContainerKey map
    f =
            [(ContainerKey map, MapValue map)] -> map
    forall map. IsMap map => [(ContainerKey map, MapValue map)] -> map
    mapFromList ([(ContainerKey map, MapValue map)] -> map)
    -> (map -> [(ContainerKey map, MapValue map)]) -> map -> map
    forall b c a. (b -> c) -> (a -> b) -> a -> c
    . (MapValue [(ContainerKey map, MapValue map)]
     -> MapValue [(ContainerKey map, MapValue map)]
     -> MapValue [(ContainerKey map, MapValue map)])
    -> [[(ContainerKey map, MapValue map)]]
    -> [(ContainerKey map, MapValue map)]
    forall map.
    IsMap map =>
    (MapValue map -> MapValue map -> MapValue map) -> [map] -> map
    unionsWith MapValue map -> MapValue map -> MapValue map
    MapValue [(ContainerKey map, MapValue map)]
    -> MapValue [(ContainerKey map, MapValue map)]
    -> MapValue [(ContainerKey map, MapValue map)]
    g ([[(ContainerKey map, MapValue map)]]
     -> [(ContainerKey map, MapValue map)])
    -> (map -> [[(ContainerKey map, MapValue map)]])
    -> map
    -> [(ContainerKey map, MapValue map)]
    forall b c a. (b -> c) -> (a -> b) -> a -> c
    . ((ContainerKey map, MapValue map)
     -> [(ContainerKey map, MapValue map)])
    -> [(ContainerKey map, MapValue map)]
    -> [[(ContainerKey map, MapValue map)]]
    forall a b. (a -> b) -> [a] -> [b]
    map (ContainerKey map, MapValue map)
    -> [(ContainerKey map, MapValue map)]
    go ([(ContainerKey map, MapValue map)]
     -> [[(ContainerKey map, MapValue map)]])
    -> (map -> [(ContainerKey map, MapValue map)])
    -> map
    -> [[(ContainerKey map, MapValue map)]]
    forall b c a. (b -> c) -> (a -> b) -> a -> c
    . map -> [(ContainerKey map, MapValue map)]
    forall map. IsMap map => map -> [(ContainerKey map, MapValue map)]
    mapToList
          where
            go :: (ContainerKey map, MapValue map)
    -> [(ContainerKey map, MapValue map)]
    go (ContainerKey map
    k, MapValue map
    v) = [(ContainerKey map -> ContainerKey map
    f ContainerKey map
    k, MapValue map
    v)]

        -- | Filter values in a map.
        --
        -- @since 1.0.9.0
        filterMap :: (MapValue map -> Bool) -> map -> map
        filterMap = (ContainerKey map -> MapValue map -> Bool) -> map -> map
    forall map.
    IsMap map =>
    (ContainerKey map -> MapValue map -> Bool) -> map -> map
    filterWithKey ((ContainerKey map -> MapValue map -> Bool) -> map -> map)
    -> ((MapValue map -> Bool)
        -> ContainerKey map -> MapValue map -> Bool)
    -> (MapValue map -> Bool)
    -> map
    -> map
    forall b c a. (b -> c) -> (a -> b) -> a -> c
    . (MapValue map -> Bool) -> ContainerKey map -> MapValue map -> Bool
    forall a b. a -> b -> a
    const

        -- | Equivalent to 'filterMap', but the function accepts the key,
        -- as well as the value.
        --
        -- @since 1.0.19.0
        filterWithKey :: (ContainerKey map -> MapValue map -> Bool) -> map -> map
        filterWithKey ContainerKey map -> MapValue map -> Bool
    p = [(ContainerKey map, MapValue map)] -> map
    forall map. IsMap map => [(ContainerKey map, MapValue map)] -> map
    mapFromList ([(ContainerKey map, MapValue map)] -> map)
    -> (map -> [(ContainerKey map, MapValue map)]) -> map -> map
    forall b c a. (b -> c) -> (a -> b) -> a -> c
    . ((ContainerKey map, MapValue map) -> Bool)
    -> [(ContainerKey map, MapValue map)]
    -> [(ContainerKey map, MapValue map)]
    forall a. (a -> Bool) -> [a] -> [a]
    filter ((ContainerKey map -> MapValue map -> Bool)
    -> (ContainerKey map, MapValue map) -> Bool
    forall a b c. (a -> b -> c) -> (a, b) -> c
    uncurry ContainerKey map -> MapValue map -> Bool
    p) ([(ContainerKey map, MapValue map)]
     -> [(ContainerKey map, MapValue map)])
    -> (map -> [(ContainerKey map, MapValue map)])
    -> map
    -> [(ContainerKey map, MapValue map)]
    forall b c a. (b -> c) -> (a -> b) -> a -> c
    . map -> [(ContainerKey map, MapValue map)]
    forall map. IsMap map => map -> [(ContainerKey map, MapValue map)]
    mapToList

    -- | This instance uses the functions from "Data.Map.Strict".
    instance Ord key => IsMap (Map.Map key value) where
        type MapValue (Map.Map key value) = value
        lookup :: ContainerKey (Map key value)
    -> Map key value -> Maybe (MapValue (Map key value))
    lookup = key -> Map key value -> Maybe value
    ContainerKey (Map key value)
    -> Map key value -> Maybe (MapValue (Map key value))
    forall k a. Ord k => k -> Map k a -> Maybe a
    Map.lookup
        {-# INLINE lookup #-}
        insertMap :: ContainerKey (Map key value)
    -> MapValue (Map key value) -> Map key value -> Map key value
    insertMap = key -> value -> Map key value -> Map key value
    ContainerKey (Map key value)
    -> MapValue (Map key value) -> Map key value -> Map key value
    forall k a. Ord k => k -> a -> Map k a -> Map k a
    Map.insert
        {-# INLINE insertMap #-}
        deleteMap :: ContainerKey (Map key value) -> Map key value -> Map key value
    deleteMap = key -> Map key value -> Map key value
    ContainerKey (Map key value) -> Map key value -> Map key value
    forall k a. Ord k => k -> Map k a -> Map k a
    Map.delete
        {-# INLINE deleteMap #-}
        singletonMap :: ContainerKey (Map key value)
    -> MapValue (Map key value) -> Map key value
    singletonMap = key -> value -> Map key value
    ContainerKey (Map key value)
    -> MapValue (Map key value) -> Map key value
    forall k a. k -> a -> Map k a
    Map.singleton
        {-# INLINE singletonMap #-}
        mapFromList :: [(ContainerKey (Map key value), MapValue (Map key value))]
    -> Map key value
    mapFromList = [(key, value)] -> Map key value
    [(ContainerKey (Map key value), MapValue (Map key value))]
    -> Map key value
    forall k a. Ord k => [(k, a)] -> Map k a
    Map.fromList
        {-# INLINE mapFromList #-}
        mapToList :: Map key value
    -> [(ContainerKey (Map key value), MapValue (Map key value))]
    mapToList = Map key value -> [(key, value)]
    Map key value
    -> [(ContainerKey (Map key value), MapValue (Map key value))]
    forall k a. Map k a -> [(k, a)]
    Map.toList
        {-# INLINE mapToList #-}

        findWithDefault :: MapValue (Map key value)
    -> ContainerKey (Map key value)
    -> Map key value
    -> MapValue (Map key value)
    findWithDefault = value -> key -> Map key value -> value
    MapValue (Map key value)
    -> ContainerKey (Map key value)
    -> Map key value
    -> MapValue (Map key value)
    forall k a. Ord k => a -> k -> Map k a -> a
    Map.findWithDefault
        {-# INLINE findWithDefault #-}
        insertWith :: (MapValue (Map key value)
     -> MapValue (Map key value) -> MapValue (Map key value))
    -> ContainerKey (Map key value)
    -> MapValue (Map key value)
    -> Map key value
    -> Map key value
    insertWith = (value -> value -> value)
    -> key -> value -> Map key value -> Map key value
    (MapValue (Map key value)
     -> MapValue (Map key value) -> MapValue (Map key value))
    -> ContainerKey (Map key value)
    -> MapValue (Map key value)
    -> Map key value
    -> Map key value
    forall k a. Ord k => (a -> a -> a) -> k -> a -> Map k a -> Map k a
    Map.insertWith
        {-# INLINE insertWith #-}
        insertWithKey :: (ContainerKey (Map key value)
     -> MapValue (Map key value)
     -> MapValue (Map key value)
     -> MapValue (Map key value))
    -> ContainerKey (Map key value)
    -> MapValue (Map key value)
    -> Map key value
    -> Map key value
    insertWithKey = (key -> value -> value -> value)
    -> key -> value -> Map key value -> Map key value
    (ContainerKey (Map key value)
     -> MapValue (Map key value)
     -> MapValue (Map key value)
     -> MapValue (Map key value))
    -> ContainerKey (Map key value)
    -> MapValue (Map key value)
    -> Map key value
    -> Map key value
    forall k a.
    Ord k =>
    (k -> a -> a -> a) -> k -> a -> Map k a -> Map k a
    Map.insertWithKey
        {-# INLINE insertWithKey #-}
        insertLookupWithKey :: (ContainerKey (Map key value)
     -> MapValue (Map key value)
     -> MapValue (Map key value)
     -> MapValue (Map key value))
    -> ContainerKey (Map key value)
    -> MapValue (Map key value)
    -> Map key value
    -> (Maybe (MapValue (Map key value)), Map key value)
    insertLookupWithKey = (key -> value -> value -> value)
    -> key -> value -> Map key value -> (Maybe value, Map key value)
    (ContainerKey (Map key value)
     -> MapValue (Map key value)
     -> MapValue (Map key value)
     -> MapValue (Map key value))
    -> ContainerKey (Map key value)
    -> MapValue (Map key value)
    -> Map key value
    -> (Maybe (MapValue (Map key value)), Map key value)
    forall k a.
    Ord k =>
    (k -> a -> a -> a) -> k -> a -> Map k a -> (Maybe a, Map k a)
    Map.insertLookupWithKey
        {-# INLINE insertLookupWithKey #-}
        adjustMap :: (MapValue (Map key value) -> MapValue (Map key value))
    -> ContainerKey (Map key value) -> Map key value -> Map key value
    adjustMap = (value -> value) -> key -> Map key value -> Map key value
    (MapValue (Map key value) -> MapValue (Map key value))
    -> ContainerKey (Map key value) -> Map key value -> Map key value
    forall k a. Ord k => (a -> a) -> k -> Map k a -> Map k a
    Map.adjust
        {-# INLINE adjustMap #-}
        adjustWithKey :: (ContainerKey (Map key value)
     -> MapValue (Map key value) -> MapValue (Map key value))
    -> ContainerKey (Map key value) -> Map key value -> Map key value
    adjustWithKey = (key -> value -> value) -> key -> Map key value -> Map key value
    (ContainerKey (Map key value)
     -> MapValue (Map key value) -> MapValue (Map key value))
    -> ContainerKey (Map key value) -> Map key value -> Map key value
    forall k a. Ord k => (k -> a -> a) -> k -> Map k a -> Map k a
    Map.adjustWithKey
        {-# INLINE adjustWithKey #-}
        updateMap :: (MapValue (Map key value) -> Maybe (MapValue (Map key value)))
    -> ContainerKey (Map key value) -> Map key value -> Map key value
    updateMap = (value -> Maybe value) -> key -> Map key value -> Map key value
    (MapValue (Map key value) -> Maybe (MapValue (Map key value)))
    -> ContainerKey (Map key value) -> Map key value -> Map key value
    forall k a. Ord k => (a -> Maybe a) -> k -> Map k a -> Map k a
    Map.update
        {-# INLINE updateMap #-}
        updateWithKey :: (ContainerKey (Map key value)
     -> MapValue (Map key value) -> Maybe (MapValue (Map key value)))
    -> ContainerKey (Map key value) -> Map key value -> Map key value
    updateWithKey = (key -> value -> Maybe value)
    -> key -> Map key value -> Map key value
    (ContainerKey (Map key value)
     -> MapValue (Map key value) -> Maybe (MapValue (Map key value)))
    -> ContainerKey (Map key value) -> Map key value -> Map key value
    forall k a. Ord k => (k -> a -> Maybe a) -> k -> Map k a -> Map k a
    Map.updateWithKey
        {-# INLINE updateWithKey #-}
        updateLookupWithKey :: (ContainerKey (Map key value)
     -> MapValue (Map key value) -> Maybe (MapValue (Map key value)))
    -> ContainerKey (Map key value)
    -> Map key value
    -> (Maybe (MapValue (Map key value)), Map key value)
    updateLookupWithKey = (key -> value -> Maybe value)
    -> key -> Map key value -> (Maybe value, Map key value)
    (ContainerKey (Map key value)
     -> MapValue (Map key value) -> Maybe (MapValue (Map key value)))
    -> ContainerKey (Map key value)
    -> Map key value
    -> (Maybe (MapValue (Map key value)), Map key value)
    forall k a.
    Ord k =>
    (k -> a -> Maybe a) -> k -> Map k a -> (Maybe a, Map k a)
    Map.updateLookupWithKey
        {-# INLINE updateLookupWithKey #-}
        alterMap :: (Maybe (MapValue (Map key value))
     -> Maybe (MapValue (Map key value)))
    -> ContainerKey (Map key value) -> Map key value -> Map key value
    alterMap = (Maybe value -> Maybe value)
    -> key -> Map key value -> Map key value
    (Maybe (MapValue (Map key value))
     -> Maybe (MapValue (Map key value)))
    -> ContainerKey (Map key value) -> Map key value -> Map key value
    forall k a.
    Ord k =>
    (Maybe a -> Maybe a) -> k -> Map k a -> Map k a
    Map.alter
        {-# INLINE alterMap #-}
        unionWith :: (MapValue (Map key value)
     -> MapValue (Map key value) -> MapValue (Map key value))
    -> Map key value -> Map key value -> Map key value
    unionWith = (value -> value -> value)
    -> Map key value -> Map key value -> Map key value
    (MapValue (Map key value)
     -> MapValue (Map key value) -> MapValue (Map key value))
    -> Map key value -> Map key value -> Map key value
    forall k a. Ord k => (a -> a -> a) -> Map k a -> Map k a -> Map k a
    Map.unionWith
        {-# INLINE unionWith #-}
        unionWithKey :: (ContainerKey (Map key value)
     -> MapValue (Map key value)
     -> MapValue (Map key value)
     -> MapValue (Map key value))
    -> Map key value -> Map key value -> Map key value
    unionWithKey = (key -> value -> value -> value)
    -> Map key value -> Map key value -> Map key value
    (ContainerKey (Map key value)
     -> MapValue (Map key value)
     -> MapValue (Map key value)
     -> MapValue (Map key value))
    -> Map key value -> Map key value -> Map key value
    forall k a.
    Ord k =>
    (k -> a -> a -> a) -> Map k a -> Map k a -> Map k a
    Map.unionWithKey
        {-# INLINE unionWithKey #-}
        unionsWith :: (MapValue (Map key value)
     -> MapValue (Map key value) -> MapValue (Map key value))
    -> [Map key value] -> Map key value
    unionsWith = (value -> value -> value) -> [Map key value] -> Map key value
    (MapValue (Map key value)
     -> MapValue (Map key value) -> MapValue (Map key value))
    -> [Map key value] -> Map key value
    forall (f :: * -> *) k a.
    (Foldable f, Ord k) =>
    (a -> a -> a) -> f (Map k a) -> Map k a
    Map.unionsWith
        {-# INLINE unionsWith #-}
        mapWithKey :: (ContainerKey (Map key value)
     -> MapValue (Map key value) -> MapValue (Map key value))
    -> Map key value -> Map key value
    mapWithKey = (key -> value -> value) -> Map key value -> Map key value
    (ContainerKey (Map key value)
     -> MapValue (Map key value) -> MapValue (Map key value))
    -> Map key value -> Map key value
    forall k a b. (k -> a -> b) -> Map k a -> Map k b
    Map.mapWithKey
        {-# INLINE mapWithKey #-}
        omapKeysWith :: (MapValue (Map key value)
     -> MapValue (Map key value) -> MapValue (Map key value))
    -> (ContainerKey (Map key value) -> ContainerKey (Map key value))
    -> Map key value
    -> Map key value
    omapKeysWith = (value -> value -> value)
    -> (key -> key) -> Map key value -> Map key value
    (MapValue (Map key value)
     -> MapValue (Map key value) -> MapValue (Map key value))
    -> (ContainerKey (Map key value) -> ContainerKey (Map key value))
    -> Map key value
    -> Map key value
    forall k2 a k1.
    Ord k2 =>
    (a -> a -> a) -> (k1 -> k2) -> Map k1 a -> Map k2 a
    Map.mapKeysWith
        {-# INLINE omapKeysWith #-}
        filterMap :: (MapValue (Map key value) -> Bool)
    -> Map key value -> Map key value
    filterMap = (value -> Bool) -> Map key value -> Map key value
    (MapValue (Map key value) -> Bool)
    -> Map key value -> Map key value
    forall a k. (a -> Bool) -> Map k a -> Map k a
    Map.filter
        {-# INLINE filterMap #-}
        filterWithKey :: (ContainerKey (Map key value) -> MapValue (Map key value) -> Bool)
    -> Map key value -> Map key value
    filterWithKey = (key -> value -> Bool) -> Map key value -> Map key value
    (ContainerKey (Map key value) -> MapValue (Map key value) -> Bool)
    -> Map key value -> Map key value
    forall k a. (k -> a -> Bool) -> Map k a -> Map k a
    Map.filterWithKey
        {-# INLINE filterWithKey #-}

    -- | This instance uses the functions from "Data.HashMap.Strict".
    instance (Eq key, Hashable key) => IsMap (HashMap.HashMap key value) where
        type MapValue (HashMap.HashMap key value) = value
        lookup :: ContainerKey (HashMap key value)
    -> HashMap key value -> Maybe (MapValue (HashMap key value))
    lookup = key -> HashMap key value -> Maybe value
    ContainerKey (HashMap key value)
    -> HashMap key value -> Maybe (MapValue (HashMap key value))
    forall k v. (Eq k, Hashable k) => k -> HashMap k v -> Maybe v
    HashMap.lookup
        {-# INLINE lookup #-}
        insertMap :: ContainerKey (HashMap key value)
    -> MapValue (HashMap key value)
    -> HashMap key value
    -> HashMap key value
    insertMap = key -> value -> HashMap key value -> HashMap key value
    ContainerKey (HashMap key value)
    -> MapValue (HashMap key value)
    -> HashMap key value
    -> HashMap key value
    forall k v.
    (Eq k, Hashable k) =>
    k -> v -> HashMap k v -> HashMap k v
    HashMap.insert
        {-# INLINE insertMap #-}
        deleteMap :: ContainerKey (HashMap key value)
    -> HashMap key value -> HashMap key value
    deleteMap = key -> HashMap key value -> HashMap key value
    ContainerKey (HashMap key value)
    -> HashMap key value -> HashMap key value
    forall k v. (Eq k, Hashable k) => k -> HashMap k v -> HashMap k v
    HashMap.delete
        {-# INLINE deleteMap #-}
        singletonMap :: ContainerKey (HashMap key value)
    -> MapValue (HashMap key value) -> HashMap key value
    singletonMap = key -> value -> HashMap key value
    ContainerKey (HashMap key value)
    -> MapValue (HashMap key value) -> HashMap key value
    forall k v. Hashable k => k -> v -> HashMap k v
    HashMap.singleton
        {-# INLINE singletonMap #-}
        mapFromList :: [(ContainerKey (HashMap key value), MapValue (HashMap key value))]
    -> HashMap key value
    mapFromList = [(key, value)] -> HashMap key value
    [(ContainerKey (HashMap key value), MapValue (HashMap key value))]
    -> HashMap key value
    forall k v. (Eq k, Hashable k) => [(k, v)] -> HashMap k v
    HashMap.fromList
        {-# INLINE mapFromList #-}
        mapToList :: HashMap key value
    -> [(ContainerKey (HashMap key value),
         MapValue (HashMap key value))]
    mapToList = HashMap key value -> [(key, value)]
    HashMap key value
    -> [(ContainerKey (HashMap key value),
         MapValue (HashMap key value))]
    forall k v. HashMap k v -> [(k, v)]
    HashMap.toList
        {-# INLINE mapToList #-}

        --findWithDefault = HashMap.findWithDefault
        insertWith :: (MapValue (HashMap key value)
     -> MapValue (HashMap key value) -> MapValue (HashMap key value))
    -> ContainerKey (HashMap key value)
    -> MapValue (HashMap key value)
    -> HashMap key value
    -> HashMap key value
    insertWith = (value -> value -> value)
    -> key -> value -> HashMap key value -> HashMap key value
    (MapValue (HashMap key value)
     -> MapValue (HashMap key value) -> MapValue (HashMap key value))
    -> ContainerKey (HashMap key value)
    -> MapValue (HashMap key value)
    -> HashMap key value
    -> HashMap key value
    forall k v.
    (Eq k, Hashable k) =>
    (v -> v -> v) -> k -> v -> HashMap k v -> HashMap k v
    HashMap.insertWith
        {-# INLINE insertWith #-}
        --insertWithKey = HashMap.insertWithKey
        --insertLookupWithKey = HashMap.insertLookupWithKey
        adjustMap :: (MapValue (HashMap key value) -> MapValue (HashMap key value))
    -> ContainerKey (HashMap key value)
    -> HashMap key value
    -> HashMap key value
    adjustMap = (value -> value) -> key -> HashMap key value -> HashMap key value
    (MapValue (HashMap key value) -> MapValue (HashMap key value))
    -> ContainerKey (HashMap key value)
    -> HashMap key value
    -> HashMap key value
    forall k v.
    (Eq k, Hashable k) =>
    (v -> v) -> k -> HashMap k v -> HashMap k v
    HashMap.adjust
        {-# INLINE adjustMap #-}
        --adjustWithKey = HashMap.adjustWithKey
        --updateMap = HashMap.update
        --updateWithKey = HashMap.updateWithKey
        --updateLookupWithKey = HashMap.updateLookupWithKey
        --alterMap = HashMap.alter
        unionWith :: (MapValue (HashMap key value)
     -> MapValue (HashMap key value) -> MapValue (HashMap key value))
    -> HashMap key value -> HashMap key value -> HashMap key value
    unionWith = (value -> value -> value)
    -> HashMap key value -> HashMap key value -> HashMap key value
    (MapValue (HashMap key value)
     -> MapValue (HashMap key value) -> MapValue (HashMap key value))
    -> HashMap key value -> HashMap key value -> HashMap key value
    forall k v.
    Eq k =>
    (v -> v -> v) -> HashMap k v -> HashMap k v -> HashMap k v
    HashMap.unionWith
        {-# INLINE unionWith #-}
        --unionWithKey = HashMap.unionWithKey
        --unionsWith = HashMap.unionsWith
        --mapWithKey = HashMap.mapWithKey
        --mapKeysWith = HashMap.mapKeysWith
        filterMap :: (MapValue (HashMap key value) -> Bool)
    -> HashMap key value -> HashMap key value
    filterMap = (value -> Bool) -> HashMap key value -> HashMap key value
    (MapValue (HashMap key value) -> Bool)
    -> HashMap key value -> HashMap key value
    forall v k. (v -> Bool) -> HashMap k v -> HashMap k v
    HashMap.filter
        {-# INLINE filterMap #-}
        filterWithKey :: (ContainerKey (HashMap key value)
     -> MapValue (HashMap key value) -> Bool)
    -> HashMap key value -> HashMap key value
    filterWithKey = (key -> value -> Bool) -> HashMap key value -> HashMap key value
    (ContainerKey (HashMap key value)
     -> MapValue (HashMap key value) -> Bool)
    -> HashMap key value -> HashMap key value
    forall k v. (k -> v -> Bool) -> HashMap k v -> HashMap k v
    HashMap.filterWithKey
        {-# INLINE filterWithKey #-}

    -- | This instance uses the functions from "Data.IntMap.Strict".
    instance IsMap (IntMap.IntMap value) where
        type MapValue (IntMap.IntMap value) = value
        lookup :: ContainerKey (IntMap value)
    -> IntMap value -> Maybe (MapValue (IntMap value))
    lookup = Int -> IntMap value -> Maybe value
    ContainerKey (IntMap value)
    -> IntMap value -> Maybe (MapValue (IntMap value))
    forall a. Int -> IntMap a -> Maybe a
    IntMap.lookup
        {-# INLINE lookup #-}
        insertMap :: ContainerKey (IntMap value)
    -> MapValue (IntMap value) -> IntMap value -> IntMap value
    insertMap = Int -> value -> IntMap value -> IntMap value
    ContainerKey (IntMap value)
    -> MapValue (IntMap value) -> IntMap value -> IntMap value
    forall a. Int -> a -> IntMap a -> IntMap a
    IntMap.insert
        {-# INLINE insertMap #-}
        deleteMap :: ContainerKey (IntMap value) -> IntMap value -> IntMap value
    deleteMap = Int -> IntMap value -> IntMap value
    ContainerKey (IntMap value) -> IntMap value -> IntMap value
    forall a. Int -> IntMap a -> IntMap a
    IntMap.delete
        {-# INLINE deleteMap #-}
        singletonMap :: ContainerKey (IntMap value)
    -> MapValue (IntMap value) -> IntMap value
    singletonMap = Int -> value -> IntMap value
    ContainerKey (IntMap value)
    -> MapValue (IntMap value) -> IntMap value
    forall a. Int -> a -> IntMap a
    IntMap.singleton
        {-# INLINE singletonMap #-}
        mapFromList :: [(ContainerKey (IntMap value), MapValue (IntMap value))]
    -> IntMap value
    mapFromList = [(Int, value)] -> IntMap value
    [(ContainerKey (IntMap value), MapValue (IntMap value))]
    -> IntMap value
    forall a. [(Int, a)] -> IntMap a
    IntMap.fromList
        {-# INLINE mapFromList #-}
        mapToList :: IntMap value
    -> [(ContainerKey (IntMap value), MapValue (IntMap value))]
    mapToList = IntMap value -> [(Int, value)]
    IntMap value
    -> [(ContainerKey (IntMap value), MapValue (IntMap value))]
    forall a. IntMap a -> [(Int, a)]
    IntMap.toList
        {-# INLINE mapToList #-}

        findWithDefault :: MapValue (IntMap value)
    -> ContainerKey (IntMap value)
    -> IntMap value
    -> MapValue (IntMap value)
    findWithDefault = value -> Int -> IntMap value -> value
    MapValue (IntMap value)
    -> ContainerKey (IntMap value)
    -> IntMap value
    -> MapValue (IntMap value)
    forall a. a -> Int -> IntMap a -> a
    IntMap.findWithDefault
        {-# INLINE findWithDefault #-}
        insertWith :: (MapValue (IntMap value)
     -> MapValue (IntMap value) -> MapValue (IntMap value))
    -> ContainerKey (IntMap value)
    -> MapValue (IntMap value)
    -> IntMap value
    -> IntMap value
    insertWith = (value -> value -> value)
    -> Int -> value -> IntMap value -> IntMap value
    (MapValue (IntMap value)
     -> MapValue (IntMap value) -> MapValue (IntMap value))
    -> ContainerKey (IntMap value)
    -> MapValue (IntMap value)
    -> IntMap value
    -> IntMap value
    forall a. (a -> a -> a) -> Int -> a -> IntMap a -> IntMap a
    IntMap.insertWith
        {-# INLINE insertWith #-}
        insertWithKey :: (ContainerKey (IntMap value)
     -> MapValue (IntMap value)
     -> MapValue (IntMap value)
     -> MapValue (IntMap value))
    -> ContainerKey (IntMap value)
    -> MapValue (IntMap value)
    -> IntMap value
    -> IntMap value
    insertWithKey = (Int -> value -> value -> value)
    -> Int -> value -> IntMap value -> IntMap value
    (ContainerKey (IntMap value)
     -> MapValue (IntMap value)
     -> MapValue (IntMap value)
     -> MapValue (IntMap value))
    -> ContainerKey (IntMap value)
    -> MapValue (IntMap value)
    -> IntMap value
    -> IntMap value
    forall a. (Int -> a -> a -> a) -> Int -> a -> IntMap a -> IntMap a
    IntMap.insertWithKey
        {-# INLINE insertWithKey #-}
        insertLookupWithKey :: (ContainerKey (IntMap value)
     -> MapValue (IntMap value)
     -> MapValue (IntMap value)
     -> MapValue (IntMap value))
    -> ContainerKey (IntMap value)
    -> MapValue (IntMap value)
    -> IntMap value
    -> (Maybe (MapValue (IntMap value)), IntMap value)
    insertLookupWithKey = (Int -> value -> value -> value)
    -> Int -> value -> IntMap value -> (Maybe value, IntMap value)
    (ContainerKey (IntMap value)
     -> MapValue (IntMap value)
     -> MapValue (IntMap value)
     -> MapValue (IntMap value))
    -> ContainerKey (IntMap value)
    -> MapValue (IntMap value)
    -> IntMap value
    -> (Maybe (MapValue (IntMap value)), IntMap value)
    forall a.
    (Int -> a -> a -> a) -> Int -> a -> IntMap a -> (Maybe a, IntMap a)
    IntMap.insertLookupWithKey
        {-# INLINE insertLookupWithKey #-}
        adjustMap :: (MapValue (IntMap value) -> MapValue (IntMap value))
    -> ContainerKey (IntMap value) -> IntMap value -> IntMap value
    adjustMap = (value -> value) -> Int -> IntMap value -> IntMap value
    (MapValue (IntMap value) -> MapValue (IntMap value))
    -> ContainerKey (IntMap value) -> IntMap value -> IntMap value
    forall a. (a -> a) -> Int -> IntMap a -> IntMap a
    IntMap.adjust
        {-# INLINE adjustMap #-}
        adjustWithKey :: (ContainerKey (IntMap value)
     -> MapValue (IntMap value) -> MapValue (IntMap value))
    -> ContainerKey (IntMap value) -> IntMap value -> IntMap value
    adjustWithKey = (Int -> value -> value) -> Int -> IntMap value -> IntMap value
    (ContainerKey (IntMap value)
     -> MapValue (IntMap value) -> MapValue (IntMap value))
    -> ContainerKey (IntMap value) -> IntMap value -> IntMap value
    forall a. (Int -> a -> a) -> Int -> IntMap a -> IntMap a
    IntMap.adjustWithKey
        {-# INLINE adjustWithKey #-}
        updateMap :: (MapValue (IntMap value) -> Maybe (MapValue (IntMap value)))
    -> ContainerKey (IntMap value) -> IntMap value -> IntMap value
    updateMap = (value -> Maybe value) -> Int -> IntMap value -> IntMap value
    (MapValue (IntMap value) -> Maybe (MapValue (IntMap value)))
    -> ContainerKey (IntMap value) -> IntMap value -> IntMap value
    forall a. (a -> Maybe a) -> Int -> IntMap a -> IntMap a
    IntMap.update
        {-# INLINE updateMap #-}
        updateWithKey :: (ContainerKey (IntMap value)
     -> MapValue (IntMap value) -> Maybe (MapValue (IntMap value)))
    -> ContainerKey (IntMap value) -> IntMap value -> IntMap value
    updateWithKey = (Int -> value -> Maybe value)
    -> Int -> IntMap value -> IntMap value
    (ContainerKey (IntMap value)
     -> MapValue (IntMap value) -> Maybe (MapValue (IntMap value)))
    -> ContainerKey (IntMap value) -> IntMap value -> IntMap value
    forall a. (Int -> a -> Maybe a) -> Int -> IntMap a -> IntMap a
    IntMap.updateWithKey
        {-# INLINE updateWithKey #-}
        --updateLookupWithKey = IntMap.updateLookupWithKey
        alterMap :: (Maybe (MapValue (IntMap value))
     -> Maybe (MapValue (IntMap value)))
    -> ContainerKey (IntMap value) -> IntMap value -> IntMap value
    alterMap = (Maybe value -> Maybe value) -> Int -> IntMap value -> IntMap value
    (Maybe (MapValue (IntMap value))
     -> Maybe (MapValue (IntMap value)))
    -> ContainerKey (IntMap value) -> IntMap value -> IntMap value
    forall a. (Maybe a -> Maybe a) -> Int -> IntMap a -> IntMap a
    IntMap.alter
        {-# INLINE alterMap #-}
        unionWith :: (MapValue (IntMap value)
     -> MapValue (IntMap value) -> MapValue (IntMap value))
    -> IntMap value -> IntMap value -> IntMap value
    unionWith = (value -> value -> value)
    -> IntMap value -> IntMap value -> IntMap value
    (MapValue (IntMap value)
     -> MapValue (IntMap value) -> MapValue (IntMap value))
    -> IntMap value -> IntMap value -> IntMap value
    forall a. (a -> a -> a) -> IntMap a -> IntMap a -> IntMap a
    IntMap.unionWith
        {-# INLINE unionWith #-}
        unionWithKey :: (ContainerKey (IntMap value)
     -> MapValue (IntMap value)
     -> MapValue (IntMap value)
     -> MapValue (IntMap value))
    -> IntMap value -> IntMap value -> IntMap value
    unionWithKey = (Int -> value -> value -> value)
    -> IntMap value -> IntMap value -> IntMap value
    (ContainerKey (IntMap value)
     -> MapValue (IntMap value)
     -> MapValue (IntMap value)
     -> MapValue (IntMap value))
    -> IntMap value -> IntMap value -> IntMap value
    forall a. (Int -> a -> a -> a) -> IntMap a -> IntMap a -> IntMap a
    IntMap.unionWithKey
        {-# INLINE unionWithKey #-}
        unionsWith :: (MapValue (IntMap value)
     -> MapValue (IntMap value) -> MapValue (IntMap value))
    -> [IntMap value] -> IntMap value
    unionsWith = (value -> value -> value) -> [IntMap value] -> IntMap value
    (MapValue (IntMap value)
     -> MapValue (IntMap value) -> MapValue (IntMap value))
    -> [IntMap value] -> IntMap value
    forall (f :: * -> *) a.
    Foldable f =>
    (a -> a -> a) -> f (IntMap a) -> IntMap a
    IntMap.unionsWith
        {-# INLINE unionsWith #-}
        mapWithKey :: (ContainerKey (IntMap value)
     -> MapValue (IntMap value) -> MapValue (IntMap value))
    -> IntMap value -> IntMap value
    mapWithKey = (Int -> value -> value) -> IntMap value -> IntMap value
    (ContainerKey (IntMap value)
     -> MapValue (IntMap value) -> MapValue (IntMap value))
    -> IntMap value -> IntMap value
    forall a b. (Int -> a -> b) -> IntMap a -> IntMap b
    IntMap.mapWithKey
        {-# INLINE mapWithKey #-}
        omapKeysWith :: (MapValue (IntMap value)
     -> MapValue (IntMap value) -> MapValue (IntMap value))
    -> (ContainerKey (IntMap value) -> ContainerKey (IntMap value))
    -> IntMap value
    -> IntMap value
    omapKeysWith = (value -> value -> value)
    -> (Int -> Int) -> IntMap value -> IntMap value
    (MapValue (IntMap value)
     -> MapValue (IntMap value) -> MapValue (IntMap value))
    -> (ContainerKey (IntMap value) -> ContainerKey (IntMap value))
    -> IntMap value
    -> IntMap value
    forall a. (a -> a -> a) -> (Int -> Int) -> IntMap a -> IntMap a
    IntMap.mapKeysWith
        {-# INLINE omapKeysWith #-}
        filterMap :: (MapValue (IntMap value) -> Bool) -> IntMap value -> IntMap value
    filterMap = (value -> Bool) -> IntMap value -> IntMap value
    (MapValue (IntMap value) -> Bool) -> IntMap value -> IntMap value
    forall a. (a -> Bool) -> IntMap a -> IntMap a
    IntMap.filter
        {-# INLINE filterMap #-}
        filterWithKey :: (ContainerKey (IntMap value) -> MapValue (IntMap value) -> Bool)
    -> IntMap value -> IntMap value
    filterWithKey = (Int -> value -> Bool) -> IntMap value -> IntMap value
    (ContainerKey (IntMap value) -> MapValue (IntMap value) -> Bool)
    -> IntMap value -> IntMap value
    forall a. (Int -> a -> Bool) -> IntMap a -> IntMap a
    IntMap.filterWithKey
        {-# INLINE filterWithKey #-}

    instance Eq key => IsMap [(key, value)] where
        type MapValue [(key, value)] = value
        lookup :: ContainerKey [(key, value)]
    -> [(key, value)] -> Maybe (MapValue [(key, value)])
    lookup = key -> [(key, value)] -> Maybe value
    ContainerKey [(key, value)]
    -> [(key, value)] -> Maybe (MapValue [(key, value)])
    forall a b. Eq a => a -> [(a, b)] -> Maybe b
    List.lookup
        {-# INLINE lookup #-}
        insertMap :: ContainerKey [(key, value)]
    -> MapValue [(key, value)] -> [(key, value)] -> [(key, value)]
    insertMap ContainerKey [(key, value)]
    k MapValue [(key, value)]
    v = ((key
    ContainerKey [(key, value)]
    k, value
    MapValue [(key, value)]
    v)(key, value) -> [(key, value)] -> [(key, value)]
    forall a. a -> [a] -> [a]
    :) ([(key, value)] -> [(key, value)])
    -> ([(key, value)] -> [(key, value)])
    -> [(key, value)]
    -> [(key, value)]
    forall b c a. (b -> c) -> (a -> b) -> a -> c
    . ContainerKey [(key, value)] -> [(key, value)] -> [(key, value)]
    forall map. IsMap map => ContainerKey map -> map -> map
    deleteMap ContainerKey [(key, value)]
    k
        {-# INLINE insertMap #-}
        deleteMap :: ContainerKey [(key, value)] -> [(key, value)] -> [(key, value)]
    deleteMap ContainerKey [(key, value)]
    k = ((key, value) -> Bool) -> [(key, value)] -> [(key, value)]
    forall a. (a -> Bool) -> [a] -> [a]
    List.filter ((ContainerKey [(key, value)] -> ContainerKey [(key, value)] -> Bool
    forall a. Eq a => a -> a -> Bool
    /= ContainerKey [(key, value)]
    k) (key -> Bool) -> ((key, value) -> key) -> (key, value) -> Bool
    forall b c a. (b -> c) -> (a -> b) -> a -> c
    . (key, value) -> key
    forall a b. (a, b) -> a
    fst)
        {-# INLINE deleteMap #-}
        singletonMap :: ContainerKey [(key, value)]
    -> MapValue [(key, value)] -> [(key, value)]
    singletonMap ContainerKey [(key, value)]
    k MapValue [(key, value)]
    v = [(key
    ContainerKey [(key, value)]
    k, value
    MapValue [(key, value)]
    v)]
        {-# INLINE singletonMap #-}
        mapFromList :: [(ContainerKey [(key, value)], MapValue [(key, value)])]
    -> [(key, value)]
    mapFromList = [(key, value)] -> [(key, value)]
    [(ContainerKey [(key, value)], MapValue [(key, value)])]
    -> [(key, value)]
    forall a. a -> a
    id
        {-# INLINE mapFromList #-}
        mapToList :: [(key, value)]
    -> [(ContainerKey [(key, value)], MapValue [(key, value)])]
    mapToList = [(key, value)] -> [(key, value)]
    [(key, value)]
    -> [(ContainerKey [(key, value)], MapValue [(key, value)])]
    forall a. a -> a
    id
        {-# INLINE mapToList #-}

    -- | Polymorphic typeclass for interacting with different set types
    class (SetContainer set, Element set ~ ContainerKey set) => IsSet set where
        -- | Insert a value into a set.
        insertSet :: Element set -> set -> set

        -- | Delete a value from a set.
        deleteSet :: Element set -> set -> set

        -- | Create a set from a single element.
        singletonSet :: Element set -> set

        -- | Convert a list to a set.
        setFromList :: [Element set] -> set

        -- | Convert a set to a list.
        setToList :: set -> [Element set]

        -- | Filter values in a set.
        --
        -- @since 1.0.12.0
        filterSet :: (Element set -> Bool) -> set -> set
        filterSet Element set -> Bool
    p = [Element set] -> set
    [ContainerKey set] -> set
    forall set. IsSet set => [Element set] -> set
    setFromList ([ContainerKey set] -> set)
    -> (set -> [ContainerKey set]) -> set -> set
    forall b c a. (b -> c) -> (a -> b) -> a -> c
    . (ContainerKey set -> Bool)
    -> [ContainerKey set] -> [ContainerKey set]
    forall a. (a -> Bool) -> [a] -> [a]
    filter Element set -> Bool
    ContainerKey set -> Bool
    p ([ContainerKey set] -> [ContainerKey set])
    -> (set -> [ContainerKey set]) -> set -> [ContainerKey set]
    forall b c a. (b -> c) -> (a -> b) -> a -> c
    . set -> [Element set]
    set -> [ContainerKey set]
    forall set. IsSet set => set -> [Element set]
    setToList

    instance Ord element => IsSet (Set.Set element) where
        insertSet :: Element (Set element) -> Set element -> Set element
    insertSet = element -> Set element -> Set element
    Element (Set element) -> Set element -> Set element
    forall a. Ord a => a -> Set a -> Set a
    Set.insert
        {-# INLINE insertSet #-}
        deleteSet :: Element (Set element) -> Set element -> Set element
    deleteSet = element -> Set element -> Set element
    Element (Set element) -> Set element -> Set element
    forall a. Ord a => a -> Set a -> Set a
    Set.delete
        {-# INLINE deleteSet #-}
        singletonSet :: Element (Set element) -> Set element
    singletonSet = element -> Set element
    Element (Set element) -> Set element
    forall a. a -> Set a
    Set.singleton
        {-# INLINE singletonSet #-}
        setFromList :: [Element (Set element)] -> Set element
    setFromList = [element] -> Set element
    [Element (Set element)] -> Set element
    forall a. Ord a => [a] -> Set a
    Set.fromList
        {-# INLINE setFromList #-}
        setToList :: Set element -> [Element (Set element)]
    setToList = Set element -> [element]
    Set element -> [Element (Set element)]
    forall a. Set a -> [a]
    Set.toList
        {-# INLINE setToList #-}
        filterSet :: (Element (Set element) -> Bool) -> Set element -> Set element
    filterSet = (element -> Bool) -> Set element -> Set element
    (Element (Set element) -> Bool) -> Set element -> Set element
    forall a. (a -> Bool) -> Set a -> Set a
    Set.filter
        {-# INLINE filterSet #-}

    instance (Eq element, Hashable element) => IsSet (HashSet.HashSet element) where
        insertSet :: Element (HashSet element) -> HashSet element -> HashSet element
    insertSet = element -> HashSet element -> HashSet element
    Element (HashSet element) -> HashSet element -> HashSet element
    forall a. (Eq a, Hashable a) => a -> HashSet a -> HashSet a
    HashSet.insert
        {-# INLINE insertSet #-}
        deleteSet :: Element (HashSet element) -> HashSet element -> HashSet element
    deleteSet = element -> HashSet element -> HashSet element
    Element (HashSet element) -> HashSet element -> HashSet element
    forall a. (Eq a, Hashable a) => a -> HashSet a -> HashSet a
    HashSet.delete
        {-# INLINE deleteSet #-}
        singletonSet :: Element (HashSet element) -> HashSet element
    singletonSet = element -> HashSet element
    Element (HashSet element) -> HashSet element
    forall a. Hashable a => a -> HashSet a
    HashSet.singleton
        {-# INLINE singletonSet #-}
        setFromList :: [Element (HashSet element)] -> HashSet element
    setFromList = [element] -> HashSet element
    [Element (HashSet element)] -> HashSet element
    forall a. (Eq a, Hashable a) => [a] -> HashSet a
    HashSet.fromList
        {-# INLINE setFromList #-}
        setToList :: HashSet element -> [Element (HashSet element)]
    setToList = HashSet element -> [element]
    HashSet element -> [Element (HashSet element)]
    forall a. HashSet a -> [a]
    HashSet.toList
        {-# INLINE setToList #-}
        filterSet :: (Element (HashSet element) -> Bool)
    -> HashSet element -> HashSet element
    filterSet = (element -> Bool) -> HashSet element -> HashSet element
    (Element (HashSet element) -> Bool)
    -> HashSet element -> HashSet element
    forall a. (a -> Bool) -> HashSet a -> HashSet a
    HashSet.filter
        {-# INLINE filterSet #-}

    instance IsSet IntSet.IntSet where
        insertSet :: Element IntSet -> IntSet -> IntSet
    insertSet = Int -> IntSet -> IntSet
    Element IntSet -> IntSet -> IntSet
    IntSet.insert
        {-# INLINE insertSet #-}
        deleteSet :: Element IntSet -> IntSet -> IntSet
    deleteSet = Int -> IntSet -> IntSet
    Element IntSet -> IntSet -> IntSet
    IntSet.delete
        {-# INLINE deleteSet #-}
        singletonSet :: Element IntSet -> IntSet
    singletonSet = Int -> IntSet
    Element IntSet -> IntSet
    IntSet.singleton
        {-# INLINE singletonSet #-}
        setFromList :: [Element IntSet] -> IntSet
    setFromList = [Int] -> IntSet
    [Element IntSet] -> IntSet
    IntSet.fromList
        {-# INLINE setFromList #-}
        setToList :: IntSet -> [Element IntSet]
    setToList = IntSet -> [Int]
    IntSet -> [Element IntSet]
    IntSet.toList
        {-# INLINE setToList #-}
        filterSet :: (Element IntSet -> Bool) -> IntSet -> IntSet
    filterSet = (Int -> Bool) -> IntSet -> IntSet
    (Element IntSet -> Bool) -> IntSet -> IntSet
    IntSet.filter
        {-# INLINE filterSet #-}

    -- | Zip operations on 'MonoFunctor's.
    class MonoFunctor mono => MonoZip mono where
        -- | Combine each element of two 'MonoZip's using a supplied function.
        ozipWith :: (Element mono -> Element mono -> Element mono) -> mono -> mono -> mono

        -- | Take two 'MonoZip's and return a list of the pairs of their elements.
        ozip :: mono -> mono -> [(Element mono, Element mono)]

        -- | Take a list of pairs of elements and return a 'MonoZip' of the first
        -- components and a 'MonoZip' of the second components.
        ounzip :: [(Element mono, Element mono)] -> (mono, mono)

    instance MonoZip ByteString.ByteString where
        ozip :: ByteString
    -> ByteString -> [(Element ByteString, Element ByteString)]
    ozip     = ByteString -> ByteString -> [(Word8, Word8)]
    ByteString
    -> ByteString -> [(Element ByteString, Element ByteString)]
    ByteString.zip
        ounzip :: [(Element ByteString, Element ByteString)]
    -> (ByteString, ByteString)
    ounzip   = [(Word8, Word8)] -> (ByteString, ByteString)
    [(Element ByteString, Element ByteString)]
    -> (ByteString, ByteString)
    ByteString.unzip
        ozipWith :: (Element ByteString -> Element ByteString -> Element ByteString)
    -> ByteString -> ByteString -> ByteString
    ozipWith Element ByteString -> Element ByteString -> Element ByteString
    f ByteString
    xs = [Word8] -> ByteString
    ByteString.pack ([Word8] -> ByteString)
    -> (ByteString -> [Word8]) -> ByteString -> ByteString
    forall b c a. (b -> c) -> (a -> b) -> a -> c
    . (Word8 -> Word8 -> Word8) -> ByteString -> ByteString -> [Word8]
    forall a. (Word8 -> Word8 -> a) -> ByteString -> ByteString -> [a]
    ByteString.zipWith Word8 -> Word8 -> Word8
    Element ByteString -> Element ByteString -> Element ByteString
    f ByteString
    xs
        {-# INLINE ozip #-}
        {-# INLINE ounzip #-}
        {-# INLINE ozipWith #-}
    instance MonoZip LByteString.ByteString where
        ozip :: ByteString
    -> ByteString -> [(Element ByteString, Element ByteString)]
    ozip     = ByteString -> ByteString -> [(Word8, Word8)]
    ByteString
    -> ByteString -> [(Element ByteString, Element ByteString)]
    LByteString.zip
        ounzip :: [(Element ByteString, Element ByteString)]
    -> (ByteString, ByteString)
    ounzip   = [(Word8, Word8)] -> (ByteString, ByteString)
    [(Element ByteString, Element ByteString)]
    -> (ByteString, ByteString)
    LByteString.unzip
        ozipWith :: (Element ByteString -> Element ByteString -> Element ByteString)
    -> ByteString -> ByteString -> ByteString
    ozipWith Element ByteString -> Element ByteString -> Element ByteString
    f ByteString
    xs = [Word8] -> ByteString
    LByteString.pack ([Word8] -> ByteString)
    -> (ByteString -> [Word8]) -> ByteString -> ByteString
    forall b c a. (b -> c) -> (a -> b) -> a -> c
    . (Word8 -> Word8 -> Word8) -> ByteString -> ByteString -> [Word8]
    forall a. (Word8 -> Word8 -> a) -> ByteString -> ByteString -> [a]
    LByteString.zipWith Word8 -> Word8 -> Word8
    Element ByteString -> Element ByteString -> Element ByteString
    f ByteString
    xs
        {-# INLINE ozip #-}
        {-# INLINE ounzip #-}
        {-# INLINE ozipWith #-}
    instance MonoZip Text.Text where
        ozip :: Text -> Text -> [(Element Text, Element Text)]
    ozip     = Text -> Text -> [(Char, Char)]
    Text -> Text -> [(Element Text, Element Text)]
    Text.zip
        ounzip :: [(Element Text, Element Text)] -> (Text, Text)
    ounzip   = ([Char] -> Text
    Text.pack ([Char] -> Text)
    -> ([Char] -> Text) -> ([Char], [Char]) -> (Text, Text)
    forall b c b' c'. (b -> c) -> (b' -> c') -> (b, b') -> (c, c')
    forall (a :: * -> * -> *) b c b' c'.
    Arrow a =>
    a b c -> a b' c' -> a (b, b') (c, c')
    *** [Char] -> Text
    Text.pack) (([Char], [Char]) -> (Text, Text))
    -> ([(Char, Char)] -> ([Char], [Char]))
    -> [(Char, Char)]
    -> (Text, Text)
    forall b c a. (b -> c) -> (a -> b) -> a -> c
    . [(Char, Char)] -> ([Char], [Char])
    forall a b. [(a, b)] -> ([a], [b])
    List.unzip
        ozipWith :: (Element Text -> Element Text -> Element Text)
    -> Text -> Text -> Text
    ozipWith = (Char -> Char -> Char) -> Text -> Text -> Text
    (Element Text -> Element Text -> Element Text)
    -> Text -> Text -> Text
    Text.zipWith
        {-# INLINE ozip #-}
        {-# INLINE ounzip #-}
        {-# INLINE ozipWith #-}
    instance MonoZip LText.Text where
        ozip :: Text -> Text -> [(Element Text, Element Text)]
    ozip     = Text -> Text -> [(Char, Char)]
    Text -> Text -> [(Element Text, Element Text)]
    LText.zip
        ounzip :: [(Element Text, Element Text)] -> (Text, Text)
    ounzip   = ([Char] -> Text
    LText.pack ([Char] -> Text)
    -> ([Char] -> Text) -> ([Char], [Char]) -> (Text, Text)
    forall b c b' c'. (b -> c) -> (b' -> c') -> (b, b') -> (c, c')
    forall (a :: * -> * -> *) b c b' c'.
    Arrow a =>
    a b c -> a b' c' -> a (b, b') (c, c')
    *** [Char] -> Text
    LText.pack) (([Char], [Char]) -> (Text, Text))
    -> ([(Char, Char)] -> ([Char], [Char]))
    -> [(Char, Char)]
    -> (Text, Text)
    forall b c a. (b -> c) -> (a -> b) -> a -> c
    . [(Char, Char)] -> ([Char], [Char])
    forall a b. [(a, b)] -> ([a], [b])
    List.unzip
        ozipWith :: (Element Text -> Element Text -> Element Text)
    -> Text -> Text -> Text
    ozipWith = (Char -> Char -> Char) -> Text -> Text -> Text
    (Element Text -> Element Text -> Element Text)
    -> Text -> Text -> Text
    LText.zipWith
        {-# INLINE ozip #-}
        {-# INLINE ounzip #-}
        {-# INLINE ozipWith #-}

    -- | Type class for maps whose keys can be converted into sets.
    class SetContainer set => HasKeysSet set where
        -- | Type of the key set.
        type KeySet set

        -- | Convert a map into a set of its keys.
        keysSet :: set -> KeySet set

    instance Ord k => HasKeysSet (Map.Map k v) where
        type KeySet (Map.Map k v) = Set.Set k
        keysSet :: Map k v -> KeySet (Map k v)
    keysSet = Map k v -> Set k
    Map k v -> KeySet (Map k v)
    forall k a. Map k a -> Set k
    Map.keysSet
    instance HasKeysSet (IntMap.IntMap v) where
        type KeySet (IntMap.IntMap v) = IntSet.IntSet
        keysSet :: IntMap v -> KeySet (IntMap v)
    keysSet = IntMap v -> IntSet
    IntMap v -> KeySet (IntMap v)
    forall a. IntMap a -> IntSet
    IntMap.keysSet
    instance (Hashable k, Eq k) => HasKeysSet (HashMap.HashMap k v) where
        type KeySet (HashMap.HashMap k v) = HashSet.HashSet k
        keysSet :: HashMap k v -> KeySet (HashMap k v)
    keysSet = [k] -> HashSet k
    [Element (HashSet k)] -> HashSet k
    forall set. IsSet set => [Element set] -> set
    setFromList ([k] -> HashSet k)
    -> (HashMap k v -> [k]) -> HashMap k v -> HashSet k
    forall b c a. (b -> c) -> (a -> b) -> a -> c
    . HashMap k v -> [k]
    forall k v. HashMap k v -> [k]
    HashMap.keys