{-# LANGUAGE BangPatterns #-}
{-# LANGUAGE KindSignatures #-}
{-# LANGUAGE MagicHash #-}
{-# LANGUAGE RankNTypes #-}
{-# LANGUAGE ScopedTypeVariables #-}
{-# LANGUAGE TypeFamilies #-}
{-# LANGUAGE UnboxedTuples #-}

module Data.Map.Subset.Lazy.Lifted
  ( I.Map
  , I.empty
    -- * Singleton Subset Maps
  , singleton
  , antisingleton
  , fromPolarities
    -- * Querying
  , lookup
    -- * List Conversion
  , toList
  , fromList
  ) where

import Prelude hiding (lookup)

import Data.Map.Subset.Lazy.Internal (Map)
import Data.Set.Lifted.Internal (Set(..))
import Data.Bifunctor (first)
import Data.Semigroup (Semigroup)

import qualified Data.Map.Lifted.Lifted as M
import qualified Data.Map.Subset.Lazy.Internal as I

-- | A subset map with a single set as its key.
singleton :: 
     Set k
  -> v
  -> Map k v
singleton :: forall k v. Set k -> v -> Map k v
singleton (Set Set Array k
s) v
v = forall (arr :: * -> *) k v.
(ContiguousU arr, Element arr k) =>
Set arr k -> v -> Map k v
I.singleton Set Array k
s v
v

-- | A subset map with a single negative set as its key. That is,
-- a lookup into this map will only succeed if the needle set and the
-- negative set do not overlap.
antisingleton ::
     Set k -- ^ negative set
  -> v -- ^ value
  -> Map k v
antisingleton :: forall k v. Set k -> v -> Map k v
antisingleton (Set Set Array k
s) v
v = forall (arr :: * -> *) k v.
(ContiguousU arr, Element arr k) =>
Set arr k -> v -> Map k v
I.antisingleton Set Array k
s v
v

-- | Construct a singleton subset map by interpreting a
-- @Data.Map.Unlifted.Lifted.Map@ as requirements about
-- what must be present and absent.
fromPolarities ::
     M.Map k Bool -- ^ Map of required presences and absences
  -> v -- 
  -> Map k v 
fromPolarities :: forall k v. Map k Bool -> v -> Map k v
fromPolarities (M.Map Map Array Array k Bool
m) v
v = forall (karr :: * -> *) k v.
(ContiguousU karr, Element karr k) =>
Map karr Array k Bool -> v -> Map k v
I.fromPolarities Map Array Array k Bool
m v
v

lookup :: Ord k => Set k -> Map k v -> Maybe v
lookup :: forall k v. Ord k => Set k -> Map k v -> Maybe v
lookup (Set Set Array k
s) Map k v
m = forall (arr :: * -> *) k v.
(Ord k, ContiguousU arr, Element arr k) =>
Set arr k -> Map k v -> Maybe v
I.lookup Set Array k
s Map k v
m

toList :: Map k v -> [(Set k,v)]
toList :: forall k v. Map k v -> [(Set k, v)]
toList = forall a b. (a -> b) -> [a] -> [b]
map (forall (p :: * -> * -> *) a b c.
Bifunctor p =>
(a -> b) -> p a c -> p b c
first forall a. Set Array a -> Set a
Set) forall b c a. (b -> c) -> (a -> b) -> a -> c
. forall (arr :: * -> *) k v.
(ContiguousU arr, Element arr k) =>
Map k v -> [(Set arr k, v)]
I.toList

fromList :: Ord k => [(Set k,v)] -> Map k v
fromList :: forall k v. Ord k => [(Set k, v)] -> Map k v
fromList = forall (arr :: * -> *) k v.
(ContiguousU arr, Element arr k, Ord k) =>
[(Set arr k, v)] -> Map k v
I.fromList forall b c a. (b -> c) -> (a -> b) -> a -> c
. forall a b. (a -> b) -> [a] -> [b]
map (forall (p :: * -> * -> *) a b c.
Bifunctor p =>
(a -> b) -> p a c -> p b c
first forall a. Set a -> Set Array a
getSet)