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

module Data.Map.Subset.Lazy.Unlifted
  ( 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.Unlifted.Internal (Set(..))
import Data.Bifunctor (first)
import Data.Semigroup (Semigroup)
import Data.Primitive.Unlifted.Class (PrimUnlifted)

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

-- | A subset map with a single set as its key.
singleton :: PrimUnlifted k
  => Set k
  -> v
  -> Map k v
singleton :: forall k v. PrimUnlifted k => Set k -> v -> Map k v
singleton (Set Set UnliftedArray k
s) v
v = forall (arr :: * -> *) k v.
(ContiguousU arr, Element arr k) =>
Set arr k -> v -> Map k v
I.singleton Set UnliftedArray 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 :: PrimUnlifted k
  => Set k -- ^ negative set
  -> v -- ^ value
  -> Map k v
antisingleton :: forall k v. PrimUnlifted k => Set k -> v -> Map k v
antisingleton (Set Set UnliftedArray k
s) v
v = forall (arr :: * -> *) k v.
(ContiguousU arr, Element arr k) =>
Set arr k -> v -> Map k v
I.antisingleton Set UnliftedArray 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 :: PrimUnlifted k
  => M.Map k Bool -- ^ Map of required presences and absences
  -> v -- 
  -> Map k v 
fromPolarities :: forall k v. PrimUnlifted k => Map k Bool -> v -> Map k v
fromPolarities (M.Map Map UnliftedArray 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 UnliftedArray Array k Bool
m v
v

lookup :: (Ord k, PrimUnlifted k) => Set k -> Map k v -> Maybe v
lookup :: forall k v. (Ord k, PrimUnlifted k) => Set k -> Map k v -> Maybe v
lookup (Set Set UnliftedArray 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 UnliftedArray k
s Map k v
m

toList :: PrimUnlifted k => Map k v -> [(Set k,v)]
toList :: forall k v. PrimUnlifted k => 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 UnliftedArray 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, PrimUnlifted k) => [(Set k,v)] -> Map k v
fromList :: forall k v. (Ord k, PrimUnlifted 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 UnliftedArray a
getSet)