-- Term indexing, where the inserted values can be given categories. {-# LANGUAGE CPP, TypeFamilies, ScopedTypeVariables #-} module Twee.Indexes where #include "errors.h" import Twee.Base hiding (empty) import qualified Twee.Index as Index import Twee.Index(Index) import Data.Array class Rated a where rating :: a -> Int maxRating :: a -> Int newtype Indexes a = Indexes { unIndexes :: Array Int (Index a) } deriving Show {-# INLINE empty #-} empty :: forall a. Rated a => Indexes a empty = Indexes (listArray (0, maxRating (undefined :: a)) (repeat Index.Nil)) {-# INLINE singleton #-} singleton :: (Symbolic a, Rated a) => a -> Indexes a singleton x = insert x empty {-# INLINE insert #-} insert :: forall a. (Symbolic a, Rated a) => a -> Indexes a -> Indexes a insert x (Indexes idxs) = Indexes (idxs // [(i, Index.insert x (idxs ! i)) | i <- [rating x..maxRating (undefined :: a)]]) {-# INLINE delete #-} delete :: forall a. (Eq a, Symbolic a, Rated a) => a -> Indexes a -> Indexes a delete x (Indexes idxs) = Indexes (idxs // [(i, Index.delete x (idxs ! i)) | i <- [rating x..maxRating (undefined :: a)]]) {-# INLINE freeze #-} freeze :: Int -> Indexes a -> Index.Frozen a freeze n (Indexes idxs) = Index.freeze (idxs ! n) {-# INLINE elems #-} elems :: forall a. Rated a => Indexes a -> [a] elems (Indexes idxs) = Index.elems (idxs ! maxRating (undefined :: a))