packages feed

justified-containers 0.2.0.1 → 0.3.0.0

raw patch · 4 files changed

+37/−10 lines, 4 filesPVP ok

version bump matches the API change (PVP)

API changes (from Hackage documentation)

+ Data.Map.Justified: data Index ph
+ Data.Map.Justified: instance GHC.Classes.Eq (Data.Map.Justified.Index ph)
+ Data.Map.Justified: instance GHC.Classes.Ord (Data.Map.Justified.Index ph)
+ Data.Map.Justified: instance GHC.Show.Show (Data.Map.Justified.Index ph)
+ Data.Map.Justified: theIndex :: Index ph -> Int
- Data.Map.Justified: elemAt :: Key ph Int -> Map ph k v -> (Key ph k, v)
+ Data.Map.Justified: elemAt :: Index ph -> Map ph k v -> (Key ph k, v)
- Data.Map.Justified: findIndex :: Ord k => Key ph k -> Map ph k a -> Key ph Int
+ Data.Map.Justified: findIndex :: Ord k => Key ph k -> Map ph k a -> Index ph

Files

README.md view
@@ -95,7 +95,7 @@  It is tempting to reach for partial functions or "impossible" runtime errors here, because the programmer has proven that the key is a member of the map in some other way. They-know that lookup` should return a `Just v` --- but the *compiler* doesnt know this!+know that `lookup` should return a `Just v` --- but the *compiler* doesnt know this!  The idea behind `Data.Map.Justified` is to encode the programmers knowledge that a key is present *within the type system*, where it can be checked at compile-time. Once a key
justified-containers.cabal view
@@ -1,5 +1,5 @@ name:                justified-containers-version:             0.2.0.1+version:             0.3.0.0 synopsis:            Keyed container types with type-checked proofs of key presence. description:         This package contains wrappers around standard container types,                      that provide guarantees about the presence of keys within the
src/Data/Map/Justified.hs view
@@ -128,8 +128,10 @@     -- * Map and Key types       Map     , Key-    , theKey+    , Index     , theMap+    , theKey+    , theIndex      -- * Evaluation     , withMap@@ -234,15 +236,30 @@ newtype Key ph k = Key k deriving (Eq, Ord, Show) type role Key phantom representational +-- | An index that knows it is valid in certain @'Map'@s.+--+-- The evidence that the index is valid for a map is carried by+-- the type system via the phantom type parameter @ph@. Indexing+-- operations such as `elemAt` will only type-check if the @'Index'@+-- and the @'Map'@ have the same phantom type parameter.+newtype Index ph = Index Int deriving (Eq, Ord, Show)+type role Index phantom++-- | Get the underlying "Data.Map" @'Data.Map'@ out of a @'Map'@.+theMap :: Map ph k v -> M.Map k v+theMap (Map m) = m+ -- | Get a bare key out of a key-plus-evidence by forgetting -- what map the key can be found in. theKey :: Key ph k -> k theKey (Key k) = k --- | Get the underlying "Data.Map" @'Data.Map'@ out of a @'Map'@.-theMap :: Map ph k v -> M.Map k v-theMap (Map m) = m+-- | Get a bare index out of an index-plus-evidence by forgetting+-- what map the index is valid for.+theIndex :: Index ph -> Int+theIndex (Index n) = n + {--------------------------------------------------------------------   Evaluation --------------------------------------------------------------------}@@ -797,16 +814,16 @@ -- -- Unlike "Data.Map"'s @'Data.Map.findIndex'@, this function can not fail at runtime. -findIndex :: Ord k => Key ph k -> Map ph k a -> Key ph Int-findIndex (Key k) (Map m) = Key (M.findIndex k m)+findIndex :: Ord k => Key ph k -> Map ph k a -> Index ph+findIndex (Key k) (Map m) = Index (M.findIndex k m)  -- | /O(log n)/. Retrieve an element by its /index/, i.e. by its zero-based -- index in the sequence sorted by keys. -- -- Unlike "Data.Map"'s @'Data.Map.elemAt'@, this function can not fail at runtime. -elemAt :: Key ph Int -> Map ph k v -> (Key ph k, v)-elemAt (Key n) (Map m) = let (k,v) = M.elemAt n m in (Key k, v)+elemAt :: Index ph -> Map ph k v -> (Key ph k, v)+elemAt (Index n) (Map m) = let (k,v) = M.elemAt n m in (Key k, v)  {--------------------------------------------------------------------   Utilities
test/Data/Map/JustifiedSpec.hs view
@@ -106,7 +106,17 @@       shouldNotTypecheck $         withMap letters $ \m -> deleting 'X' m $           \(_, _, m') -> map (`lookup` m') (keys m)++  describe "indices" $ do     +    it "cannot be used as keys" $+      shouldNotTypecheck $+        withSingleton (17 :: Int) () $ \(k,m) -> m ! findIndex k m++    it "cannot be used instead of keys" $+      shouldNotTypecheck $+        withSingleton (17 :: Int) () $ \(k,m) -> snd (elemAt k m)+   describe "at runtime" $ do      it "does not allocate map copies when gathering evidence" $ do