ralist 0.4.0.0 → 0.4.1.0
raw patch · 4 files changed
+154/−24 lines, 4 filesdep ~deepseqdep ~hspecdep ~indexed-traversablePVP: major bump suggested
API removals or changes: PVP suggests a major version bump
Dependency ranges changed: deepseq, hspec, indexed-traversable
API changes (from Hackage documentation)
- Data.RAList: instance GHC.Exts.IsList (Data.RAList.RAList a)
- Data.RAList.Co: instance GHC.Exts.IsList (Data.RAList.Co.RAList a)
+ Data.RAList: instance GHC.IsList.IsList (Data.RAList.RAList a)
+ Data.RAList.Co: instance GHC.IsList.IsList (Data.RAList.Co.RAList a)
- Data.RAList: adjust :: forall a. (a -> a) -> Word64 -> RAList a -> RAList a
+ Data.RAList: adjust :: (a -> a) -> Word64 -> RAList a -> RAList a
- Data.RAList: augment :: forall a. (forall b. (a -> b -> b) -> b -> b) -> RAList a -> RAList a
+ Data.RAList: augment :: (forall b. () => (a -> b -> b) -> b -> b) -> RAList a -> RAList a
- Data.RAList: build :: forall a. (forall b. (a -> b -> b) -> b -> b) -> RAList a
+ Data.RAList: build :: (forall b. () => (a -> b -> b) -> b -> b) -> RAList a
- Data.RAList: filter :: forall a. (a -> Bool) -> RAList a -> RAList a
+ Data.RAList: filter :: (a -> Bool) -> RAList a -> RAList a
- Data.RAList: lookup :: forall a. RAList a -> Word64 -> Maybe a
+ Data.RAList: lookup :: RAList a -> Word64 -> Maybe a
- Data.RAList: lookupCC :: forall a r. RAList a -> Word64 -> (a -> r) -> (String -> r) -> r
+ Data.RAList: lookupCC :: RAList a -> Word64 -> (a -> r) -> (String -> r) -> r
- Data.RAList: lookupWithDefault :: forall t. t -> Word64 -> RAList t -> t
+ Data.RAList: lookupWithDefault :: t -> Word64 -> RAList t -> t
- Data.RAList: mapMaybe :: forall a b. (a -> Maybe b) -> RAList a -> RAList b
+ Data.RAList: mapMaybe :: (a -> Maybe b) -> RAList a -> RAList b
- Data.RAList: pattern (:|) :: forall a. a -> RAList a -> RAList a
+ Data.RAList: pattern (:|) :: a -> RAList a -> RAList a
- Data.RAList: pattern Cons :: forall a. a -> RAList a -> RAList a
+ Data.RAList: pattern Cons :: a -> RAList a -> RAList a
- Data.RAList: pattern Nil :: forall a. RAList a
+ Data.RAList: pattern Nil :: RAList a
- Data.RAList: zipWith :: forall a b c. (a -> b -> c) -> RAList a -> RAList b -> RAList c
+ Data.RAList: zipWith :: (a -> b -> c) -> RAList a -> RAList b -> RAList c
- Data.RAList.Co: adjust :: forall a. (a -> a) -> Word64 -> RAList a -> RAList a
+ Data.RAList.Co: adjust :: (a -> a) -> Word64 -> RAList a -> RAList a
- Data.RAList.Co: filter :: forall a. (a -> Bool) -> RAList a -> RAList a
+ Data.RAList.Co: filter :: (a -> Bool) -> RAList a -> RAList a
- Data.RAList.Co: infixl 5 :.
+ Data.RAList.Co: infixl 5 `RCons`
- Data.RAList.Co: lookup :: forall a. RAList a -> Word64 -> Maybe a
+ Data.RAList.Co: lookup :: RAList a -> Word64 -> Maybe a
- Data.RAList.Co: lookupWithDefault :: forall t. t -> Word64 -> RAList t -> t
+ Data.RAList.Co: lookupWithDefault :: t -> Word64 -> RAList t -> t
- Data.RAList.Co: mapMaybe :: forall a b. (a -> Maybe b) -> RAList a -> RAList b
+ Data.RAList.Co: mapMaybe :: (a -> Maybe b) -> RAList a -> RAList b
- Data.RAList.Co: pattern (:.) :: forall a. RAList a -> a -> RAList a
+ Data.RAList.Co: pattern (:.) :: RAList a -> a -> RAList a
- Data.RAList.Co: pattern Cons :: forall a. a -> RAList a -> RAList a
+ Data.RAList.Co: pattern Cons :: a -> RAList a -> RAList a
- Data.RAList.Co: pattern Nil :: forall a. RAList a
+ Data.RAList.Co: pattern Nil :: RAList a
- Data.RAList.Co: pattern RCons :: forall a. RAList a -> a -> RAList a
+ Data.RAList.Co: pattern RCons :: RAList a -> a -> RAList a
- Data.RAList.Internal: Indexing :: (Word64 -> (Word64, f a)) -> Indexing f a
+ Data.RAList.Internal: Indexing :: (Word64 -> (Word64, f a)) -> Indexing (f :: Type -> Type) a
- Data.RAList.Internal: [runIndexing] :: Indexing f a -> Word64 -> (Word64, f a)
+ Data.RAList.Internal: [runIndexing] :: Indexing (f :: Type -> Type) a -> Word64 -> (Word64, f a)
- Data.RAList.Internal: newtype Indexing f a
+ Data.RAList.Internal: newtype Indexing (f :: Type -> Type) a
Files
- changelog.md +24/−11
- ralist.cabal +6/−6
- src/Data/RAList/Co.hs +7/−7
- tests/hspec.hs +117/−0
changelog.md view
@@ -1,21 +1,34 @@+# 0.4.1.0++- **Bug fix**: `Data.RAList.Co` — off-by-one in all index operations (`!!`, `lookup`, `lookupM`, `lookupWithDefault`, `lookupCC`). Index formula was `length - n` instead of `length - 1 - n`.+- **Bug fix**: `Data.RAList.Co.adjust` — infinite recursion (called itself instead of `QRA.adjust`).+- **Bug fix**: `Data.RAList.Co.genericReplicate` — infinite recursion (called itself instead of `QRA.genericReplicate`).+- Widened dependency bounds for GHC 9.14 (base < 6, deepseq < 1.7, transformers < 0.7, hspec < 2.12).+- Added test coverage for `Data.RAList.Co` (35 new tests).+ # 0.4.0.0 -* flipped the argument order for `Co.lookup` to be consistent between-both flavors of RAList apis+- Breaking change to api to make api flavors more consistent. # 0.3.0.0-* changed type from- `lookupM :: forall (m :: * -> *) a. Monad m => Word64 -> Top a -> m a` to `lookupM :: forall a. Word64 -> Top a -> Either String a`-* added `Data.RAList.Flip`, which flips the counting by having the zeroth index be the last element of the skew binary list,-rather than the head element. +- Added `Data.RAList.Co` module for reversed (co-indexed) access lists.+- Added filter/catMaybe/wither family of operations.+- Added NFData/NFData1 instances.+- Added indexed traversal instances (FunctorWithIndex, FoldableWithIndex, TraversableWithIndex).+ # 0.2.1.1-Fix bug in log n time drop +- Documentation tweaks.+ # 0.2.1.0-Added missing traversable instance +- Various improvements.+ # 0.2.0.0-updated version of ralist-includes bug fixes, api cleanup,-test suite and logarithmic drop contributed by Nell White++- Major rework by Carter Schonwald.++# 0.1.0.0++- Initial release by Lennart Augustsson.
ralist.cabal view
@@ -1,6 +1,6 @@ cabal-version: 3.0 Name: ralist-Version: 0.4.0.0+Version: 0.4.1.0 License: BSD-3-Clause license-file: LICENSE Author: Lennart Augustsson, Carter Schonwald@@ -16,7 +16,7 @@ -- URL for the project homepage or repository. homepage: http://github.com/cartazio/ralist -tested-with: GHC==8.10.2, GHC==8.8.4, GHC==8.6.5+tested-with: GHC==9.14.1, GHC==8.10.2, GHC==8.8.4, GHC==8.6.5 extra-source-files: changelog.md LICENSE @@ -30,10 +30,10 @@ Library Build-Depends: base >= 4.12 && < 6- ,indexed-traversable ^>= 0.1- , transformers ^>= 0.5+ ,indexed-traversable >= 0.1 && < 0.2+ , transformers >= 0.5 && < 0.7 -- only needed for one spot in .co- ,deepseq ^>= 1.4.4.0+ ,deepseq >= 1.4.4.0 && < 1.7 Exposed-modules: Data.RAList ,Data.RAList.Co@@ -59,7 +59,7 @@ build-depends: base, ralist,- hspec >= 2.2 && < 2.8+ hspec >= 2.2 && < 2.12 benchmark benchmarking
src/Data/RAList/Co.hs view
@@ -322,23 +322,23 @@ (!!) :: RAList a -> Word64 -> a rls !! n | n < 0 = error "Data.RAList.Flip.!!: negative index" | n >= (wLength rls) = error "Data.RAList.Flip.!!: index too large"- | otherwise = reindex rls QRA.!! ((wLength rls) - n )+ | otherwise = reindex rls QRA.!! ((wLength rls) - 1 - n ) {-# INLINE lookupWithDefault #-} lookupWithDefault :: forall t. t -> Word64 -> RAList t -> t-lookupWithDefault = \ def ix tree -> QRA.lookupWithDefault def ((wLength tree) - ix ) $ reindex tree+lookupWithDefault = \ def ix tree -> QRA.lookupWithDefault def ((wLength tree) - 1 - ix ) $ reindex tree {-# INLINE lookupM #-} lookupM :: forall a m . MF.MonadFail m => Word64 -> RAList a -> m a-lookupM = \ ix tree -> QRA.lookupM (reindex tree) ((wLength tree) - ix)+lookupM = \ ix tree -> QRA.lookupM (reindex tree) ((wLength tree) - 1 - ix) {-# INLINE lookup #-} lookup :: forall a. RAList a -> Word64 -> Maybe a-lookup = \ (CoIndex tree) ix -> QRA.lookup tree ((QRA.wLength tree) - ix )+lookup = \ (CoIndex tree) ix -> QRA.lookup tree ((QRA.wLength tree) - 1 - ix ) {-# INLINE lookupCC #-} lookupCC :: RAList a -> Word64 -> (a -> r) -> (String -> r) -> r-lookupCC = \ tree ix f g -> QRA.lookupCC (reindex tree) ((wLength tree) - ix ) f g+lookupCC = \ tree ix f g -> QRA.lookupCC (reindex tree) ((wLength tree) - 1 - ix ) f g {-# INLINE wLength #-} wLength:: RAList a -> Word64@@ -396,7 +396,7 @@ genericIndex x i = QRA.genericIndex (reindex x) i genericReplicate :: Integral n => n -> a -> RAList a-genericReplicate i v = coerce $ genericReplicate i v+genericReplicate i v = coerce $ QRA.genericReplicate i v update :: Word64 -> a -> RAList a -> RAList a@@ -404,7 +404,7 @@ adjust :: forall a . (a->a) -> Word64 -> RAList a -> RAList a-adjust f i l = coerce $ adjust f i $ coerce l+adjust f i l = coerce $ QRA.adjust f ((wLength l) - 1 - i) $ coerce l unfoldr :: (b -> Maybe (a, b)) -> b -> RAList a
tests/hspec.hs view
@@ -1,8 +1,10 @@ module Main where import Data.RAList+import qualified Data.RAList.Co as Co import Test.Hspec import Control.Exception (evaluate)+import Data.Word (Word64) import Prelude hiding ( (++), head, last, tail, init, null, length, map, reverse,@@ -737,4 +739,119 @@ toList (fromList [1..9]) `shouldBe` ([1..9] :: [Int]) it "converts an empty list" $ do toList (empty) `shouldBe` ([] :: [Int])++ -- ═══════════════════════════════════════════════════════+ -- Data.RAList.Co tests (reversed indexing)+ -- ═══════════════════════════════════════════════════════++ let co3 = Co.fromList [1,2,3] :: Co.RAList Int+ co9 = Co.fromList [1..9] :: Co.RAList Int+ coEmpty = Co.Nil :: Co.RAList Int++ describe "Co.cons/uncons" $ do+ it "cons adds to an empty list" $+ Co.cons 1 coEmpty `shouldBe` Co.fromList [1 :: Int]+ it "cons then uncons roundtrips" $+ Co.uncons (Co.cons 42 co3) `shouldBe` Just (42 :: Int, co3)+ it "uncons empty is Nothing" $+ Co.uncons coEmpty `shouldBe` (Nothing :: Maybe (Int, Co.RAList Int))++ describe "Co.toList/fromList" $ do+ it "roundtrips length 3" $+ Co.toList co3 `shouldBe` [1,2,3 :: Int]+ it "roundtrips length 9" $+ Co.toList co9 `shouldBe` [1..9 :: Int]+ it "roundtrips empty" $+ Co.toList coEmpty `shouldBe` ([] :: [Int])++ describe "Co.(!!) reversed indexing" $ do+ -- Co indexes from the back: head is at (length-1), last is at 0+ it "!! 0 gives last element" $+ co9 Co.!! 0 `shouldBe` (9 :: Int)+ it "!! (length-1) gives first element" $+ co9 Co.!! 8 `shouldBe` (1 :: Int)+ it "!! 4 gives middle element" $+ co9 Co.!! 4 `shouldBe` (5 :: Int)++ describe "Co.lookup" $ do+ it "lookup 0 gives last" $+ Co.lookup co9 0 `shouldBe` Just (9 :: Int)+ it "lookup (length-1) gives first" $+ Co.lookup co9 8 `shouldBe` Just (1 :: Int)+ it "lookup out of bounds gives Nothing" $+ Co.lookup co9 99 `shouldBe` (Nothing :: Maybe Int)++ describe "Co.length" $ do+ it "length 9" $+ Co.wLength co9 `shouldBe` (9 :: Word64)+ it "length empty" $+ Co.wLength coEmpty `shouldBe` (0 :: Word64)++ describe "Co.drop" $ do+ it "drop 0 is identity" $+ Co.toList (Co.drop 0 co9) `shouldBe` [1..9 :: Int]+ it "drop 3 removes first 3" $+ Co.toList (Co.drop 3 co9) `shouldBe` [4..9 :: Int]+ it "drop all gives empty" $+ Co.toList (Co.drop 9 co9) `shouldBe` ([] :: [Int])++ describe "Co.take" $ do+ it "take 3 keeps first 3" $+ Co.toList (Co.take 3 co9) `shouldBe` [1,2,3 :: Int]+ it "take 0 gives empty" $+ Co.toList (Co.take 0 co9) `shouldBe` ([] :: [Int])+ it "take all is identity" $+ Co.toList (Co.take 9 co9) `shouldBe` [1..9 :: Int]++ describe "Co.zip/zipWith" $ do+ it "zip equal length" $+ Co.toList (Co.zip co3 (Co.fromList [10,20,30])) `shouldBe`+ [(1,10),(2,20),(3,30 :: Int)]+ it "zipWith (+) equal length" $+ Co.toList (Co.zipWith (+) co3 (Co.fromList [10,20,30])) `shouldBe`+ [11,22,33 :: Int]+ it "zip different lengths truncates from front (Co semantics)" $+ Co.toList (Co.zip co3 co9) `shouldBe`+ [(1,7),(2,8),(3,9 :: Int)]++ describe "Co.filter/partition" $ do+ it "filter even" $+ Co.toList (Co.filter even co9) `shouldBe` [2,4,6,8 :: Int]+ it "partition even" $ do+ let (evens, odds) = Co.partition even co9+ Co.toList evens `shouldBe` [2,4,6,8 :: Int]+ Co.toList odds `shouldBe` [1,3,5,7,9 :: Int]++ describe "Co.genericReplicate (was infinite recursion)" $ do+ it "replicate 0" $+ Co.toList (Co.genericReplicate (0 :: Int) 'x') `shouldBe` ""+ it "replicate 1" $+ Co.toList (Co.genericReplicate (1 :: Int) 'x') `shouldBe` "x"+ it "replicate 5" $+ Co.toList (Co.genericReplicate (5 :: Int) 'x') `shouldBe` "xxxxx"++ describe "Co.adjust (was infinite recursion)" $ do+ it "adjust at 0 modifies last element" $+ Co.toList (Co.adjust (+100) 0 co9) `shouldBe`+ [1,2,3,4,5,6,7,8,109 :: Int]+ it "adjust at (length-1) modifies first element" $+ Co.toList (Co.adjust (+100) 8 co9) `shouldBe`+ [101,2,3,4,5,6,7,8,9 :: Int]+ it "adjust at 4 modifies middle element" $+ Co.toList (Co.adjust (*10) 4 co9) `shouldBe`+ [1,2,3,4,50,6,7,8,9 :: Int]++ describe "Co.update (uses adjust)" $ do+ it "update at 0 replaces last element" $+ Co.toList (Co.update 0 99 co9) `shouldBe`+ [1,2,3,4,5,6,7,8,99 :: Int]+ it "update at 8 replaces first element" $+ Co.toList (Co.update 8 99 co9) `shouldBe`+ [99,2,3,4,5,6,7,8,9 :: Int]++ describe "Co.append" $ do+ it "append two lists" $+ Co.toList (co3 Co.++ Co.fromList [4,5,6]) `shouldBe` [1..6 :: Int]+ it "append empty" $+ Co.toList (co3 Co.++ coEmpty) `shouldBe` [1,2,3 :: Int]