-- |
-- Module      : Streamly.Internal.Data.IsMap
-- Copyright   : (c) 2022 Composewell Technologies
-- License     : BSD-3-Clause
-- Maintainer  : streamly@composewell.com
-- Stability   : experimental
-- Portability : GHC

module Streamly.Internal.Data.IsMap (IsMap(..)) where

import Data.Kind (Type)
import Data.Map.Strict (Map)

import qualified Data.IntMap.Strict as IntMap
import qualified Data.Map.Strict as Map

-- XXX Try unpacked-containers

class IsMap f where
    type Key f :: Type

    mapEmpty :: f a
    mapAlterF :: Functor g =>
        (Maybe a -> g (Maybe a)) -> Key f -> f a -> g (f a)
    -- These can be implemented in terms of alterF itself
    mapLookup :: Key f -> f a -> Maybe a
    mapInsert :: Key f -> a -> f a -> f a
    mapDelete :: Key f -> f a -> f a
    mapUnion :: f a -> f a -> f a
    mapNull :: f a -> Bool

instance Ord k => IsMap (Map k) where
    type Key (Map k) = k

    mapEmpty :: Map k a
mapEmpty = Map k a
forall k a. Map k a
Map.empty
    mapAlterF :: (Maybe a -> g (Maybe a)) -> Key (Map k) -> Map k a -> g (Map k a)
mapAlterF = (Maybe a -> g (Maybe a)) -> Key (Map k) -> Map k a -> g (Map k a)
forall (f :: * -> *) k a.
(Functor f, Ord k) =>
(Maybe a -> f (Maybe a)) -> k -> Map k a -> f (Map k a)
Map.alterF
    mapLookup :: Key (Map k) -> Map k a -> Maybe a
mapLookup = Key (Map k) -> Map k a -> Maybe a
forall k a. Ord k => k -> Map k a -> Maybe a
Map.lookup
    mapInsert :: Key (Map k) -> a -> Map k a -> Map k a
mapInsert = Key (Map k) -> a -> Map k a -> Map k a
forall k a. Ord k => k -> a -> Map k a -> Map k a
Map.insert
    mapDelete :: Key (Map k) -> Map k a -> Map k a
mapDelete = Key (Map k) -> Map k a -> Map k a
forall k a. Ord k => k -> Map k a -> Map k a
Map.delete
    mapUnion :: Map k a -> Map k a -> Map k a
mapUnion = Map k a -> Map k a -> Map k a
forall k a. Ord k => Map k a -> Map k a -> Map k a
Map.union
    mapNull :: Map k a -> Bool
mapNull = Map k a -> Bool
forall k a. Map k a -> Bool
Map.null

instance IsMap IntMap.IntMap where
    type Key IntMap.IntMap = Int

    mapEmpty :: IntMap a
mapEmpty = IntMap a
forall a. IntMap a
IntMap.empty
    mapAlterF :: (Maybe a -> g (Maybe a)) -> Key IntMap -> IntMap a -> g (IntMap a)
mapAlterF = (Maybe a -> g (Maybe a)) -> Key IntMap -> IntMap a -> g (IntMap a)
forall (f :: * -> *) a.
Functor f =>
(Maybe a -> f (Maybe a)) -> Key -> IntMap a -> f (IntMap a)
IntMap.alterF
    mapLookup :: Key IntMap -> IntMap a -> Maybe a
mapLookup = Key IntMap -> IntMap a -> Maybe a
forall a. Key -> IntMap a -> Maybe a
IntMap.lookup
    mapInsert :: Key IntMap -> a -> IntMap a -> IntMap a
mapInsert = Key IntMap -> a -> IntMap a -> IntMap a
forall a. Key -> a -> IntMap a -> IntMap a
IntMap.insert
    mapDelete :: Key IntMap -> IntMap a -> IntMap a
mapDelete = Key IntMap -> IntMap a -> IntMap a
forall a. Key -> IntMap a -> IntMap a
IntMap.delete
    mapUnion :: IntMap a -> IntMap a -> IntMap a
mapUnion = IntMap a -> IntMap a -> IntMap a
forall a. IntMap a -> IntMap a -> IntMap a
IntMap.union
    mapNull :: IntMap a -> Bool
mapNull = IntMap a -> Bool
forall a. IntMap a -> Bool
IntMap.null