{-# LANGUAGE Safe, MultiParamTypeClasses, FlexibleInstances #-}

{- |
    Module      :  SDP.HashMap.Strict
    Copyright   :  (c) Andrey Mulik 2020
    License     :  BSD-style
    Maintainer  :  work.a.mulik@gmail.com
    Portability :  portable
  
    @SDP.HashMap.Strict@ provides 'HashMap' - strict unordered associative array
    with 'Hashable' keys.
-}
module SDP.HashMap.Strict
(
  -- * Exports
  module SDP.Hashable,
  module SDP.Linear,
  module SDP.Map,
  
  -- * Hash map
  HashMap, SHashMap
)
where

import Prelude ()
import SDP.SafePrelude
import SDP.Hashable
import SDP.Linear
import SDP.Map

import qualified Data.HashMap.Strict as H
import Data.HashMap.Strict ( HashMap )

import Data.Maybe

import Control.Exception.SDP

default ()

--------------------------------------------------------------------------------

-- | 'HashMap' alias, may reduce ambiguity.
type SHashMap = HashMap

--------------------------------------------------------------------------------

instance Nullable (HashMap k e)
  where
    isNull :: HashMap k e -> Bool
isNull = HashMap k e -> Bool
forall (t :: * -> *) a. Foldable t => t a -> Bool
null
    lzero :: HashMap k e
lzero  = HashMap k e
forall k e. HashMap k e
H.empty

instance (Index k) => Estimate (HashMap k e)
  where
    <==> :: Compare (HashMap k e)
(<==>) = (Int -> Int -> Ordering)
-> (HashMap k e -> Int) -> Compare (HashMap k e)
forall b c a. (b -> b -> c) -> (a -> b) -> a -> a -> c
on Int -> Int -> Ordering
forall o. Ord o => Compare o
(<=>) HashMap k e -> Int
forall (t :: * -> *) a. Foldable t => t a -> Int
length
    .<=. :: HashMap k e -> HashMap k e -> Bool
(.<=.) = (Int -> Int -> Bool)
-> (HashMap k e -> Int) -> HashMap k e -> HashMap k e -> Bool
forall b c a. (b -> b -> c) -> (a -> b) -> a -> a -> c
on Int -> Int -> Bool
forall a. Ord a => a -> a -> Bool
(<=)  HashMap k e -> Int
forall (t :: * -> *) a. Foldable t => t a -> Int
length
    .>=. :: HashMap k e -> HashMap k e -> Bool
(.>=.) = (Int -> Int -> Bool)
-> (HashMap k e -> Int) -> HashMap k e -> HashMap k e -> Bool
forall b c a. (b -> b -> c) -> (a -> b) -> a -> a -> c
on Int -> Int -> Bool
forall a. Ord a => a -> a -> Bool
(>=)  HashMap k e -> Int
forall (t :: * -> *) a. Foldable t => t a -> Int
length
    .>. :: HashMap k e -> HashMap k e -> Bool
(.>.)  = (Int -> Int -> Bool)
-> (HashMap k e -> Int) -> HashMap k e -> HashMap k e -> Bool
forall b c a. (b -> b -> c) -> (a -> b) -> a -> a -> c
on Int -> Int -> Bool
forall a. Ord a => a -> a -> Bool
(>)   HashMap k e -> Int
forall (t :: * -> *) a. Foldable t => t a -> Int
length
    .<. :: HashMap k e -> HashMap k e -> Bool
(.<.)  = (Int -> Int -> Bool)
-> (HashMap k e -> Int) -> HashMap k e -> HashMap k e -> Bool
forall b c a. (b -> b -> c) -> (a -> b) -> a -> a -> c
on Int -> Int -> Bool
forall a. Ord a => a -> a -> Bool
(<)   HashMap k e -> Int
forall (t :: * -> *) a. Foldable t => t a -> Int
length
    
    <.=> :: HashMap k e -> Int -> Ordering
(<.=>) = Int -> Int -> Ordering
forall o. Ord o => Compare o
(<=>) (Int -> Int -> Ordering)
-> (HashMap k e -> Int) -> HashMap k e -> Int -> Ordering
forall b c a. (b -> c) -> (a -> b) -> a -> c
. HashMap k e -> Int
forall (t :: * -> *) a. Foldable t => t a -> Int
length
    .>= :: HashMap k e -> Int -> Bool
(.>=)  = Int -> Int -> Bool
forall a. Ord a => a -> a -> Bool
(>=)  (Int -> Int -> Bool)
-> (HashMap k e -> Int) -> HashMap k e -> Int -> Bool
forall b c a. (b -> c) -> (a -> b) -> a -> c
. HashMap k e -> Int
forall (t :: * -> *) a. Foldable t => t a -> Int
length
    .<= :: HashMap k e -> Int -> Bool
(.<=)  = Int -> Int -> Bool
forall a. Ord a => a -> a -> Bool
(<=)  (Int -> Int -> Bool)
-> (HashMap k e -> Int) -> HashMap k e -> Int -> Bool
forall b c a. (b -> c) -> (a -> b) -> a -> c
. HashMap k e -> Int
forall (t :: * -> *) a. Foldable t => t a -> Int
length
    .> :: HashMap k e -> Int -> Bool
(.>)   = Int -> Int -> Bool
forall a. Ord a => a -> a -> Bool
(>)   (Int -> Int -> Bool)
-> (HashMap k e -> Int) -> HashMap k e -> Int -> Bool
forall b c a. (b -> c) -> (a -> b) -> a -> c
. HashMap k e -> Int
forall (t :: * -> *) a. Foldable t => t a -> Int
length
    .< :: HashMap k e -> Int -> Bool
(.<)   = Int -> Int -> Bool
forall a. Ord a => a -> a -> Bool
(<)   (Int -> Int -> Bool)
-> (HashMap k e -> Int) -> HashMap k e -> Int -> Bool
forall b c a. (b -> c) -> (a -> b) -> a -> c
. HashMap k e -> Int
forall (t :: * -> *) a. Foldable t => t a -> Int
length

instance (Eq k, Hashable k) => Map (HashMap k e) k e
  where
    toMap' :: e -> [(k, e)] -> HashMap k e
toMap' = ([(k, e)] -> HashMap k e) -> e -> [(k, e)] -> HashMap k e
forall a b. a -> b -> a
const [(k, e)] -> HashMap k e
forall map key e. Map map key e => [(key, e)] -> map
toMap
    toMap :: [(k, e)] -> HashMap k e
toMap  = [(k, e)] -> HashMap k e
forall k e. (Eq k, Hashable k) => [(k, e)] -> HashMap k e
H.fromList
    assocs :: HashMap k e -> [(k, e)]
assocs = HashMap k e -> [(k, e)]
forall k v. HashMap k v -> [(k, v)]
H.toList
    
    kfoldl :: (k -> b -> e -> b) -> b -> HashMap k e -> b
kfoldl  = (b -> k -> e -> b) -> b -> HashMap k e -> b
forall a k v. (a -> k -> v -> a) -> a -> HashMap k v -> a
H.foldlWithKey' ((b -> k -> e -> b) -> b -> HashMap k e -> b)
-> ((k -> b -> e -> b) -> b -> k -> e -> b)
-> (k -> b -> e -> b)
-> b
-> HashMap k e
-> b
forall b c a. (b -> c) -> (a -> b) -> a -> c
. (k -> b -> e -> b) -> b -> k -> e -> b
forall a b c. (a -> b -> c) -> b -> a -> c
flip
    kfoldr :: (k -> e -> b -> b) -> b -> HashMap k e -> b
kfoldr  = (k -> e -> b -> b) -> b -> HashMap k e -> b
forall k v a. (k -> v -> a -> a) -> a -> HashMap k v -> a
H.foldrWithKey
    
    filter' :: (k -> e -> Bool) -> HashMap k e -> HashMap k e
filter' = (k -> e -> Bool) -> HashMap k e -> HashMap k e
forall k v. (k -> v -> Bool) -> HashMap k v -> HashMap k v
H.filterWithKey
    member' :: k -> HashMap k e -> Bool
member' = k -> HashMap k e -> Bool
forall k e. (Eq k, Hashable k) => k -> HashMap k e -> Bool
H.member
    insert' :: k -> e -> HashMap k e -> HashMap k e
insert' = k -> e -> HashMap k e -> HashMap k e
forall k e.
(Eq k, Hashable k) =>
k -> e -> HashMap k e -> HashMap k e
H.insert
    delete' :: k -> HashMap k e -> HashMap k e
delete' = k -> HashMap k e -> HashMap k e
forall k e. (Eq k, Hashable k) => k -> HashMap k e -> HashMap k e
H.delete
    
    -- | Throws 'IndexException' instead 'error' call.
    (!)  = e -> Maybe e -> e
forall a. a -> Maybe a -> a
fromMaybe (String -> e
forall a. String -> a
undEx String
"(!) {HashMap k e}") (Maybe e -> e)
-> (HashMap k e -> k -> Maybe e) -> HashMap k e -> k -> e
forall c d a b. (c -> d) -> (a -> b -> c) -> a -> b -> d
... HashMap k e -> k -> Maybe e
forall map key e. Map map key e => map -> key -> Maybe e
(!?)
    // :: HashMap k e -> [(k, e)] -> HashMap k e
(//) = [(k, e)] -> HashMap k e
forall map key e. Map map key e => [(key, e)] -> map
toMap ([(k, e)] -> HashMap k e)
-> (HashMap k e -> [(k, e)] -> [(k, e)])
-> HashMap k e
-> [(k, e)]
-> HashMap k e
forall c d a b. (c -> d) -> (a -> b -> c) -> a -> b -> d
... [(k, e)] -> [(k, e)] -> [(k, e)]
forall l e. Linear l e => l -> l -> l
(++) ([(k, e)] -> [(k, e)] -> [(k, e)])
-> (HashMap k e -> [(k, e)]) -> HashMap k e -> [(k, e)] -> [(k, e)]
forall b c a. (b -> c) -> (a -> b) -> a -> c
. HashMap k e -> [(k, e)]
forall map key e. Map map key e => map -> [(key, e)]
assocs
    !? :: HashMap k e -> k -> Maybe e
(!?) = (k -> HashMap k e -> Maybe e) -> HashMap k e -> k -> Maybe e
forall a b c. (a -> b -> c) -> b -> a -> c
flip k -> HashMap k e -> Maybe e
forall k v. (Eq k, Hashable k) => k -> HashMap k v -> Maybe v
H.lookup
    keys :: HashMap k e -> [k]
keys = HashMap k e -> [k]
forall k v. HashMap k v -> [k]
H.keys

--------------------------------------------------------------------------------

undEx :: String -> a
undEx :: String -> a
undEx =  IndexException -> a
forall a e. Exception e => e -> a
throw (IndexException -> a) -> (String -> IndexException) -> String -> a
forall b c a. (b -> c) -> (a -> b) -> a -> c
. String -> IndexException
UndefinedValue (String -> IndexException)
-> (String -> String) -> String -> IndexException
forall b c a. (b -> c) -> (a -> b) -> a -> c
. String -> String -> String
showString String
"in SDP.HashMap.Strict."