module Unison.Util.EnumContainers
  ( EnumMap,
    EnumSet,
    EnumKey (..),
    mapFromList,
    setFromList,
    setToList,
    mapSingleton,
    setSingleton,
    mapInsert,
    unionWith,
    intersectionWith,
    hasKey,
    keys,
    keysSet,
    restrictKeys,
    withoutKeys,
    member,
    lookup,
    lookupWithDefault,
    mapWithKey,
    foldMapWithKey,
    mapToList,
    (!),
    findMin,
    interverse,
    traverseSet_,
    traverseWithKey,
    setSize,
  )
where

import Data.Bifunctor
import Data.IntMap.Strict qualified as IM
import Data.IntSet qualified as IS
import Data.Word (Word16, Word64)
import Prelude hiding (lookup)

class EnumKey k where
  keyToInt :: k -> Int
  intToKey :: Int -> k

instance EnumKey Word64 where
  keyToInt :: Word64 -> Int
keyToInt Word64
e = Word64 -> Int
forall a b. (Integral a, Num b) => a -> b
fromIntegral Word64
e
  intToKey :: Int -> Word64
intToKey Int
i = Int -> Word64
forall a b. (Integral a, Num b) => a -> b
fromIntegral Int
i

instance EnumKey Word16 where
  keyToInt :: Word16 -> Int
keyToInt Word16
e = Word16 -> Int
forall a b. (Integral a, Num b) => a -> b
fromIntegral Word16
e
  intToKey :: Int -> Word16
intToKey Int
i = Int -> Word16
forall a b. (Integral a, Num b) => a -> b
fromIntegral Int
i

newtype EnumMap k a = EM (IM.IntMap a)
  deriving stock
    ( (forall a b. (a -> b) -> EnumMap k a -> EnumMap k b)
-> (forall a b. a -> EnumMap k b -> EnumMap k a)
-> Functor (EnumMap k)
forall a b. a -> EnumMap k b -> EnumMap k a
forall a b. (a -> b) -> EnumMap k a -> EnumMap k b
forall k a b. a -> EnumMap k b -> EnumMap k a
forall k a b. (a -> b) -> EnumMap k a -> EnumMap k b
forall (f :: * -> *).
(forall a b. (a -> b) -> f a -> f b)
-> (forall a b. a -> f b -> f a) -> Functor f
$cfmap :: forall k a b. (a -> b) -> EnumMap k a -> EnumMap k b
fmap :: forall a b. (a -> b) -> EnumMap k a -> EnumMap k b
$c<$ :: forall k a b. a -> EnumMap k b -> EnumMap k a
<$ :: forall a b. a -> EnumMap k b -> EnumMap k a
Functor,
      (forall m. Monoid m => EnumMap k m -> m)
-> (forall m a. Monoid m => (a -> m) -> EnumMap k a -> m)
-> (forall m a. Monoid m => (a -> m) -> EnumMap k a -> m)
-> (forall a b. (a -> b -> b) -> b -> EnumMap k a -> b)
-> (forall a b. (a -> b -> b) -> b -> EnumMap k a -> b)
-> (forall b a. (b -> a -> b) -> b -> EnumMap k a -> b)
-> (forall b a. (b -> a -> b) -> b -> EnumMap k a -> b)
-> (forall a. (a -> a -> a) -> EnumMap k a -> a)
-> (forall a. (a -> a -> a) -> EnumMap k a -> a)
-> (forall a. EnumMap k a -> [a])
-> (forall a. EnumMap k a -> Bool)
-> (forall a. EnumMap k a -> Int)
-> (forall a. Eq a => a -> EnumMap k a -> Bool)
-> (forall a. Ord a => EnumMap k a -> a)
-> (forall a. Ord a => EnumMap k a -> a)
-> (forall a. Num a => EnumMap k a -> a)
-> (forall a. Num a => EnumMap k a -> a)
-> Foldable (EnumMap k)
forall a. Eq a => a -> EnumMap k a -> Bool
forall a. Num a => EnumMap k a -> a
forall a. Ord a => EnumMap k a -> a
forall m. Monoid m => EnumMap k m -> m
forall a. EnumMap k a -> Bool
forall a. EnumMap k a -> Int
forall a. EnumMap k a -> [a]
forall a. (a -> a -> a) -> EnumMap k a -> a
forall k a. Eq a => a -> EnumMap k a -> Bool
forall k a. Num a => EnumMap k a -> a
forall k a. Ord a => EnumMap k a -> a
forall m a. Monoid m => (a -> m) -> EnumMap k a -> m
forall k m. Monoid m => EnumMap k m -> m
forall k a. EnumMap k a -> Bool
forall k a. EnumMap k a -> Int
forall k a. EnumMap k a -> [a]
forall b a. (b -> a -> b) -> b -> EnumMap k a -> b
forall a b. (a -> b -> b) -> b -> EnumMap k a -> b
forall k a. (a -> a -> a) -> EnumMap k a -> a
forall k m a. Monoid m => (a -> m) -> EnumMap k a -> m
forall k b a. (b -> a -> b) -> b -> EnumMap k a -> b
forall k a b. (a -> b -> b) -> b -> EnumMap k a -> b
forall (t :: * -> *).
(forall m. Monoid m => t m -> m)
-> (forall m a. Monoid m => (a -> m) -> t a -> m)
-> (forall m a. Monoid m => (a -> m) -> t a -> m)
-> (forall a b. (a -> b -> b) -> b -> t a -> b)
-> (forall a b. (a -> b -> b) -> b -> t a -> b)
-> (forall b a. (b -> a -> b) -> b -> t a -> b)
-> (forall b a. (b -> a -> b) -> b -> t a -> b)
-> (forall a. (a -> a -> a) -> t a -> a)
-> (forall a. (a -> a -> a) -> t a -> a)
-> (forall a. t a -> [a])
-> (forall a. t a -> Bool)
-> (forall a. t a -> Int)
-> (forall a. Eq a => a -> t a -> Bool)
-> (forall a. Ord a => t a -> a)
-> (forall a. Ord a => t a -> a)
-> (forall a. Num a => t a -> a)
-> (forall a. Num a => t a -> a)
-> Foldable t
$cfold :: forall k m. Monoid m => EnumMap k m -> m
fold :: forall m. Monoid m => EnumMap k m -> m
$cfoldMap :: forall k m a. Monoid m => (a -> m) -> EnumMap k a -> m
foldMap :: forall m a. Monoid m => (a -> m) -> EnumMap k a -> m
$cfoldMap' :: forall k m a. Monoid m => (a -> m) -> EnumMap k a -> m
foldMap' :: forall m a. Monoid m => (a -> m) -> EnumMap k a -> m
$cfoldr :: forall k a b. (a -> b -> b) -> b -> EnumMap k a -> b
foldr :: forall a b. (a -> b -> b) -> b -> EnumMap k a -> b
$cfoldr' :: forall k a b. (a -> b -> b) -> b -> EnumMap k a -> b
foldr' :: forall a b. (a -> b -> b) -> b -> EnumMap k a -> b
$cfoldl :: forall k b a. (b -> a -> b) -> b -> EnumMap k a -> b
foldl :: forall b a. (b -> a -> b) -> b -> EnumMap k a -> b
$cfoldl' :: forall k b a. (b -> a -> b) -> b -> EnumMap k a -> b
foldl' :: forall b a. (b -> a -> b) -> b -> EnumMap k a -> b
$cfoldr1 :: forall k a. (a -> a -> a) -> EnumMap k a -> a
foldr1 :: forall a. (a -> a -> a) -> EnumMap k a -> a
$cfoldl1 :: forall k a. (a -> a -> a) -> EnumMap k a -> a
foldl1 :: forall a. (a -> a -> a) -> EnumMap k a -> a
$ctoList :: forall k a. EnumMap k a -> [a]
toList :: forall a. EnumMap k a -> [a]
$cnull :: forall k a. EnumMap k a -> Bool
null :: forall a. EnumMap k a -> Bool
$clength :: forall k a. EnumMap k a -> Int
length :: forall a. EnumMap k a -> Int
$celem :: forall k a. Eq a => a -> EnumMap k a -> Bool
elem :: forall a. Eq a => a -> EnumMap k a -> Bool
$cmaximum :: forall k a. Ord a => EnumMap k a -> a
maximum :: forall a. Ord a => EnumMap k a -> a
$cminimum :: forall k a. Ord a => EnumMap k a -> a
minimum :: forall a. Ord a => EnumMap k a -> a
$csum :: forall k a. Num a => EnumMap k a -> a
sum :: forall a. Num a => EnumMap k a -> a
$cproduct :: forall k a. Num a => EnumMap k a -> a
product :: forall a. Num a => EnumMap k a -> a
Foldable,
      Functor (EnumMap k)
Foldable (EnumMap k)
(Functor (EnumMap k), Foldable (EnumMap k)) =>
(forall (f :: * -> *) a b.
 Applicative f =>
 (a -> f b) -> EnumMap k a -> f (EnumMap k b))
-> (forall (f :: * -> *) a.
    Applicative f =>
    EnumMap k (f a) -> f (EnumMap k a))
-> (forall (m :: * -> *) a b.
    Monad m =>
    (a -> m b) -> EnumMap k a -> m (EnumMap k b))
-> (forall (m :: * -> *) a.
    Monad m =>
    EnumMap k (m a) -> m (EnumMap k a))
-> Traversable (EnumMap k)
forall k. Functor (EnumMap k)
forall k. Foldable (EnumMap k)
forall k (m :: * -> *) a.
Monad m =>
EnumMap k (m a) -> m (EnumMap k a)
forall k (f :: * -> *) a.
Applicative f =>
EnumMap k (f a) -> f (EnumMap k a)
forall k (m :: * -> *) a b.
Monad m =>
(a -> m b) -> EnumMap k a -> m (EnumMap k b)
forall k (f :: * -> *) a b.
Applicative f =>
(a -> f b) -> EnumMap k a -> f (EnumMap k b)
forall (t :: * -> *).
(Functor t, Foldable t) =>
(forall (f :: * -> *) a b.
 Applicative f =>
 (a -> f b) -> t a -> f (t b))
-> (forall (f :: * -> *) a. Applicative f => t (f a) -> f (t a))
-> (forall (m :: * -> *) a b.
    Monad m =>
    (a -> m b) -> t a -> m (t b))
-> (forall (m :: * -> *) a. Monad m => t (m a) -> m (t a))
-> Traversable t
forall (m :: * -> *) a.
Monad m =>
EnumMap k (m a) -> m (EnumMap k a)
forall (f :: * -> *) a.
Applicative f =>
EnumMap k (f a) -> f (EnumMap k a)
forall (m :: * -> *) a b.
Monad m =>
(a -> m b) -> EnumMap k a -> m (EnumMap k b)
forall (f :: * -> *) a b.
Applicative f =>
(a -> f b) -> EnumMap k a -> f (EnumMap k b)
$ctraverse :: forall k (f :: * -> *) a b.
Applicative f =>
(a -> f b) -> EnumMap k a -> f (EnumMap k b)
traverse :: forall (f :: * -> *) a b.
Applicative f =>
(a -> f b) -> EnumMap k a -> f (EnumMap k b)
$csequenceA :: forall k (f :: * -> *) a.
Applicative f =>
EnumMap k (f a) -> f (EnumMap k a)
sequenceA :: forall (f :: * -> *) a.
Applicative f =>
EnumMap k (f a) -> f (EnumMap k a)
$cmapM :: forall k (m :: * -> *) a b.
Monad m =>
(a -> m b) -> EnumMap k a -> m (EnumMap k b)
mapM :: forall (m :: * -> *) a b.
Monad m =>
(a -> m b) -> EnumMap k a -> m (EnumMap k b)
$csequence :: forall k (m :: * -> *) a.
Monad m =>
EnumMap k (m a) -> m (EnumMap k a)
sequence :: forall (m :: * -> *) a.
Monad m =>
EnumMap k (m a) -> m (EnumMap k a)
Traversable,
      Int -> EnumMap k a -> ShowS
[EnumMap k a] -> ShowS
EnumMap k a -> String
(Int -> EnumMap k a -> ShowS)
-> (EnumMap k a -> String)
-> ([EnumMap k a] -> ShowS)
-> Show (EnumMap k a)
forall a.
(Int -> a -> ShowS) -> (a -> String) -> ([a] -> ShowS) -> Show a
forall k a. Show a => Int -> EnumMap k a -> ShowS
forall k a. Show a => [EnumMap k a] -> ShowS
forall k a. Show a => EnumMap k a -> String
$cshowsPrec :: forall k a. Show a => Int -> EnumMap k a -> ShowS
showsPrec :: Int -> EnumMap k a -> ShowS
$cshow :: forall k a. Show a => EnumMap k a -> String
show :: EnumMap k a -> String
$cshowList :: forall k a. Show a => [EnumMap k a] -> ShowS
showList :: [EnumMap k a] -> ShowS
Show,
      EnumMap k a -> EnumMap k a -> Bool
(EnumMap k a -> EnumMap k a -> Bool)
-> (EnumMap k a -> EnumMap k a -> Bool) -> Eq (EnumMap k a)
forall a. (a -> a -> Bool) -> (a -> a -> Bool) -> Eq a
forall k a. Eq a => EnumMap k a -> EnumMap k a -> Bool
$c== :: forall k a. Eq a => EnumMap k a -> EnumMap k a -> Bool
== :: EnumMap k a -> EnumMap k a -> Bool
$c/= :: forall k a. Eq a => EnumMap k a -> EnumMap k a -> Bool
/= :: EnumMap k a -> EnumMap k a -> Bool
Eq,
      Eq (EnumMap k a)
Eq (EnumMap k a) =>
(EnumMap k a -> EnumMap k a -> Ordering)
-> (EnumMap k a -> EnumMap k a -> Bool)
-> (EnumMap k a -> EnumMap k a -> Bool)
-> (EnumMap k a -> EnumMap k a -> Bool)
-> (EnumMap k a -> EnumMap k a -> Bool)
-> (EnumMap k a -> EnumMap k a -> EnumMap k a)
-> (EnumMap k a -> EnumMap k a -> EnumMap k a)
-> Ord (EnumMap k a)
EnumMap k a -> EnumMap k a -> Bool
EnumMap k a -> EnumMap k a -> Ordering
EnumMap k a -> EnumMap k a -> EnumMap k a
forall a.
Eq a =>
(a -> a -> Ordering)
-> (a -> a -> Bool)
-> (a -> a -> Bool)
-> (a -> a -> Bool)
-> (a -> a -> Bool)
-> (a -> a -> a)
-> (a -> a -> a)
-> Ord a
forall k a. Ord a => Eq (EnumMap k a)
forall k a. Ord a => EnumMap k a -> EnumMap k a -> Bool
forall k a. Ord a => EnumMap k a -> EnumMap k a -> Ordering
forall k a. Ord a => EnumMap k a -> EnumMap k a -> EnumMap k a
$ccompare :: forall k a. Ord a => EnumMap k a -> EnumMap k a -> Ordering
compare :: EnumMap k a -> EnumMap k a -> Ordering
$c< :: forall k a. Ord a => EnumMap k a -> EnumMap k a -> Bool
< :: EnumMap k a -> EnumMap k a -> Bool
$c<= :: forall k a. Ord a => EnumMap k a -> EnumMap k a -> Bool
<= :: EnumMap k a -> EnumMap k a -> Bool
$c> :: forall k a. Ord a => EnumMap k a -> EnumMap k a -> Bool
> :: EnumMap k a -> EnumMap k a -> Bool
$c>= :: forall k a. Ord a => EnumMap k a -> EnumMap k a -> Bool
>= :: EnumMap k a -> EnumMap k a -> Bool
$cmax :: forall k a. Ord a => EnumMap k a -> EnumMap k a -> EnumMap k a
max :: EnumMap k a -> EnumMap k a -> EnumMap k a
$cmin :: forall k a. Ord a => EnumMap k a -> EnumMap k a -> EnumMap k a
min :: EnumMap k a -> EnumMap k a -> EnumMap k a
Ord
    )
  deriving newtype
    ( Semigroup (EnumMap k a)
EnumMap k a
Semigroup (EnumMap k a) =>
EnumMap k a
-> (EnumMap k a -> EnumMap k a -> EnumMap k a)
-> ([EnumMap k a] -> EnumMap k a)
-> Monoid (EnumMap k a)
[EnumMap k a] -> EnumMap k a
EnumMap k a -> EnumMap k a -> EnumMap k a
forall a.
Semigroup a =>
a -> (a -> a -> a) -> ([a] -> a) -> Monoid a
forall k a. Semigroup (EnumMap k a)
forall k a. EnumMap k a
forall k a. [EnumMap k a] -> EnumMap k a
forall k a. EnumMap k a -> EnumMap k a -> EnumMap k a
$cmempty :: forall k a. EnumMap k a
mempty :: EnumMap k a
$cmappend :: forall k a. EnumMap k a -> EnumMap k a -> EnumMap k a
mappend :: EnumMap k a -> EnumMap k a -> EnumMap k a
$cmconcat :: forall k a. [EnumMap k a] -> EnumMap k a
mconcat :: [EnumMap k a] -> EnumMap k a
Monoid,
      NonEmpty (EnumMap k a) -> EnumMap k a
EnumMap k a -> EnumMap k a -> EnumMap k a
(EnumMap k a -> EnumMap k a -> EnumMap k a)
-> (NonEmpty (EnumMap k a) -> EnumMap k a)
-> (forall b. Integral b => b -> EnumMap k a -> EnumMap k a)
-> Semigroup (EnumMap k a)
forall b. Integral b => b -> EnumMap k a -> EnumMap k a
forall a.
(a -> a -> a)
-> (NonEmpty a -> a)
-> (forall b. Integral b => b -> a -> a)
-> Semigroup a
forall k a. NonEmpty (EnumMap k a) -> EnumMap k a
forall k a. EnumMap k a -> EnumMap k a -> EnumMap k a
forall k a b. Integral b => b -> EnumMap k a -> EnumMap k a
$c<> :: forall k a. EnumMap k a -> EnumMap k a -> EnumMap k a
<> :: EnumMap k a -> EnumMap k a -> EnumMap k a
$csconcat :: forall k a. NonEmpty (EnumMap k a) -> EnumMap k a
sconcat :: NonEmpty (EnumMap k a) -> EnumMap k a
$cstimes :: forall k a b. Integral b => b -> EnumMap k a -> EnumMap k a
stimes :: forall b. Integral b => b -> EnumMap k a -> EnumMap k a
Semigroup
    )

newtype EnumSet k = ES IS.IntSet
  deriving stock
    ( Int -> EnumSet k -> ShowS
[EnumSet k] -> ShowS
EnumSet k -> String
(Int -> EnumSet k -> ShowS)
-> (EnumSet k -> String)
-> ([EnumSet k] -> ShowS)
-> Show (EnumSet k)
forall k. Int -> EnumSet k -> ShowS
forall k. [EnumSet k] -> ShowS
forall k. EnumSet k -> String
forall a.
(Int -> a -> ShowS) -> (a -> String) -> ([a] -> ShowS) -> Show a
$cshowsPrec :: forall k. Int -> EnumSet k -> ShowS
showsPrec :: Int -> EnumSet k -> ShowS
$cshow :: forall k. EnumSet k -> String
show :: EnumSet k -> String
$cshowList :: forall k. [EnumSet k] -> ShowS
showList :: [EnumSet k] -> ShowS
Show,
      EnumSet k -> EnumSet k -> Bool
(EnumSet k -> EnumSet k -> Bool)
-> (EnumSet k -> EnumSet k -> Bool) -> Eq (EnumSet k)
forall k. EnumSet k -> EnumSet k -> Bool
forall a. (a -> a -> Bool) -> (a -> a -> Bool) -> Eq a
$c== :: forall k. EnumSet k -> EnumSet k -> Bool
== :: EnumSet k -> EnumSet k -> Bool
$c/= :: forall k. EnumSet k -> EnumSet k -> Bool
/= :: EnumSet k -> EnumSet k -> Bool
Eq,
      Eq (EnumSet k)
Eq (EnumSet k) =>
(EnumSet k -> EnumSet k -> Ordering)
-> (EnumSet k -> EnumSet k -> Bool)
-> (EnumSet k -> EnumSet k -> Bool)
-> (EnumSet k -> EnumSet k -> Bool)
-> (EnumSet k -> EnumSet k -> Bool)
-> (EnumSet k -> EnumSet k -> EnumSet k)
-> (EnumSet k -> EnumSet k -> EnumSet k)
-> Ord (EnumSet k)
EnumSet k -> EnumSet k -> Bool
EnumSet k -> EnumSet k -> Ordering
EnumSet k -> EnumSet k -> EnumSet k
forall k. Eq (EnumSet k)
forall a.
Eq a =>
(a -> a -> Ordering)
-> (a -> a -> Bool)
-> (a -> a -> Bool)
-> (a -> a -> Bool)
-> (a -> a -> Bool)
-> (a -> a -> a)
-> (a -> a -> a)
-> Ord a
forall k. EnumSet k -> EnumSet k -> Bool
forall k. EnumSet k -> EnumSet k -> Ordering
forall k. EnumSet k -> EnumSet k -> EnumSet k
$ccompare :: forall k. EnumSet k -> EnumSet k -> Ordering
compare :: EnumSet k -> EnumSet k -> Ordering
$c< :: forall k. EnumSet k -> EnumSet k -> Bool
< :: EnumSet k -> EnumSet k -> Bool
$c<= :: forall k. EnumSet k -> EnumSet k -> Bool
<= :: EnumSet k -> EnumSet k -> Bool
$c> :: forall k. EnumSet k -> EnumSet k -> Bool
> :: EnumSet k -> EnumSet k -> Bool
$c>= :: forall k. EnumSet k -> EnumSet k -> Bool
>= :: EnumSet k -> EnumSet k -> Bool
$cmax :: forall k. EnumSet k -> EnumSet k -> EnumSet k
max :: EnumSet k -> EnumSet k -> EnumSet k
$cmin :: forall k. EnumSet k -> EnumSet k -> EnumSet k
min :: EnumSet k -> EnumSet k -> EnumSet k
Ord
    )
  deriving newtype
    ( Semigroup (EnumSet k)
EnumSet k
Semigroup (EnumSet k) =>
EnumSet k
-> (EnumSet k -> EnumSet k -> EnumSet k)
-> ([EnumSet k] -> EnumSet k)
-> Monoid (EnumSet k)
[EnumSet k] -> EnumSet k
EnumSet k -> EnumSet k -> EnumSet k
forall k. Semigroup (EnumSet k)
forall k. EnumSet k
forall a.
Semigroup a =>
a -> (a -> a -> a) -> ([a] -> a) -> Monoid a
forall k. [EnumSet k] -> EnumSet k
forall k. EnumSet k -> EnumSet k -> EnumSet k
$cmempty :: forall k. EnumSet k
mempty :: EnumSet k
$cmappend :: forall k. EnumSet k -> EnumSet k -> EnumSet k
mappend :: EnumSet k -> EnumSet k -> EnumSet k
$cmconcat :: forall k. [EnumSet k] -> EnumSet k
mconcat :: [EnumSet k] -> EnumSet k
Monoid,
      NonEmpty (EnumSet k) -> EnumSet k
EnumSet k -> EnumSet k -> EnumSet k
(EnumSet k -> EnumSet k -> EnumSet k)
-> (NonEmpty (EnumSet k) -> EnumSet k)
-> (forall b. Integral b => b -> EnumSet k -> EnumSet k)
-> Semigroup (EnumSet k)
forall b. Integral b => b -> EnumSet k -> EnumSet k
forall k. NonEmpty (EnumSet k) -> EnumSet k
forall k. EnumSet k -> EnumSet k -> EnumSet k
forall a.
(a -> a -> a)
-> (NonEmpty a -> a)
-> (forall b. Integral b => b -> a -> a)
-> Semigroup a
forall k b. Integral b => b -> EnumSet k -> EnumSet k
$c<> :: forall k. EnumSet k -> EnumSet k -> EnumSet k
<> :: EnumSet k -> EnumSet k -> EnumSet k
$csconcat :: forall k. NonEmpty (EnumSet k) -> EnumSet k
sconcat :: NonEmpty (EnumSet k) -> EnumSet k
$cstimes :: forall k b. Integral b => b -> EnumSet k -> EnumSet k
stimes :: forall b. Integral b => b -> EnumSet k -> EnumSet k
Semigroup
    )

mapFromList :: (EnumKey k) => [(k, a)] -> EnumMap k a
mapFromList :: forall k a. EnumKey k => [(k, a)] -> EnumMap k a
mapFromList = IntMap a -> EnumMap k a
forall k a. IntMap a -> EnumMap k a
EM (IntMap a -> EnumMap k a)
-> ([(k, a)] -> IntMap a) -> [(k, a)] -> EnumMap k a
forall b c a. (b -> c) -> (a -> b) -> a -> c
. [(Int, a)] -> IntMap a
forall a. [(Int, a)] -> IntMap a
IM.fromList ([(Int, a)] -> IntMap a)
-> ([(k, a)] -> [(Int, a)]) -> [(k, a)] -> IntMap a
forall b c a. (b -> c) -> (a -> b) -> a -> c
. ((k, a) -> (Int, a)) -> [(k, a)] -> [(Int, a)]
forall a b. (a -> b) -> [a] -> [b]
forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
fmap ((k -> Int) -> (k, a) -> (Int, a)
forall a b c. (a -> b) -> (a, c) -> (b, c)
forall (p :: * -> * -> *) a b c.
Bifunctor p =>
(a -> b) -> p a c -> p b c
first k -> Int
forall k. EnumKey k => k -> Int
keyToInt)

setFromList :: (EnumKey k) => [k] -> EnumSet k
setFromList :: forall k. EnumKey k => [k] -> EnumSet k
setFromList = IntSet -> EnumSet k
forall k. IntSet -> EnumSet k
ES (IntSet -> EnumSet k) -> ([k] -> IntSet) -> [k] -> EnumSet k
forall b c a. (b -> c) -> (a -> b) -> a -> c
. [Int] -> IntSet
IS.fromList ([Int] -> IntSet) -> ([k] -> [Int]) -> [k] -> IntSet
forall b c a. (b -> c) -> (a -> b) -> a -> c
. (k -> Int) -> [k] -> [Int]
forall a b. (a -> b) -> [a] -> [b]
forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
fmap k -> Int
forall k. EnumKey k => k -> Int
keyToInt

setToList :: (EnumKey k) => EnumSet k -> [k]
setToList :: forall k. EnumKey k => EnumSet k -> [k]
setToList (ES IntSet
s) = Int -> k
forall k. EnumKey k => Int -> k
intToKey (Int -> k) -> [Int] -> [k]
forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
<$> IntSet -> [Int]
IS.toList IntSet
s

mapSingleton :: (EnumKey k) => k -> a -> EnumMap k a
mapSingleton :: forall k a. EnumKey k => k -> a -> EnumMap k a
mapSingleton k
e a
a = IntMap a -> EnumMap k a
forall k a. IntMap a -> EnumMap k a
EM (IntMap a -> EnumMap k a) -> IntMap a -> EnumMap k a
forall a b. (a -> b) -> a -> b
$ Int -> a -> IntMap a
forall a. Int -> a -> IntMap a
IM.singleton (k -> Int
forall k. EnumKey k => k -> Int
keyToInt k
e) a
a

setSingleton :: (EnumKey k) => k -> EnumSet k
setSingleton :: forall k. EnumKey k => k -> EnumSet k
setSingleton k
e = IntSet -> EnumSet k
forall k. IntSet -> EnumSet k
ES (IntSet -> EnumSet k) -> (Int -> IntSet) -> Int -> EnumSet k
forall b c a. (b -> c) -> (a -> b) -> a -> c
. Int -> IntSet
IS.singleton (Int -> EnumSet k) -> Int -> EnumSet k
forall a b. (a -> b) -> a -> b
$ k -> Int
forall k. EnumKey k => k -> Int
keyToInt k
e

mapInsert :: (EnumKey k) => k -> a -> EnumMap k a -> EnumMap k a
mapInsert :: forall k a. EnumKey k => k -> a -> EnumMap k a -> EnumMap k a
mapInsert k
e a
x (EM IntMap a
m) = IntMap a -> EnumMap k a
forall k a. IntMap a -> EnumMap k a
EM (IntMap a -> EnumMap k a) -> IntMap a -> EnumMap k a
forall a b. (a -> b) -> a -> b
$ Int -> a -> IntMap a -> IntMap a
forall a. Int -> a -> IntMap a -> IntMap a
IM.insert (k -> Int
forall k. EnumKey k => k -> Int
keyToInt k
e) a
x IntMap a
m

unionWith ::
  (EnumKey k) =>
  (a -> a -> a) ->
  EnumMap k a ->
  EnumMap k a ->
  EnumMap k a
unionWith :: forall k a.
EnumKey k =>
(a -> a -> a) -> EnumMap k a -> EnumMap k a -> EnumMap k a
unionWith a -> a -> a
f (EM IntMap a
l) (EM IntMap a
r) = IntMap a -> EnumMap k a
forall k a. IntMap a -> EnumMap k a
EM (IntMap a -> EnumMap k a) -> IntMap a -> EnumMap k a
forall a b. (a -> b) -> a -> b
$ (a -> a -> a) -> IntMap a -> IntMap a -> IntMap a
forall a. (a -> a -> a) -> IntMap a -> IntMap a -> IntMap a
IM.unionWith a -> a -> a
f IntMap a
l IntMap a
r

intersectionWith ::
  (a -> b -> c) ->
  EnumMap k a ->
  EnumMap k b ->
  EnumMap k c
intersectionWith :: forall a b c k.
(a -> b -> c) -> EnumMap k a -> EnumMap k b -> EnumMap k c
intersectionWith a -> b -> c
f (EM IntMap a
l) (EM IntMap b
r) = IntMap c -> EnumMap k c
forall k a. IntMap a -> EnumMap k a
EM (IntMap c -> EnumMap k c) -> IntMap c -> EnumMap k c
forall a b. (a -> b) -> a -> b
$ (a -> b -> c) -> IntMap a -> IntMap b -> IntMap c
forall a b c. (a -> b -> c) -> IntMap a -> IntMap b -> IntMap c
IM.intersectionWith a -> b -> c
f IntMap a
l IntMap b
r

keys :: (EnumKey k) => EnumMap k a -> [k]
keys :: forall k a. EnumKey k => EnumMap k a -> [k]
keys (EM IntMap a
m) = (Int -> k) -> [Int] -> [k]
forall a b. (a -> b) -> [a] -> [b]
forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
fmap Int -> k
forall k. EnumKey k => Int -> k
intToKey ([Int] -> [k]) -> (IntMap a -> [Int]) -> IntMap a -> [k]
forall b c a. (b -> c) -> (a -> b) -> a -> c
. IntMap a -> [Int]
forall a. IntMap a -> [Int]
IM.keys (IntMap a -> [k]) -> IntMap a -> [k]
forall a b. (a -> b) -> a -> b
$ IntMap a
m

keysSet :: (EnumKey k) => EnumMap k a -> EnumSet k
keysSet :: forall k a. EnumKey k => EnumMap k a -> EnumSet k
keysSet (EM IntMap a
m) = IntSet -> EnumSet k
forall k. IntSet -> EnumSet k
ES (IntMap a -> IntSet
forall a. IntMap a -> IntSet
IM.keysSet IntMap a
m)

restrictKeys :: (EnumKey k) => EnumMap k a -> EnumSet k -> EnumMap k a
restrictKeys :: forall k a. EnumKey k => EnumMap k a -> EnumSet k -> EnumMap k a
restrictKeys (EM IntMap a
m) (ES IntSet
s) = IntMap a -> EnumMap k a
forall k a. IntMap a -> EnumMap k a
EM (IntMap a -> EnumMap k a) -> IntMap a -> EnumMap k a
forall a b. (a -> b) -> a -> b
$ IntMap a -> IntSet -> IntMap a
forall a. IntMap a -> IntSet -> IntMap a
IM.restrictKeys IntMap a
m IntSet
s

withoutKeys :: (EnumKey k) => EnumMap k a -> EnumSet k -> EnumMap k a
withoutKeys :: forall k a. EnumKey k => EnumMap k a -> EnumSet k -> EnumMap k a
withoutKeys (EM IntMap a
m) (ES IntSet
s) = IntMap a -> EnumMap k a
forall k a. IntMap a -> EnumMap k a
EM (IntMap a -> EnumMap k a) -> IntMap a -> EnumMap k a
forall a b. (a -> b) -> a -> b
$ IntMap a -> IntSet -> IntMap a
forall a. IntMap a -> IntSet -> IntMap a
IM.withoutKeys IntMap a
m IntSet
s

member :: (EnumKey k) => k -> EnumSet k -> Bool
member :: forall k. EnumKey k => k -> EnumSet k -> Bool
member k
e (ES IntSet
s) = Int -> IntSet -> Bool
IS.member (k -> Int
forall k. EnumKey k => k -> Int
keyToInt k
e) IntSet
s

hasKey :: (EnumKey k) => k -> EnumMap k a -> Bool
hasKey :: forall k a. EnumKey k => k -> EnumMap k a -> Bool
hasKey k
k (EM IntMap a
m) = Int -> IntMap a -> Bool
forall a. Int -> IntMap a -> Bool
IM.member (k -> Int
forall k. EnumKey k => k -> Int
keyToInt k
k) IntMap a
m

lookup :: (EnumKey k) => k -> EnumMap k a -> Maybe a
lookup :: forall k a. EnumKey k => k -> EnumMap k a -> Maybe a
lookup k
e (EM IntMap a
m) = Int -> IntMap a -> Maybe a
forall a. Int -> IntMap a -> Maybe a
IM.lookup (k -> Int
forall k. EnumKey k => k -> Int
keyToInt k
e) IntMap a
m

lookupWithDefault :: (EnumKey k) => a -> k -> EnumMap k a -> a
lookupWithDefault :: forall k a. EnumKey k => a -> k -> EnumMap k a -> a
lookupWithDefault a
d k
e (EM IntMap a
m) = a -> Int -> IntMap a -> a
forall a. a -> Int -> IntMap a -> a
IM.findWithDefault a
d (k -> Int
forall k. EnumKey k => k -> Int
keyToInt k
e) IntMap a
m

mapWithKey :: (EnumKey k) => (k -> a -> b) -> EnumMap k a -> EnumMap k b
mapWithKey :: forall k a b.
EnumKey k =>
(k -> a -> b) -> EnumMap k a -> EnumMap k b
mapWithKey k -> a -> b
f (EM IntMap a
m) = IntMap b -> EnumMap k b
forall k a. IntMap a -> EnumMap k a
EM (IntMap b -> EnumMap k b) -> IntMap b -> EnumMap k b
forall a b. (a -> b) -> a -> b
$ (Int -> a -> b) -> IntMap a -> IntMap b
forall a b. (Int -> a -> b) -> IntMap a -> IntMap b
IM.mapWithKey (k -> a -> b
f (k -> a -> b) -> (Int -> k) -> Int -> a -> b
forall b c a. (b -> c) -> (a -> b) -> a -> c
. Int -> k
forall k. EnumKey k => Int -> k
intToKey) IntMap a
m

foldMapWithKey :: (EnumKey k) => (Monoid m) => (k -> a -> m) -> EnumMap k a -> m
foldMapWithKey :: forall k m a.
(EnumKey k, Monoid m) =>
(k -> a -> m) -> EnumMap k a -> m
foldMapWithKey k -> a -> m
f (EM IntMap a
m) = (Int -> a -> m) -> IntMap a -> m
forall m a. Monoid m => (Int -> a -> m) -> IntMap a -> m
IM.foldMapWithKey (k -> a -> m
f (k -> a -> m) -> (Int -> k) -> Int -> a -> m
forall b c a. (b -> c) -> (a -> b) -> a -> c
. Int -> k
forall k. EnumKey k => Int -> k
intToKey) IntMap a
m

mapToList :: (EnumKey k) => EnumMap k a -> [(k, a)]
mapToList :: forall k a. EnumKey k => EnumMap k a -> [(k, a)]
mapToList (EM IntMap a
m) = (Int -> k) -> (Int, a) -> (k, a)
forall a b c. (a -> b) -> (a, c) -> (b, c)
forall (p :: * -> * -> *) a b c.
Bifunctor p =>
(a -> b) -> p a c -> p b c
first Int -> k
forall k. EnumKey k => Int -> k
intToKey ((Int, a) -> (k, a)) -> [(Int, a)] -> [(k, a)]
forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
<$> IntMap a -> [(Int, a)]
forall a. IntMap a -> [(Int, a)]
IM.toList IntMap a
m

(!) :: (EnumKey k) => EnumMap k a -> k -> a
! :: forall k a. EnumKey k => EnumMap k a -> k -> a
(!) (EM IntMap a
m) k
e = IntMap a
m IntMap a -> Int -> a
forall a. IntMap a -> Int -> a
IM.! k -> Int
forall k. EnumKey k => k -> Int
keyToInt k
e

findMin :: (EnumKey k) => EnumSet k -> k
findMin :: forall k. EnumKey k => EnumSet k -> k
findMin (ES IntSet
s) = Int -> k
forall k. EnumKey k => Int -> k
intToKey (Int -> k) -> Int -> k
forall a b. (a -> b) -> a -> b
$ IntSet -> Int
IS.findMin IntSet
s

traverseSet_ ::
  (Applicative f) => (EnumKey k) => (k -> f ()) -> EnumSet k -> f ()
traverseSet_ :: forall (f :: * -> *) k.
(Applicative f, EnumKey k) =>
(k -> f ()) -> EnumSet k -> f ()
traverseSet_ k -> f ()
f (ES IntSet
s) =
  (Int -> f () -> f ()) -> f () -> IntSet -> f ()
forall b. (Int -> b -> b) -> b -> IntSet -> b
IS.foldr (\Int
i f ()
r -> k -> f ()
f (Int -> k
forall k. EnumKey k => Int -> k
intToKey Int
i) f () -> f () -> f ()
forall a b. f a -> f b -> f b
forall (f :: * -> *) a b. Applicative f => f a -> f b -> f b
*> f ()
r) (() -> f ()
forall a. a -> f a
forall (f :: * -> *) a. Applicative f => a -> f a
pure ()) IntSet
s

interverse ::
  (Applicative f) =>
  (a -> b -> f c) ->
  EnumMap k a ->
  EnumMap k b ->
  f (EnumMap k c)
interverse :: forall (f :: * -> *) a b c k.
Applicative f =>
(a -> b -> f c) -> EnumMap k a -> EnumMap k b -> f (EnumMap k c)
interverse a -> b -> f c
f (EM IntMap a
l) (EM IntMap b
r) =
  (IntMap c -> EnumMap k c) -> f (IntMap c) -> f (EnumMap k c)
forall a b. (a -> b) -> f a -> f b
forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
fmap IntMap c -> EnumMap k c
forall k a. IntMap a -> EnumMap k a
EM (f (IntMap c) -> f (EnumMap k c))
-> (IntMap (f c) -> f (IntMap c))
-> IntMap (f c)
-> f (EnumMap k c)
forall b c a. (b -> c) -> (a -> b) -> a -> c
. (f c -> f c) -> IntMap (f c) -> f (IntMap c)
forall (t :: * -> *) (f :: * -> *) a b.
(Traversable t, Applicative f) =>
(a -> f b) -> t a -> f (t b)
forall (f :: * -> *) a b.
Applicative f =>
(a -> f b) -> IntMap a -> f (IntMap b)
traverse f c -> f c
forall a. a -> a
id (IntMap (f c) -> f (EnumMap k c))
-> IntMap (f c) -> f (EnumMap k c)
forall a b. (a -> b) -> a -> b
$ (a -> b -> f c) -> IntMap a -> IntMap b -> IntMap (f c)
forall a b c. (a -> b -> c) -> IntMap a -> IntMap b -> IntMap c
IM.intersectionWith a -> b -> f c
f IntMap a
l IntMap b
r

traverseWithKey ::
  (Applicative f) =>
  (EnumKey k) =>
  (k -> a -> f b) ->
  EnumMap k a ->
  f (EnumMap k b)
traverseWithKey :: forall (f :: * -> *) k a b.
(Applicative f, EnumKey k) =>
(k -> a -> f b) -> EnumMap k a -> f (EnumMap k b)
traverseWithKey k -> a -> f b
f (EM IntMap a
m) = IntMap b -> EnumMap k b
forall k a. IntMap a -> EnumMap k a
EM (IntMap b -> EnumMap k b) -> f (IntMap b) -> f (EnumMap k b)
forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
<$> (Int -> a -> f b) -> IntMap a -> f (IntMap b)
forall (t :: * -> *) a b.
Applicative t =>
(Int -> a -> t b) -> IntMap a -> t (IntMap b)
IM.traverseWithKey (k -> a -> f b
f (k -> a -> f b) -> (Int -> k) -> Int -> a -> f b
forall b c a. (b -> c) -> (a -> b) -> a -> c
. Int -> k
forall k. EnumKey k => Int -> k
intToKey) IntMap a
m

setSize :: EnumSet k -> Int
setSize :: forall k. EnumSet k -> Int
setSize (ES IntSet
s) = IntSet -> Int
IS.size IntSet
s