module Data.IOHashMap
  ( IOHashMap
  , newIOHashMap
  , readIOHashMap
  , modifyIOHashMap
  , empty
  , singleton
  , null
  , size
  , member
  , lookup
  , (!?)
  , findWithDefault
  , (!)
  , insert
  , insertWith
  , delete
  , adjust
  , update
  , alter
  , foldMapWithKey
  , foldr
  , foldl
  , foldr'
  , foldl'
  , foldrWithKey'
  , foldlWithKey'
  , foldrWithKey
  , foldlWithKey
  , keys
  , elems
  , toList
  , fromList
  ) where

import           Control.Monad.IO.Class (MonadIO (..))
import           Control.Monad.STM      (atomically)
import           Data.HashMap.Strict    (HashMap)
import qualified Data.HashMap.Strict    as HM
import           Data.Hashable
import           Data.IOHashMap.STM     (IOHashMap)
import qualified Data.IOHashMap.STM     as STM
import           Prelude                hiding (foldl, foldr, lookup, null)

-- start helpers
newIOHashMap :: MonadIO m => HashMap k v -> m (IOHashMap k v)
newIOHashMap :: HashMap k v -> m (IOHashMap k v)
newIOHashMap = IO (IOHashMap k v) -> m (IOHashMap k v)
forall (m :: * -> *) a. MonadIO m => IO a -> m a
liftIO (IO (IOHashMap k v) -> m (IOHashMap k v))
-> (HashMap k v -> IO (IOHashMap k v))
-> HashMap k v
-> m (IOHashMap k v)
forall b c a. (b -> c) -> (a -> b) -> a -> c
. STM (IOHashMap k v) -> IO (IOHashMap k v)
forall a. STM a -> IO a
atomically (STM (IOHashMap k v) -> IO (IOHashMap k v))
-> (HashMap k v -> STM (IOHashMap k v))
-> HashMap k v
-> IO (IOHashMap k v)
forall b c a. (b -> c) -> (a -> b) -> a -> c
. HashMap k v -> STM (IOHashMap k v)
forall k v. HashMap k v -> STM (IOHashMap k v)
STM.newIOHashMap

readIOHashMap :: MonadIO m => (HashMap k v -> a) -> IOHashMap k v -> m a
readIOHashMap :: (HashMap k v -> a) -> IOHashMap k v -> m a
readIOHashMap HashMap k v -> a
f = IO a -> m a
forall (m :: * -> *) a. MonadIO m => IO a -> m a
liftIO (IO a -> m a) -> (IOHashMap k v -> IO a) -> IOHashMap k v -> m a
forall b c a. (b -> c) -> (a -> b) -> a -> c
. STM a -> IO a
forall a. STM a -> IO a
atomically (STM a -> IO a)
-> (IOHashMap k v -> STM a) -> IOHashMap k v -> IO a
forall b c a. (b -> c) -> (a -> b) -> a -> c
. (HashMap k v -> a) -> IOHashMap k v -> STM a
forall k v a. (HashMap k v -> a) -> IOHashMap k v -> STM a
STM.readIOHashMap HashMap k v -> a
f

modifyIOHashMap :: MonadIO m => (HashMap k v -> HashMap k v) -> IOHashMap k v -> m ()
modifyIOHashMap :: (HashMap k v -> HashMap k v) -> IOHashMap k v -> m ()
modifyIOHashMap HashMap k v -> HashMap k v
f = IO () -> m ()
forall (m :: * -> *) a. MonadIO m => IO a -> m a
liftIO (IO () -> m ())
-> (IOHashMap k v -> IO ()) -> IOHashMap k v -> m ()
forall b c a. (b -> c) -> (a -> b) -> a -> c
. STM () -> IO ()
forall a. STM a -> IO a
atomically (STM () -> IO ())
-> (IOHashMap k v -> STM ()) -> IOHashMap k v -> IO ()
forall b c a. (b -> c) -> (a -> b) -> a -> c
. (HashMap k v -> HashMap k v) -> IOHashMap k v -> STM ()
forall k v. (HashMap k v -> HashMap k v) -> IOHashMap k v -> STM ()
STM.modifyIOHashMap HashMap k v -> HashMap k v
f
-- end helpers

------------------------------------------------------------------------
-- * Construction

-- | /O(1)/ Construct an empty map.
empty :: MonadIO m => m (IOHashMap k v)
empty :: m (IOHashMap k v)
empty = HashMap k v -> m (IOHashMap k v)
forall (m :: * -> *) k v.
MonadIO m =>
HashMap k v -> m (IOHashMap k v)
newIOHashMap HashMap k v
forall k v. HashMap k v
HM.empty

-- | /O(1)/ Construct a map with a single element.
singleton :: MonadIO m => Hashable k => k -> v -> m (IOHashMap k v)
singleton :: k -> v -> m (IOHashMap k v)
singleton k
k = HashMap k v -> m (IOHashMap k v)
forall (m :: * -> *) k v.
MonadIO m =>
HashMap k v -> m (IOHashMap k v)
newIOHashMap (HashMap k v -> m (IOHashMap k v))
-> (v -> HashMap k v) -> v -> m (IOHashMap k v)
forall b c a. (b -> c) -> (a -> b) -> a -> c
. k -> v -> HashMap k v
forall k v. Hashable k => k -> v -> HashMap k v
HM.singleton k
k

------------------------------------------------------------------------
-- * Basic interface

-- | /O(1)/ Return 'True' if this map is empty, 'False' otherwise.
null :: MonadIO m => IOHashMap k v -> m Bool
null :: IOHashMap k v -> m Bool
null = (HashMap k v -> Bool) -> IOHashMap k v -> m Bool
forall (m :: * -> *) k v a.
MonadIO m =>
(HashMap k v -> a) -> IOHashMap k v -> m a
readIOHashMap HashMap k v -> Bool
forall k v. HashMap k v -> Bool
HM.null

-- | /O(n)/ Return the number of key-value mappings in this map.
size :: MonadIO m => IOHashMap k v -> m Int
size :: IOHashMap k v -> m Int
size = (HashMap k v -> Int) -> IOHashMap k v -> m Int
forall (m :: * -> *) k v a.
MonadIO m =>
(HashMap k v -> a) -> IOHashMap k v -> m a
readIOHashMap HashMap k v -> Int
forall k v. HashMap k v -> Int
HM.size

-- | /O(log n)/ Return 'True' if the specified key is present in the
-- map, 'False' otherwise.
member :: (MonadIO m, Eq k, Hashable k) => k -> IOHashMap k a -> m Bool
member :: k -> IOHashMap k a -> m Bool
member = (HashMap k a -> Bool) -> IOHashMap k a -> m Bool
forall (m :: * -> *) k v a.
MonadIO m =>
(HashMap k v -> a) -> IOHashMap k v -> m a
readIOHashMap ((HashMap k a -> Bool) -> IOHashMap k a -> m Bool)
-> (k -> HashMap k a -> Bool) -> k -> IOHashMap k a -> m Bool
forall b c a. (b -> c) -> (a -> b) -> a -> c
. k -> HashMap k a -> Bool
forall k a. (Eq k, Hashable k) => k -> HashMap k a -> Bool
HM.member

-- | /O(log n)/ Return the value to which the specified key is mapped,
-- or 'Nothing' if this map contains no mapping for the key.
lookup :: (MonadIO m, Eq k, Hashable k) => k -> IOHashMap k v -> m (Maybe v)
lookup :: k -> IOHashMap k v -> m (Maybe v)
lookup = (HashMap k v -> Maybe v) -> IOHashMap k v -> m (Maybe v)
forall (m :: * -> *) k v a.
MonadIO m =>
(HashMap k v -> a) -> IOHashMap k v -> m a
readIOHashMap ((HashMap k v -> Maybe v) -> IOHashMap k v -> m (Maybe v))
-> (k -> HashMap k v -> Maybe v)
-> k
-> IOHashMap k v
-> m (Maybe v)
forall b c a. (b -> c) -> (a -> b) -> a -> c
. k -> HashMap k v -> Maybe v
forall k v. (Eq k, Hashable k) => k -> HashMap k v -> Maybe v
HM.lookup

-- | /O(log n)/ Return the value to which the specified key is mapped,
-- or 'Nothing' if this map contains no mapping for the key.
--
-- This is a flipped version of 'lookup'.
--
-- @since 0.2.11
(!?) :: (MonadIO m, Eq k, Hashable k) => IOHashMap k v -> k -> m (Maybe v)
!? :: IOHashMap k v -> k -> m (Maybe v)
(!?) IOHashMap k v
m k
k = k -> IOHashMap k v -> m (Maybe v)
forall (m :: * -> *) k v.
(MonadIO m, Eq k, Hashable k) =>
k -> IOHashMap k v -> m (Maybe v)
lookup k
k IOHashMap k v
m

-- | /O(log n)/ Return the value to which the specified key is mapped,
-- or the default value if this map contains no mapping for the key.
--
-- @since 0.2.11
findWithDefault :: (MonadIO m, Eq k, Hashable k)
              => v          -- ^ Default value to return.
              -> k -> IOHashMap k v -> m v
findWithDefault :: v -> k -> IOHashMap k v -> m v
findWithDefault v
v = (HashMap k v -> v) -> IOHashMap k v -> m v
forall (m :: * -> *) k v a.
MonadIO m =>
(HashMap k v -> a) -> IOHashMap k v -> m a
readIOHashMap ((HashMap k v -> v) -> IOHashMap k v -> m v)
-> (k -> HashMap k v -> v) -> k -> IOHashMap k v -> m v
forall b c a. (b -> c) -> (a -> b) -> a -> c
. v -> k -> HashMap k v -> v
forall k v. (Eq k, Hashable k) => v -> k -> HashMap k v -> v
HM.findWithDefault v
v



-- | /O(log n)/ Return the value to which the specified key is mapped.
-- Calls 'error' if this map contains no mapping for the key.
(!) :: (MonadIO m, Eq k, Hashable k) => IOHashMap k v -> k -> m v
(!) IOHashMap k v
m k
k = (HashMap k v -> v) -> IOHashMap k v -> m v
forall (m :: * -> *) k v a.
MonadIO m =>
(HashMap k v -> a) -> IOHashMap k v -> m a
readIOHashMap ((HashMap k v -> k -> v) -> k -> HashMap k v -> v
forall a b c. (a -> b -> c) -> b -> a -> c
flip HashMap k v -> k -> v
forall k v.
(Eq k, Hashable k, HasCallStack) =>
HashMap k v -> k -> v
(HM.!) k
k) IOHashMap k v
m

infixl 9 !

------------------------------------------------------------------------
-- * Basic interface

-- | /O(log n)/ Associate the specified value with the specified
-- key in this map.  If this map previously contained a mapping for
-- the key, the old value is replaced.
insert :: (MonadIO m, Eq k, Hashable k) => k -> v -> IOHashMap k v -> m ()
insert :: k -> v -> IOHashMap k v -> m ()
insert k
k = (HashMap k v -> HashMap k v) -> IOHashMap k v -> m ()
forall (m :: * -> *) k v.
MonadIO m =>
(HashMap k v -> HashMap k v) -> IOHashMap k v -> m ()
modifyIOHashMap ((HashMap k v -> HashMap k v) -> IOHashMap k v -> m ())
-> (v -> HashMap k v -> HashMap k v) -> v -> IOHashMap k v -> m ()
forall b c a. (b -> c) -> (a -> b) -> a -> c
. k -> v -> HashMap k v -> HashMap k v
forall k v.
(Eq k, Hashable k) =>
k -> v -> HashMap k v -> HashMap k v
HM.insert k
k


-- | /O(log n)/ Associate the value with the key in this map.  If
-- this map previously contained a mapping for the key, the old value
-- is replaced by the result of applying the given function to the new
-- and old value.  Example:
--
-- > insertWith f k v map
-- >   where f new old = new + old
insertWith :: (MonadIO m, Eq k, Hashable k) => (v -> v -> v) -> k -> v -> IOHashMap k v
           -> m ()
insertWith :: (v -> v -> v) -> k -> v -> IOHashMap k v -> m ()
insertWith v -> v -> v
f k
k = (HashMap k v -> HashMap k v) -> IOHashMap k v -> m ()
forall (m :: * -> *) k v.
MonadIO m =>
(HashMap k v -> HashMap k v) -> IOHashMap k v -> m ()
modifyIOHashMap ((HashMap k v -> HashMap k v) -> IOHashMap k v -> m ())
-> (v -> HashMap k v -> HashMap k v) -> v -> IOHashMap k v -> m ()
forall b c a. (b -> c) -> (a -> b) -> a -> c
. (v -> v -> v) -> k -> v -> HashMap k v -> HashMap k v
forall k v.
(Eq k, Hashable k) =>
(v -> v -> v) -> k -> v -> HashMap k v -> HashMap k v
HM.insertWith v -> v -> v
f k
k


-- | /O(log n)/ Remove the mapping for the specified key from this map
-- if present.
delete :: (MonadIO m, Eq k, Hashable k) => k -> IOHashMap k v -> m ()
delete :: k -> IOHashMap k v -> m ()
delete = (HashMap k v -> HashMap k v) -> IOHashMap k v -> m ()
forall (m :: * -> *) k v.
MonadIO m =>
(HashMap k v -> HashMap k v) -> IOHashMap k v -> m ()
modifyIOHashMap ((HashMap k v -> HashMap k v) -> IOHashMap k v -> m ())
-> (k -> HashMap k v -> HashMap k v) -> k -> IOHashMap k v -> m ()
forall b c a. (b -> c) -> (a -> b) -> a -> c
. k -> HashMap k v -> HashMap k v
forall k v. (Eq k, Hashable k) => k -> HashMap k v -> HashMap k v
HM.delete


-- | /O(log n)/ Adjust the value tied to a given key in this map only
-- if it is present. Otherwise, leave the map alone.
adjust :: MonadIO m => (Eq k, Hashable k) => (v -> v) -> k -> IOHashMap k v -> m ()
adjust :: (v -> v) -> k -> IOHashMap k v -> m ()
adjust v -> v
f = (HashMap k v -> HashMap k v) -> IOHashMap k v -> m ()
forall (m :: * -> *) k v.
MonadIO m =>
(HashMap k v -> HashMap k v) -> IOHashMap k v -> m ()
modifyIOHashMap ((HashMap k v -> HashMap k v) -> IOHashMap k v -> m ())
-> (k -> HashMap k v -> HashMap k v) -> k -> IOHashMap k v -> m ()
forall b c a. (b -> c) -> (a -> b) -> a -> c
. (v -> v) -> k -> HashMap k v -> HashMap k v
forall k v.
(Eq k, Hashable k) =>
(v -> v) -> k -> HashMap k v -> HashMap k v
HM.adjust v -> v
f

-- | /O(log n)/  The expression @('update' f k map)@ updates the value @x@ at @k@
-- (if it is in the map). If @(f x)@ is 'Nothing', the element is deleted.
-- If it is @('Just' y)@, the key @k@ is bound to the new value @y@.
update :: (MonadIO m, Eq k, Hashable k) => (a -> Maybe a) -> k -> IOHashMap k a -> m ()
update :: (a -> Maybe a) -> k -> IOHashMap k a -> m ()
update a -> Maybe a
f = (HashMap k a -> HashMap k a) -> IOHashMap k a -> m ()
forall (m :: * -> *) k v.
MonadIO m =>
(HashMap k v -> HashMap k v) -> IOHashMap k v -> m ()
modifyIOHashMap ((HashMap k a -> HashMap k a) -> IOHashMap k a -> m ())
-> (k -> HashMap k a -> HashMap k a) -> k -> IOHashMap k a -> m ()
forall b c a. (b -> c) -> (a -> b) -> a -> c
. (a -> Maybe a) -> k -> HashMap k a -> HashMap k a
forall k a.
(Eq k, Hashable k) =>
(a -> Maybe a) -> k -> HashMap k a -> HashMap k a
HM.update a -> Maybe a
f

-- | /O(log n)/  The expression @('alter' f k map)@ alters the value @x@ at @k@, or
-- absence thereof.
--
-- 'alter' can be used to insert, delete, or update a value in a map. In short:
--
-- @
-- 'lookup' k ('alter' f k m) = f ('lookup' k m)
-- @
alter :: (MonadIO m, Eq k, Hashable k) => (Maybe v -> Maybe v) -> k -> IOHashMap k v -> m ()
alter :: (Maybe v -> Maybe v) -> k -> IOHashMap k v -> m ()
alter Maybe v -> Maybe v
f = (HashMap k v -> HashMap k v) -> IOHashMap k v -> m ()
forall (m :: * -> *) k v.
MonadIO m =>
(HashMap k v -> HashMap k v) -> IOHashMap k v -> m ()
modifyIOHashMap ((HashMap k v -> HashMap k v) -> IOHashMap k v -> m ())
-> (k -> HashMap k v -> HashMap k v) -> k -> IOHashMap k v -> m ()
forall b c a. (b -> c) -> (a -> b) -> a -> c
. (Maybe v -> Maybe v) -> k -> HashMap k v -> HashMap k v
forall k v.
(Eq k, Hashable k) =>
(Maybe v -> Maybe v) -> k -> HashMap k v -> HashMap k v
HM.alter Maybe v -> Maybe v
f

------------------------------------------------------------------------
-- * Folds

-- | /O(n)/ Reduce the map by applying a function to each element
-- and combining the results with a monoid operation.
foldMapWithKey ::(MonadIO m, Monoid n) => (k -> v -> n) -> IOHashMap k v -> m n
foldMapWithKey :: (k -> v -> n) -> IOHashMap k v -> m n
foldMapWithKey = (HashMap k v -> n) -> IOHashMap k v -> m n
forall (m :: * -> *) k v a.
MonadIO m =>
(HashMap k v -> a) -> IOHashMap k v -> m a
readIOHashMap ((HashMap k v -> n) -> IOHashMap k v -> m n)
-> ((k -> v -> n) -> HashMap k v -> n)
-> (k -> v -> n)
-> IOHashMap k v
-> m n
forall b c a. (b -> c) -> (a -> b) -> a -> c
. (k -> v -> n) -> HashMap k v -> n
forall m k v. Monoid m => (k -> v -> m) -> HashMap k v -> m
HM.foldMapWithKey

-- | /O(n)/ Reduce this map by applying a binary operator to all
-- elements, using the given starting value (typically the
-- right-identity of the operator).
foldr :: MonadIO m => (v -> a -> a) -> a -> IOHashMap k v -> m a
foldr :: (v -> a -> a) -> a -> IOHashMap k v -> m a
foldr v -> a -> a
f = (HashMap k v -> a) -> IOHashMap k v -> m a
forall (m :: * -> *) k v a.
MonadIO m =>
(HashMap k v -> a) -> IOHashMap k v -> m a
readIOHashMap ((HashMap k v -> a) -> IOHashMap k v -> m a)
-> (a -> HashMap k v -> a) -> a -> IOHashMap k v -> m a
forall b c a. (b -> c) -> (a -> b) -> a -> c
. (v -> a -> a) -> a -> HashMap k v -> a
forall v a k. (v -> a -> a) -> a -> HashMap k v -> a
HM.foldr v -> a -> a
f


-- | /O(n)/ Reduce this map by applying a binary operator to all
-- elements, using the given starting value (typically the
-- left-identity of the operator).
foldl :: MonadIO m => (a -> v -> a) -> a -> IOHashMap k v -> m a
foldl :: (a -> v -> a) -> a -> IOHashMap k v -> m a
foldl a -> v -> a
f = (HashMap k v -> a) -> IOHashMap k v -> m a
forall (m :: * -> *) k v a.
MonadIO m =>
(HashMap k v -> a) -> IOHashMap k v -> m a
readIOHashMap ((HashMap k v -> a) -> IOHashMap k v -> m a)
-> (a -> HashMap k v -> a) -> a -> IOHashMap k v -> m a
forall b c a. (b -> c) -> (a -> b) -> a -> c
. (a -> v -> a) -> a -> HashMap k v -> a
forall a v k. (a -> v -> a) -> a -> HashMap k v -> a
HM.foldl a -> v -> a
f


-- | /O(n)/ Reduce this map by applying a binary operator to all
-- elements, using the given starting value (typically the
-- right-identity of the operator).  Each application of the operator
-- is evaluated before using the result in the next application.
-- This function is strict in the starting value.
foldr' :: MonadIO m => (v -> a -> a) -> a -> IOHashMap k v -> m a
foldr' :: (v -> a -> a) -> a -> IOHashMap k v -> m a
foldr' v -> a -> a
f = (HashMap k v -> a) -> IOHashMap k v -> m a
forall (m :: * -> *) k v a.
MonadIO m =>
(HashMap k v -> a) -> IOHashMap k v -> m a
readIOHashMap ((HashMap k v -> a) -> IOHashMap k v -> m a)
-> (a -> HashMap k v -> a) -> a -> IOHashMap k v -> m a
forall b c a. (b -> c) -> (a -> b) -> a -> c
. (v -> a -> a) -> a -> HashMap k v -> a
forall v a k. (v -> a -> a) -> a -> HashMap k v -> a
HM.foldr' v -> a -> a
f

-- | /O(n)/ Reduce this map by applying a binary operator to all
-- elements, using the given starting value (typically the
-- left-identity of the operator).  Each application of the operator
-- is evaluated before using the result in the next application.
-- This function is strict in the starting value.
foldl' :: MonadIO m => (a -> v -> a) -> a -> IOHashMap k v -> m a
foldl' :: (a -> v -> a) -> a -> IOHashMap k v -> m a
foldl' a -> v -> a
f = (HashMap k v -> a) -> IOHashMap k v -> m a
forall (m :: * -> *) k v a.
MonadIO m =>
(HashMap k v -> a) -> IOHashMap k v -> m a
readIOHashMap ((HashMap k v -> a) -> IOHashMap k v -> m a)
-> (a -> HashMap k v -> a) -> a -> IOHashMap k v -> m a
forall b c a. (b -> c) -> (a -> b) -> a -> c
. (a -> v -> a) -> a -> HashMap k v -> a
forall a v k. (a -> v -> a) -> a -> HashMap k v -> a
HM.foldl' a -> v -> a
f


-- | /O(n)/ Reduce this map by applying a binary operator to all
-- elements, using the given starting value (typically the
-- right-identity of the operator).  Each application of the operator
-- is evaluated before using the result in the next application.
-- This function is strict in the starting value.
foldrWithKey' :: MonadIO m => (k -> v -> a -> a) -> a -> IOHashMap k v -> m a
foldrWithKey' :: (k -> v -> a -> a) -> a -> IOHashMap k v -> m a
foldrWithKey' k -> v -> a -> a
f = (HashMap k v -> a) -> IOHashMap k v -> m a
forall (m :: * -> *) k v a.
MonadIO m =>
(HashMap k v -> a) -> IOHashMap k v -> m a
readIOHashMap ((HashMap k v -> a) -> IOHashMap k v -> m a)
-> (a -> HashMap k v -> a) -> a -> IOHashMap k v -> m a
forall b c a. (b -> c) -> (a -> b) -> a -> c
. (k -> v -> a -> a) -> a -> HashMap k v -> a
forall k v a. (k -> v -> a -> a) -> a -> HashMap k v -> a
HM.foldrWithKey' k -> v -> a -> a
f

-- | /O(n)/ Reduce this map by applying a binary operator to all
-- elements, using the given starting value (typically the
-- left-identity of the operator).  Each application of the operator
-- is evaluated before using the result in the next application.
-- This function is strict in the starting value.
foldlWithKey' :: MonadIO m => (a -> k -> v -> a) -> a -> IOHashMap k v -> m a
foldlWithKey' :: (a -> k -> v -> a) -> a -> IOHashMap k v -> m a
foldlWithKey' a -> k -> v -> a
f = (HashMap k v -> a) -> IOHashMap k v -> m a
forall (m :: * -> *) k v a.
MonadIO m =>
(HashMap k v -> a) -> IOHashMap k v -> m a
readIOHashMap ((HashMap k v -> a) -> IOHashMap k v -> m a)
-> (a -> HashMap k v -> a) -> a -> IOHashMap k v -> m a
forall b c a. (b -> c) -> (a -> b) -> a -> c
. (a -> k -> v -> a) -> a -> HashMap k v -> a
forall a k v. (a -> k -> v -> a) -> a -> HashMap k v -> a
HM.foldlWithKey' a -> k -> v -> a
f

-- | /O(n)/ Reduce this map by applying a binary operator to all
-- elements, using the given starting value (typically the
-- right-identity of the operator).
foldrWithKey :: MonadIO m => (k -> v -> a -> a) -> a -> IOHashMap k v -> m a
foldrWithKey :: (k -> v -> a -> a) -> a -> IOHashMap k v -> m a
foldrWithKey k -> v -> a -> a
f = (HashMap k v -> a) -> IOHashMap k v -> m a
forall (m :: * -> *) k v a.
MonadIO m =>
(HashMap k v -> a) -> IOHashMap k v -> m a
readIOHashMap ((HashMap k v -> a) -> IOHashMap k v -> m a)
-> (a -> HashMap k v -> a) -> a -> IOHashMap k v -> m a
forall b c a. (b -> c) -> (a -> b) -> a -> c
. (k -> v -> a -> a) -> a -> HashMap k v -> a
forall k v a. (k -> v -> a -> a) -> a -> HashMap k v -> a
HM.foldrWithKey k -> v -> a -> a
f


-- | /O(n)/ Reduce this map by applying a binary operator to all
-- elements, using the given starting value (typically the
-- left-identity of the operator).
foldlWithKey :: MonadIO m => (a -> k -> v -> a) -> a -> IOHashMap k v -> m a
foldlWithKey :: (a -> k -> v -> a) -> a -> IOHashMap k v -> m a
foldlWithKey a -> k -> v -> a
f = (HashMap k v -> a) -> IOHashMap k v -> m a
forall (m :: * -> *) k v a.
MonadIO m =>
(HashMap k v -> a) -> IOHashMap k v -> m a
readIOHashMap ((HashMap k v -> a) -> IOHashMap k v -> m a)
-> (a -> HashMap k v -> a) -> a -> IOHashMap k v -> m a
forall b c a. (b -> c) -> (a -> b) -> a -> c
. (a -> k -> v -> a) -> a -> HashMap k v -> a
forall a k v. (a -> k -> v -> a) -> a -> HashMap k v -> a
HM.foldlWithKey a -> k -> v -> a
f


------------------------------------------------------------------------
-- * Conversions

-- TODO: Improve fusion rules by modelled them after the Prelude ones
-- on lists.

-- | /O(n)/ Return a list of this map's keys.  The list is produced
-- lazily.
keys :: MonadIO m => IOHashMap k v -> m [k]
keys :: IOHashMap k v -> m [k]
keys = (HashMap k v -> [k]) -> IOHashMap k v -> m [k]
forall (m :: * -> *) k v a.
MonadIO m =>
(HashMap k v -> a) -> IOHashMap k v -> m a
readIOHashMap HashMap k v -> [k]
forall k v. HashMap k v -> [k]
HM.keys

-- | /O(n)/ Return a list of this map's values.  The list is produced
-- lazily.
elems :: MonadIO m => IOHashMap k v -> m [v]
elems :: IOHashMap k v -> m [v]
elems = (HashMap k v -> [v]) -> IOHashMap k v -> m [v]
forall (m :: * -> *) k v a.
MonadIO m =>
(HashMap k v -> a) -> IOHashMap k v -> m a
readIOHashMap HashMap k v -> [v]
forall k v. HashMap k v -> [v]
HM.elems

------------------------------------------------------------------------
-- ** Lists

-- | /O(n)/ Return a list of this map's elements.  The list is
-- produced lazily. The order of its elements is unspecified.
toList :: MonadIO m => IOHashMap k v -> m [(k, v)]
toList :: IOHashMap k v -> m [(k, v)]
toList = (HashMap k v -> [(k, v)]) -> IOHashMap k v -> m [(k, v)]
forall (m :: * -> *) k v a.
MonadIO m =>
(HashMap k v -> a) -> IOHashMap k v -> m a
readIOHashMap HashMap k v -> [(k, v)]
forall k v. HashMap k v -> [(k, v)]
HM.toList

-- | /O(n)/ Construct a map with the supplied mappings.  If the list
-- contains duplicate mappings, the later mappings take precedence.
fromList :: (MonadIO m, Eq k, Hashable k) => [(k, v)] -> m (IOHashMap k v)
fromList :: [(k, v)] -> m (IOHashMap k v)
fromList = HashMap k v -> m (IOHashMap k v)
forall (m :: * -> *) k v.
MonadIO m =>
HashMap k v -> m (IOHashMap k v)
newIOHashMap (HashMap k v -> m (IOHashMap k v))
-> ([(k, v)] -> HashMap k v) -> [(k, v)] -> m (IOHashMap k v)
forall b c a. (b -> c) -> (a -> b) -> a -> c
. [(k, v)] -> HashMap k v
forall k v. (Eq k, Hashable k) => [(k, v)] -> HashMap k v
HM.fromList