Skip to content

Commit

Permalink
Merge remote-tracking branch 'upstream/master' into wip/merge-upstream
Browse files Browse the repository at this point in the history
  • Loading branch information
TeofilC committed Dec 8, 2023
2 parents 922174b + 204a643 commit 33eb772
Show file tree
Hide file tree
Showing 6 changed files with 56 additions and 6 deletions.
13 changes: 10 additions & 3 deletions .github/workflows/haskell.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -10,12 +10,19 @@ jobs:
strategy:
fail-fast: false
matrix:
ghc: ['8.4', '8.6', '8.8', '8.10', '9.0', '9.2', '9.4', '9.6']
ghc: ['8.4', '8.6', '8.8', '8.10', '9.0', '9.2', '9.4', '9.6', '9.8']
steps:
- uses: actions/checkout@v3
- uses: haskell/actions/setup@v2
- uses: actions/checkout@v4
- uses: haskell-actions/setup@v2
id: setup-haskell
with:
ghc-version: ${{ matrix.ghc }}
- uses: actions/cache@v3
with:
path: |
${{ steps.setup-haskell.outputs.cabal-store }}
dist-newstyle
key: ${{ runner.os }}-${{ matrix.ghc }}
- name: Build
run: cabal build
- name: Test
Expand Down
5 changes: 5 additions & 0 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
@@ -1,3 +1,8 @@
# 0.2.1.0 - December 2023

* Add `findIndexL`, `findIndexR`, `findIndicesL`, `findIndicesR`
* Fix bug in `|>` & `<|` ([#10](https://github.com/konsumlamm/rrb-vector/issues/10))

# 0.2.0.1 - October 2023

* Support `primitive-0.9` and `deepseq-1.5`
Expand Down
7 changes: 4 additions & 3 deletions rrb-vector-strict.cabal
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
name: rrb-vector-strict
version: 0.2.0.1
version: 0.2.1.0
synopsis: Efficient RRB-Vectors
description:
An RRB-Vector is an efficient sequence data structure.
Expand Down Expand Up @@ -31,8 +31,9 @@ tested-with:
GHC == 8.10.7
GHC == 9.0.2
GHC == 9.2.8
GHC == 9.4.7
GHC == 9.4.8
GHC == 9.6.3
GHC == 9.8.1

source-repository head
type: git
Expand Down Expand Up @@ -61,7 +62,7 @@ test-suite test
Strictness
type: exitcode-stdio-1.0
ghc-options: -Wall -Wno-orphans -Wno-type-defaults
build-depends: base, deepseq, quickcheck-classes-base, rrb-vector-strict, tasty, tasty-quickcheck
build-depends: base, containers, deepseq, quickcheck-classes-base, rrb-vector, tasty, tasty-quickcheck
if impl(ghc >= 8.6)
build-depends: nothunks
default-language: Haskell2010
Expand Down
1 change: 1 addition & 0 deletions src/Data/RRBVector/Strict.hs
Original file line number Diff line number Diff line change
Expand Up @@ -33,6 +33,7 @@ module Data.RRBVector.Strict
, adjust, adjust'
, take, drop, splitAt
, insertAt, deleteAt
, findIndexL, findIndexR, findIndicesL, findIndicesR
-- * With Index
--
-- | Reexported from [indexed-traversable](https://hackage.haskell.org/package/indexed-traversable).
Expand Down
17 changes: 17 additions & 0 deletions src/Data/RRBVector/Strict/Internal.hs
Original file line number Diff line number Diff line change
Expand Up @@ -24,6 +24,7 @@ module Data.RRBVector.Strict.Internal
, adjust, adjust'
, take, drop, splitAt
, insertAt, deleteAt
, findIndexL, findIndexR, findIndicesL, findIndicesR
-- * Transformations
, map, map', reverse
-- * Zipping and unzipping
Expand Down Expand Up @@ -651,6 +652,22 @@ insertAt i x v = let (left, right) = splitAt i v in (left |> x) >< right
deleteAt :: Int -> Vector a -> Vector a
deleteAt i v = let (left, right) = splitAt (i + 1) v in take i left >< right

-- | \(O(n)\). Find the first index from the left that satisfies the predicate.
findIndexL :: (a -> Bool) -> Vector a -> Maybe Int
findIndexL f = ifoldr (\i x acc -> if f x then Just i else acc) Nothing

-- | \(O(n)\). Find the first index from the right that satisfies the predicate.
findIndexR :: (a -> Bool) -> Vector a -> Maybe Int
findIndexR f = ifoldl (\i acc x -> if f x then Just i else acc) Nothing

-- | \(O(n)\). Find the indices that satisfy the predicate, starting from the left.
findIndicesL :: (a -> Bool) -> Vector a -> [Int]
findIndicesL f = ifoldr (\i x acc -> if f x then i : acc else acc) []

-- | \(O(n)\). Find the indices that satisfy the predicate, starting from the right.
findIndicesR :: (a -> Bool) -> Vector a -> [Int]
findIndicesR f = ifoldl (\i acc x -> if f x then i : acc else acc) []

-- concatenation

-- | \(O(\log \max(n_1, n_2))\). Concatenates two vectors.
Expand Down
19 changes: 19 additions & 0 deletions test/Properties.hs
Original file line number Diff line number Diff line change
@@ -1,5 +1,7 @@
{-# LANGUAGE CPP #-}

{-# OPTIONS_GHC -Wno-incomplete-uni-patterns #-}

module Properties
( properties
) where
Expand All @@ -12,6 +14,7 @@ import Data.List (uncons)
import Data.Proxy (Proxy(..))
import Prelude hiding ((==)) -- use @===@ instead

import qualified Data.Sequence as Seq
import qualified Data.RRBVector.Strict as V
import Test.QuickCheck.Classes.Base
import Test.Tasty
Expand Down Expand Up @@ -135,6 +138,22 @@ properties = testGroup "properties"
, testProperty "satisfies `deleteAt 0 v = drop 1 v`" $ \v -> V.deleteAt 0 v === V.drop 1 v
, testProperty "satisfies `deleteAt (length v - 1) v = take (length v - 1) v`" $ \v -> V.deleteAt (length v - 1) v === V.take (length v - 1) v
]
, testGroup "findIndexL"
[ testProperty "finds the first index" $ \v (Fn f) -> V.findIndexL f v === Seq.findIndexL f (Seq.fromList (toList v))
, testProperty "returns Nothing for the empty vector" $ \(Fn f) -> V.findIndexL f V.empty === Nothing
]
, testGroup "findIndexR"
[ testProperty "finds the last index" $ \v (Fn f) -> V.findIndexR f v === Seq.findIndexR f (Seq.fromList (toList v))
, testProperty "returns Nothing for the empty vector" $ \(Fn f) -> V.findIndexR f V.empty === Nothing
]
, localOption (QuickCheckMaxSize 1000) $ testGroup "findIndicesL"
[ testProperty "finds the indices starting from the left" $ \v (Fn f) -> V.findIndicesL f v === Seq.findIndicesL f (Seq.fromList (toList v))
, testProperty "returns [] for the empty vector" $ \(Fn f) -> V.findIndicesL f V.empty === []
]
, localOption (QuickCheckMaxSize 1000) $ testGroup "findIndicesR"
[ testProperty "finds the indices starting from the right" $ \v (Fn f) -> V.findIndicesR f v === Seq.findIndicesR f (Seq.fromList (toList v))
, testProperty "returns [] for the empty vector" $ \(Fn f) -> V.findIndicesR f V.empty === []
]
, testGroup "reverse"
[ testProperty "reverses the vector" $ \v -> toList (V.reverse v) === reverse (toList v)
]
Expand Down

0 comments on commit 33eb772

Please sign in to comment.