    {-# LANGUAGE NoImplicitPrelude #-}
    -- |
    -- Module:      Data.Aeson.Functions
    -- Copyright:   (c) 2011-2016 Bryan O'Sullivan
    --              (c) 2011 MailRank, Inc.
    -- License:     BSD3
    -- Maintainer:  Bryan O'Sullivan <bos@serpentine.com>
    -- Stability:   experimental
    -- Portability: portable

    module Data.Aeson.Internal.Functions
        (
          mapHashKeyVal
        , mapKeyVal
        , mapKey
        ) where

    import Prelude.Compat

    import Data.Hashable (Hashable)
    import qualified Data.HashMap.Strict as H
    import qualified Data.Map as M

    -- | Transform a 'M.Map' into a 'H.HashMap' while transforming the keys.
    mapHashKeyVal :: (Eq k2, Hashable k2) => (k1 -> k2) -> (v1 -> v2)
                  -> M.Map k1 v1 -> H.HashMap k2 v2
    mapHashKeyVal :: (k1 -> k2) -> (v1 -> v2) -> Map k1 v1 -> HashMap k2 v2
    mapHashKeyVal fk :: k1 -> k2
    fk kv :: v1 -> v2
    kv = (k1 -> v1 -> HashMap k2 v2 -> HashMap k2 v2)
    -> HashMap k2 v2 -> Map k1 v1 -> HashMap k2 v2
    forall k a b. (k -> a -> b -> b) -> b -> Map k a -> b
    M.foldrWithKey (\k :: k1
    k v :: v1
    v -> k2 -> v2 -> HashMap k2 v2 -> HashMap k2 v2
    forall k v.
    (Eq k, Hashable k) =>
    k -> v -> HashMap k v -> HashMap k v
    H.insert (k1 -> k2
    fk k1
    k) (v1 -> v2
    kv v1
    v)) HashMap k2 v2
    forall k v. HashMap k v
    H.empty
    {-# INLINE mapHashKeyVal #-}

    -- | Transform the keys and values of a 'H.HashMap'.
    mapKeyVal :: (Eq k2, Hashable k2) => (k1 -> k2) -> (v1 -> v2)
              -> H.HashMap k1 v1 -> H.HashMap k2 v2
    mapKeyVal :: (k1 -> k2) -> (v1 -> v2) -> HashMap k1 v1 -> HashMap k2 v2
    mapKeyVal fk :: k1 -> k2
    fk kv :: v1 -> v2
    kv = (k1 -> v1 -> HashMap k2 v2 -> HashMap k2 v2)
    -> HashMap k2 v2 -> HashMap k1 v1 -> HashMap k2 v2
    forall k v a. (k -> v -> a -> a) -> a -> HashMap k v -> a
    H.foldrWithKey (\k :: k1
    k v :: v1
    v -> k2 -> v2 -> HashMap k2 v2 -> HashMap k2 v2
    forall k v.
    (Eq k, Hashable k) =>
    k -> v -> HashMap k v -> HashMap k v
    H.insert (k1 -> k2
    fk k1
    k) (v1 -> v2
    kv v1
    v)) HashMap k2 v2
    forall k v. HashMap k v
    H.empty
    {-# INLINE mapKeyVal #-}

    -- | Transform the keys of a 'H.HashMap'.
    mapKey :: (Eq k2, Hashable k2) => (k1 -> k2) -> H.HashMap k1 v -> H.HashMap k2 v
    mapKey :: (k1 -> k2) -> HashMap k1 v -> HashMap k2 v
    mapKey fk :: k1 -> k2
    fk = (k1 -> k2) -> (v -> v) -> HashMap k1 v -> HashMap k2 v
    forall k2 k1 v1 v2.
    (Eq k2, Hashable k2) =>
    (k1 -> k2) -> (v1 -> v2) -> HashMap k1 v1 -> HashMap k2 v2
    mapKeyVal k1 -> k2
    fk v -> v
    forall a. a -> a
    id
    {-# INLINE mapKey #-}