packages feed

ixset-typed 0.1.0.0 → 0.1.1

raw patch · 2 files changed

+68/−48 lines, 2 filesdep ~basedep ~template-haskell

Dependency ranges changed: base, template-haskell

Files

ixset-typed.cabal view
@@ -1,13 +1,13 @@ name:                ixset-typed-version:             0.1.0.0+version:             0.1.1 synopsis:            Efficient relational queries on Haskell sets. description:     Create and query sets that are indexed by multiple indices.-+    .     This is a variant of the ixset package that tracks the index     information via the type system. It should be safer to use than     ixset, but also requires more GHC extensions.-+    .     The two packages are currently relatively compatible. Switching     from one to the other requires a little bit of manual work, but     not very much.@@ -23,11 +23,11 @@   location:          https://github.com/kosmikus/ixset-typed.git  library-  build-depends:     base >= 4 && < 5,+  build-depends:     base >= 4.6 && < 5,                      syb >= 0.4 && < 1,                      containers >= 0.5 && < 1,                      safecopy >= 0.8 && < 1,-                     template-haskell >= 2.4+                     template-haskell >= 2.8 && < 3    hs-source-dirs:    src   exposed-modules:
src/Data/IxSet/Typed.hs view
@@ -94,7 +94,7 @@ > getFirstAuthor (Entry author _ _ _ _) = [FirstAuthor author] > > type EntryIxs = '[..., FirstAuthor]-> instance Indexable Entry where+> instance Indexable EntryIxs Entry where >     empty = mkEmpty >               ... >               (ixFun getFirstAuthor)@@ -108,6 +108,7 @@      -- * Set type      IxSet,      Indexable(..),+     All,      noCalcs,      inferIxSet,      ixSet,@@ -117,6 +118,7 @@       -- * Changes to set      IndexOp,+     SetOp,      change,      insert,      insertList,@@ -199,7 +201,10 @@  -- the core datatypes --- | Set with associated indexes.+-- | Set with associated indices.+--+-- The type-level list 'ixs' contains all types that are valid index keys.+-- The type 'a' is the type of elements in the indexed set. data IxSet (ixs :: [*]) (a :: *) where   IxSet :: Set a -> IxList ixs a -> IxSet ixs a @@ -212,6 +217,17 @@  infixr 5 ::: +-- | The constraint @All c xs@ says the @c@ has to hold for all+-- elements in the type-level list @xs@.+--+-- Example:+--+-- > All Ord '[Int, Char, Bool]+--+-- is equivalent to+--+-- > (Ord Int, Ord Char, Ord Bool)+-- type family All (c :: * -> Constraint) (xs :: [*]) :: Constraint type instance All c '[]       = () type instance All c (x ': xs) = (c x, All c xs)@@ -256,20 +272,25 @@   access (_x ::: xs)     = access xs   mapAt fh ft (x ::: xs) = ft x ::: mapAt fh ft xs --- | Create an 'IxSet' using a list of indexes. Useful in the 'Indexable'--- 'empty' method. Use 'ixFun' and 'ixGen' as list elements.+-- | Create an 'IxSet' using a set and a number of indexes. If you want to+-- use this in the 'Indexable' 'empty' method, better use 'mkEmpty' instead. ----- > instance Indexable Type where--- >     empty = ixSet [ ...--- >                     ixFun getIndex1--- >                     ixGen (Proxy :: Proxy Index2Type)--- >                   ]+-- Note that this function takes a variable number of arguments. ----- Every value in the 'IxSet' must be reachable by the first index in this--- list, or you'll get a runtime error. ixSet :: MkIxSet ixs ixs a r => Set a -> r ixSet s = ixSet' (IxSet s) +-- | Create an empty 'IxSet' using a number of indexes. Useful in the 'Indexable'+-- 'empty' method. Use 'ixFun' and 'ixGen' for the individual indexes.+--+-- Note that this function takes a variable number of arguments.+--+-- > instance Indexable '[..., Index1Type, Index2Type] Type where+-- >     empty = mkEmpty+-- >                 ...+-- >                 (ixFun getIndex1)+-- >                 (ixGen (Proxy :: Proxy Index2Type))+-- mkEmpty :: MkIxSet ixs ixs a r => r mkEmpty = ixSet Set.empty @@ -285,12 +306,14 @@ -- | Create a functional index. Provided function should return a list -- of indexes where the value should be found. --+-- > getIndexes :: Type -> [IndexType] -- > getIndexes value = [...indexes...] ----- > instance Indexable Type where--- >     empty = ixSet [ ixFun getIndexes ]+-- > instance Indexable '[IndexType] Type where+-- >     empty = mkEmpty (ixFun getIndexes) -- -- This is the recommended way to create indexes.+-- ixFun :: Ord ix => (a -> [ix]) -> Ix ix a ixFun = Ix Map.empty @@ -304,6 +327,7 @@ -- -- In production systems consider using 'ixFun' in place of 'ixGen' as -- the former one is much faster.+-- ixGen :: forall proxy a ix. (Ord ix, Data a, Typeable ix) => proxy ix -> Ix ix a ixGen _proxy = ixFun (flatten :: a -> [ix]) @@ -374,30 +398,26 @@ noCalcs :: t -> () noCalcs _ = () -{- | Template Haskell helper function for automatically building an-'Indexable' instance from a data type, e.g.--> data Foo = Foo Int String--and--> $(inferIxSet "FooDB" ''Foo 'noCalcs [''Int,''String])--will build a type synonym--> type FooDB = IxSet Foo--with @Int@ and @String@ as indexes.--/WARNING/: The type specified as the first index must be a type which-appears in all values in the 'IxSet' or 'toList', 'toSet' and-serialization will not function properly.  You will be warned not to do-this with a runtime error.  You can always use the element type-itself. For example:--> $(inferIxSet "FooDB" ''Foo 'noCalcs [''Foo, ''Int, ''String])---}+-- | Template Haskell helper function for automatically building an+-- 'Indexable' instance from a data type, e.g.+--+-- > data Foo = Foo Int String+--+-- and+--+-- > $(inferIxSet "FooDB" ''Foo 'noCalcs [''Int,''String])+--+-- will build a type synonym+--+-- > type FooDB = IxSet '[Int, String] Foo+--+-- with @Int@ and @String@ as indexes.+--+-- /WARNING/: This function uses 'flattenWithCalcs' for index generation,+-- which in turn uses an SYB type-based traversal. It is often more efficient+-- (and sometimes more correct) to explicitly define the indices using+-- 'ixFun'.+-- inferIxSet :: String -> TH.Name -> TH.Name -> [TH.Name] -> Q [Dec] inferIxSet _ _ _ [] = error "inferIxSet needs at least one index" inferIxSet ixset typeName calName entryPoints@@ -566,18 +586,18 @@ delete :: Indexable ixs a => a -> IxSet ixs a -> IxSet ixs a delete = change Set.delete Ix.delete --- | Will replace the item with index k.  Only works if there is at--- most one item with that index in the 'IxSet'. Will not change--- 'IxSet' if you have more then 1 item with given index.+-- | Will replace the item with the given index of type 'ix'.+-- Only works if there is at most one item with that index in the 'IxSet'.+-- Will not change 'IxSet' if you have more than one item with given index. updateIx :: (Indexable ixs a, IsIndexOf ix ixs, Ord ix)          => ix -> a -> IxSet ixs a -> IxSet ixs a updateIx i new ixset = insert new $                      maybe ixset (flip delete ixset) $                      getOne $ ixset @= i --- | Will delete the item with index k.  Only works if there is at--- most one item with that index in the 'IxSet'. Will not change--- 'IxSet' if you have more then 1 item with given index.+-- | Will delete the item with the given index of type 'ix'.+-- Only works if there is at  most one item with that index in the 'IxSet'.+-- Will not change 'IxSet' if you have more than one item with given index. deleteIx :: (Indexable ixs a, IsIndexOf ix ixs, Ord ix)          => ix -> IxSet ixs a -> IxSet ixs a deleteIx i ixset = maybe ixset (flip delete ixset) $