{-# LANGUAGE FlexibleInstances     #-}
{-# LANGUAGE MultiParamTypeClasses #-}

{-# OPTIONS_GHC -fno-warn-orphans #-}
module Data.Strict.HashMap.Internal where

import Data.HashMap.Lazy                  as L
import Data.Strict.HashMap.Autogen.Strict as S

import Data.Binary
import Data.Hashable
import Data.Foldable.WithIndex
import Data.Functor.WithIndex
import Data.Traversable.WithIndex
import Data.Strict.Classes

instance (Eq k, Hashable k) => Strict (L.HashMap k v) (S.HashMap k v) where
  toStrict :: HashMap k v -> HashMap k v
toStrict = [(k, v)] -> HashMap k v
forall k v. (Eq k, Hashable k) => [(k, v)] -> HashMap k v
S.fromList ([(k, v)] -> HashMap k v)
-> (HashMap k v -> [(k, v)]) -> HashMap k v -> HashMap k v
forall b c a. (b -> c) -> (a -> b) -> a -> c
. HashMap k v -> [(k, v)]
forall k v. HashMap k v -> [(k, v)]
L.toList
  toLazy :: HashMap k v -> HashMap k v
toLazy = [(k, v)] -> HashMap k v
forall k v. (Eq k, Hashable k) => [(k, v)] -> HashMap k v
L.fromList ([(k, v)] -> HashMap k v)
-> (HashMap k v -> [(k, v)]) -> HashMap k v -> HashMap k v
forall b c a. (b -> c) -> (a -> b) -> a -> c
. HashMap k v -> [(k, v)]
forall k v. HashMap k v -> [(k, v)]
S.toList
  {-# INLINE toStrict #-}
  {-# INLINE toLazy #-}

-- code copied from indexed-traversable-instances

instance FunctorWithIndex k (S.HashMap k) where
  imap :: (k -> a -> b) -> HashMap k a -> HashMap k b
imap = (k -> a -> b) -> HashMap k a -> HashMap k b
forall k a b. (k -> a -> b) -> HashMap k a -> HashMap k b
S.mapWithKey
  {-# INLINE imap #-}

instance FoldableWithIndex k (S.HashMap k) where
  ifoldr :: (k -> a -> b -> b) -> b -> HashMap k a -> b
ifoldr  = (k -> a -> b -> b) -> b -> HashMap k a -> b
forall k a b. (k -> a -> b -> b) -> b -> HashMap k a -> b
S.foldrWithKey
  {-# INLINE ifoldr #-}
  ifoldl' :: (k -> b -> a -> b) -> b -> HashMap k a -> b
ifoldl' = (b -> k -> a -> b) -> b -> HashMap k a -> b
forall a k v. (a -> k -> v -> a) -> a -> HashMap k v -> a
S.foldlWithKey' ((b -> k -> a -> b) -> b -> HashMap k a -> b)
-> ((k -> b -> a -> b) -> b -> k -> a -> b)
-> (k -> b -> a -> b)
-> b
-> HashMap k a
-> b
forall b c a. (b -> c) -> (a -> b) -> a -> c
. (k -> b -> a -> b) -> b -> k -> a -> b
forall a b c. (a -> b -> c) -> b -> a -> c
flip
  {-# INLINE ifoldl' #-}

instance TraversableWithIndex k (S.HashMap k) where
  itraverse :: (k -> a -> f b) -> HashMap k a -> f (HashMap k b)
itraverse = (k -> a -> f b) -> HashMap k a -> f (HashMap k b)
forall (f :: * -> *) k v1 v2.
Applicative f =>
(k -> v1 -> f v2) -> HashMap k v1 -> f (HashMap k v2)
S.traverseWithKey
  {-# INLINE itraverse #-}

-- code copied from binary-instances

instance (Hashable k, Eq k, Binary k, Binary v) => Binary (S.HashMap k v) where
    get :: Get (HashMap k v)
get = ([(k, v)] -> HashMap k v) -> Get [(k, v)] -> Get (HashMap k v)
forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
fmap [(k, v)] -> HashMap k v
forall k v. (Eq k, Hashable k) => [(k, v)] -> HashMap k v
S.fromList Get [(k, v)]
forall t. Binary t => Get t
get
    put :: HashMap k v -> Put
put = [(k, v)] -> Put
forall t. Binary t => t -> Put
put ([(k, v)] -> Put)
-> (HashMap k v -> [(k, v)]) -> HashMap k v -> Put
forall b c a. (b -> c) -> (a -> b) -> a -> c
. HashMap k v -> [(k, v)]
forall k v. HashMap k v -> [(k, v)]
S.toList