packages feed

nonempty-vector 0.3 → 1.0

raw patch · 20 files changed

+5960/−23 lines, 20 filesPVP ok

version bump matches the API change (PVP)

API changes (from Hackage documentation)

+ Data.Vector.NonEmpty.Unboxed: (!) :: Unbox a => NonEmptyUVector a -> Int -> a
+ Data.Vector.NonEmpty.Unboxed: (!?) :: Unbox a => NonEmptyUVector a -> Int -> Maybe a
+ Data.Vector.NonEmpty.Unboxed: (++) :: Unbox a => NonEmptyUVector a -> NonEmptyUVector a -> NonEmptyUVector a
+ Data.Vector.NonEmpty.Unboxed: (//) :: Unbox a => NonEmptyUVector a -> [(Int, a)] -> NonEmptyUVector a
+ Data.Vector.NonEmpty.Unboxed: accum :: (Unbox a, Unbox b) => (a -> b -> a) -> NonEmptyUVector a -> [(Int, b)] -> NonEmptyUVector a
+ Data.Vector.NonEmpty.Unboxed: accumulate :: (Unbox a, Unbox b) => (a -> b -> a) -> NonEmptyUVector a -> Vector (Int, b) -> NonEmptyUVector a
+ Data.Vector.NonEmpty.Unboxed: accumulate_ :: (Unbox a, Unbox b) => (a -> b -> a) -> NonEmptyUVector a -> Vector Int -> Vector b -> NonEmptyUVector a
+ Data.Vector.NonEmpty.Unboxed: all :: Unbox a => (a -> Bool) -> NonEmptyUVector a -> Bool
+ Data.Vector.NonEmpty.Unboxed: and :: NonEmptyUVector Bool -> Bool
+ Data.Vector.NonEmpty.Unboxed: any :: Unbox a => (a -> Bool) -> NonEmptyUVector a -> Bool
+ Data.Vector.NonEmpty.Unboxed: backpermute :: Unbox a => NonEmptyUVector a -> NonEmptyUVector Int -> NonEmptyUVector a
+ Data.Vector.NonEmpty.Unboxed: break :: Unbox a => (a -> Bool) -> NonEmptyUVector a -> (Vector a, Vector a)
+ Data.Vector.NonEmpty.Unboxed: concat :: Unbox a => [NonEmptyUVector a] -> Maybe (NonEmptyUVector a)
+ Data.Vector.NonEmpty.Unboxed: concat1 :: Unbox a => NonEmpty (NonEmptyUVector a) -> NonEmptyUVector a
+ Data.Vector.NonEmpty.Unboxed: concatMap :: (Unbox a, Unbox b) => (a -> NonEmptyUVector b) -> NonEmptyUVector a -> NonEmptyUVector b
+ Data.Vector.NonEmpty.Unboxed: cons :: Unbox a => a -> NonEmptyUVector a -> NonEmptyUVector a
+ Data.Vector.NonEmpty.Unboxed: consV :: Unbox a => a -> Vector a -> NonEmptyUVector a
+ Data.Vector.NonEmpty.Unboxed: constructN :: Unbox a => Int -> (Vector a -> a) -> Maybe (NonEmptyUVector a)
+ Data.Vector.NonEmpty.Unboxed: constructrN :: Unbox a => Int -> (Vector a -> a) -> Maybe (NonEmptyUVector a)
+ Data.Vector.NonEmpty.Unboxed: create :: Unbox a => (forall s. () => ST s (MVector s a)) -> Maybe (NonEmptyUVector a)
+ Data.Vector.NonEmpty.Unboxed: createT :: (Traversable t, Unbox a) => (forall s. () => ST s (t (MVector s a))) -> t (Maybe (NonEmptyUVector a))
+ Data.Vector.NonEmpty.Unboxed: data NonEmptyUVector a
+ Data.Vector.NonEmpty.Unboxed: drop :: Unbox a => Int -> NonEmptyUVector a -> Vector a
+ Data.Vector.NonEmpty.Unboxed: dropWhile :: Unbox a => (a -> Bool) -> NonEmptyUVector a -> Vector a
+ Data.Vector.NonEmpty.Unboxed: elem :: (Unbox a, Eq a) => a -> NonEmptyUVector a -> Bool
+ Data.Vector.NonEmpty.Unboxed: elemIndex :: (Unbox a, Eq a) => a -> NonEmptyUVector a -> Maybe Int
+ Data.Vector.NonEmpty.Unboxed: elemIndices :: (Unbox a, Eq a) => a -> NonEmptyUVector a -> Vector Int
+ Data.Vector.NonEmpty.Unboxed: enumFromN :: (Unbox a, Num a) => a -> Int -> Maybe (NonEmptyUVector a)
+ Data.Vector.NonEmpty.Unboxed: enumFromN1 :: (Unbox a, Num a) => a -> Int -> NonEmptyUVector a
+ Data.Vector.NonEmpty.Unboxed: enumFromStepN :: (Unbox a, Num a) => a -> a -> Int -> Maybe (NonEmptyUVector a)
+ Data.Vector.NonEmpty.Unboxed: enumFromStepN1 :: (Unbox a, Num a) => a -> a -> Int -> NonEmptyUVector a
+ Data.Vector.NonEmpty.Unboxed: enumFromThenTo :: (Unbox a, Enum a) => a -> a -> a -> Maybe (NonEmptyUVector a)
+ Data.Vector.NonEmpty.Unboxed: enumFromTo :: (Unbox a, Enum a) => a -> a -> Maybe (NonEmptyUVector a)
+ Data.Vector.NonEmpty.Unboxed: filter :: Unbox a => (a -> Bool) -> NonEmptyUVector a -> Vector a
+ Data.Vector.NonEmpty.Unboxed: filterM :: (Unbox a, Monad m) => (a -> m Bool) -> NonEmptyUVector a -> m (Vector a)
+ Data.Vector.NonEmpty.Unboxed: find :: Unbox a => (a -> Bool) -> NonEmptyUVector a -> Maybe a
+ Data.Vector.NonEmpty.Unboxed: findIndex :: Unbox a => (a -> Bool) -> NonEmptyUVector a -> Maybe Int
+ Data.Vector.NonEmpty.Unboxed: findIndices :: Unbox a => (a -> Bool) -> NonEmptyUVector a -> Vector Int
+ Data.Vector.NonEmpty.Unboxed: fold1M :: (Unbox a, Monad m) => (a -> a -> m a) -> NonEmptyUVector a -> m a
+ Data.Vector.NonEmpty.Unboxed: fold1M' :: (Unbox a, Monad m) => (a -> a -> m a) -> NonEmptyUVector a -> m a
+ Data.Vector.NonEmpty.Unboxed: fold1M'_ :: (Unbox a, Monad m) => (a -> a -> m a) -> NonEmptyUVector a -> m ()
+ Data.Vector.NonEmpty.Unboxed: fold1M_ :: (Unbox a, Monad m) => (a -> a -> m a) -> NonEmptyUVector a -> m ()
+ Data.Vector.NonEmpty.Unboxed: foldM :: (Unbox b, Monad m) => (a -> b -> m a) -> a -> NonEmptyUVector b -> m a
+ Data.Vector.NonEmpty.Unboxed: foldM' :: (Unbox b, Monad m) => (a -> b -> m a) -> a -> NonEmptyUVector b -> m a
+ Data.Vector.NonEmpty.Unboxed: foldM'_ :: (Unbox b, Monad m) => (a -> b -> m a) -> a -> NonEmptyUVector b -> m ()
+ Data.Vector.NonEmpty.Unboxed: foldM_ :: (Unbox b, Monad m) => (a -> b -> m a) -> a -> NonEmptyUVector b -> m ()
+ Data.Vector.NonEmpty.Unboxed: foldl :: Unbox b => (a -> b -> a) -> a -> NonEmptyUVector b -> a
+ Data.Vector.NonEmpty.Unboxed: foldl' :: Unbox b => (a -> b -> a) -> a -> NonEmptyUVector b -> a
+ Data.Vector.NonEmpty.Unboxed: foldl1 :: Unbox a => (a -> a -> a) -> NonEmptyUVector a -> a
+ Data.Vector.NonEmpty.Unboxed: foldl1' :: Unbox a => (a -> a -> a) -> NonEmptyUVector a -> a
+ Data.Vector.NonEmpty.Unboxed: foldr :: Unbox a => (a -> b -> b) -> b -> NonEmptyUVector a -> b
+ Data.Vector.NonEmpty.Unboxed: foldr' :: Unbox a => (a -> b -> b) -> b -> NonEmptyUVector a -> b
+ Data.Vector.NonEmpty.Unboxed: foldr1 :: Unbox a => (a -> a -> a) -> NonEmptyUVector a -> a
+ Data.Vector.NonEmpty.Unboxed: foldr1' :: Unbox a => (a -> a -> a) -> NonEmptyUVector a -> a
+ Data.Vector.NonEmpty.Unboxed: forM :: (Unbox a, Unbox b, Monad m) => NonEmptyUVector a -> (a -> m b) -> m (NonEmptyUVector b)
+ Data.Vector.NonEmpty.Unboxed: forM_ :: (Unbox a, Monad m) => NonEmptyUVector a -> (a -> m b) -> m ()
+ Data.Vector.NonEmpty.Unboxed: force :: Unbox a => NonEmptyUVector a -> NonEmptyUVector a
+ Data.Vector.NonEmpty.Unboxed: fromList :: Unbox a => [a] -> Maybe (NonEmptyUVector a)
+ Data.Vector.NonEmpty.Unboxed: fromListN :: Unbox a => Int -> [a] -> Maybe (NonEmptyUVector a)
+ Data.Vector.NonEmpty.Unboxed: fromNonEmpty :: Unbox a => NonEmpty a -> NonEmptyUVector a
+ Data.Vector.NonEmpty.Unboxed: fromNonEmptyN :: Unbox a => Int -> NonEmpty a -> Maybe (NonEmptyUVector a)
+ Data.Vector.NonEmpty.Unboxed: fromNonEmptyN1 :: Unbox a => Int -> NonEmpty a -> NonEmptyUVector a
+ Data.Vector.NonEmpty.Unboxed: fromVector :: Unbox a => Vector a -> Maybe (NonEmptyUVector a)
+ Data.Vector.NonEmpty.Unboxed: generate :: Unbox a => Int -> (Int -> a) -> Maybe (NonEmptyUVector a)
+ Data.Vector.NonEmpty.Unboxed: generate1 :: Unbox a => Int -> (Int -> a) -> NonEmptyUVector a
+ Data.Vector.NonEmpty.Unboxed: generate1M :: (Monad m, Unbox a) => Int -> (Int -> m a) -> m (NonEmptyUVector a)
+ Data.Vector.NonEmpty.Unboxed: generateM :: (Monad m, Unbox a) => Int -> (Int -> m a) -> m (Maybe (NonEmptyUVector a))
+ Data.Vector.NonEmpty.Unboxed: group :: (Unbox a, Eq a) => NonEmptyUVector a -> NonEmpty (NonEmptyUVector a)
+ Data.Vector.NonEmpty.Unboxed: groupBy :: (Eq a, Unbox a) => (a -> a -> Bool) -> NonEmptyUVector a -> NonEmpty (NonEmptyUVector a)
+ Data.Vector.NonEmpty.Unboxed: head :: Unbox a => NonEmptyUVector a -> a
+ Data.Vector.NonEmpty.Unboxed: headM :: (Monad m, Unbox a) => NonEmptyUVector a -> m a
+ Data.Vector.NonEmpty.Unboxed: ifilter :: Unbox a => (Int -> a -> Bool) -> NonEmptyUVector a -> Vector a
+ Data.Vector.NonEmpty.Unboxed: ifilterM :: (Unbox a, Monad m) => (Int -> a -> m Bool) -> NonEmptyUVector a -> m (Vector a)
+ Data.Vector.NonEmpty.Unboxed: ifoldM :: (Unbox b, Monad m) => (a -> Int -> b -> m a) -> a -> NonEmptyUVector b -> m a
+ Data.Vector.NonEmpty.Unboxed: ifoldM' :: (Unbox b, Monad m) => (a -> Int -> b -> m a) -> a -> NonEmptyUVector b -> m a
+ Data.Vector.NonEmpty.Unboxed: ifoldM'_ :: (Unbox b, Monad m) => (a -> Int -> b -> m a) -> a -> NonEmptyUVector b -> m ()
+ Data.Vector.NonEmpty.Unboxed: ifoldM_ :: (Unbox b, Monad m) => (a -> Int -> b -> m a) -> a -> NonEmptyUVector b -> m ()
+ Data.Vector.NonEmpty.Unboxed: ifoldl :: Unbox b => (a -> Int -> b -> a) -> a -> NonEmptyUVector b -> a
+ Data.Vector.NonEmpty.Unboxed: ifoldl' :: Unbox b => (a -> Int -> b -> a) -> a -> NonEmptyUVector b -> a
+ Data.Vector.NonEmpty.Unboxed: ifoldr :: Unbox a => (Int -> a -> b -> b) -> b -> NonEmptyUVector a -> b
+ Data.Vector.NonEmpty.Unboxed: ifoldr' :: Unbox a => (Int -> a -> b -> b) -> b -> NonEmptyUVector a -> b
+ Data.Vector.NonEmpty.Unboxed: imap :: (Unbox a, Unbox b) => (Int -> a -> b) -> NonEmptyUVector a -> NonEmptyUVector b
+ Data.Vector.NonEmpty.Unboxed: imapM :: (Unbox a, Unbox b, Monad m) => (Int -> a -> m b) -> NonEmptyUVector a -> m (NonEmptyUVector b)
+ Data.Vector.NonEmpty.Unboxed: imapM_ :: (Unbox a, Monad m) => (Int -> a -> m b) -> NonEmptyUVector a -> m ()
+ Data.Vector.NonEmpty.Unboxed: imapMaybe :: (Unbox a, Unbox b) => (Int -> a -> Maybe b) -> NonEmptyUVector a -> Vector b
+ Data.Vector.NonEmpty.Unboxed: indexM :: (Monad m, Unbox a) => NonEmptyUVector a -> Int -> m a
+ Data.Vector.NonEmpty.Unboxed: indexed :: Unbox a => NonEmptyUVector a -> NonEmptyUVector (Int, a)
+ Data.Vector.NonEmpty.Unboxed: init :: Unbox a => NonEmptyUVector a -> Vector a
+ Data.Vector.NonEmpty.Unboxed: intersperse :: Unbox a => a -> NonEmptyUVector a -> NonEmptyUVector a
+ Data.Vector.NonEmpty.Unboxed: iscanl :: (Unbox a, Unbox b) => (Int -> a -> b -> a) -> a -> NonEmptyUVector b -> NonEmptyUVector a
+ Data.Vector.NonEmpty.Unboxed: iscanl' :: (Unbox a, Unbox b) => (Int -> a -> b -> a) -> a -> NonEmptyUVector b -> NonEmptyUVector a
+ Data.Vector.NonEmpty.Unboxed: iscanr :: (Unbox a, Unbox b) => (Int -> a -> b -> b) -> b -> NonEmptyUVector a -> NonEmptyUVector b
+ Data.Vector.NonEmpty.Unboxed: iscanr' :: (Unbox a, Unbox b) => (Int -> a -> b -> b) -> b -> NonEmptyUVector a -> NonEmptyUVector b
+ Data.Vector.NonEmpty.Unboxed: iterateN :: Unbox a => Int -> (a -> a) -> a -> Maybe (NonEmptyUVector a)
+ Data.Vector.NonEmpty.Unboxed: iterateN1 :: Unbox a => Int -> (a -> a) -> a -> NonEmptyUVector a
+ Data.Vector.NonEmpty.Unboxed: iterateN1M :: (Monad m, Unbox a) => Int -> (a -> m a) -> a -> m (NonEmptyUVector a)
+ Data.Vector.NonEmpty.Unboxed: iterateNM :: (Monad m, Unbox a) => Int -> (a -> m a) -> a -> m (Maybe (NonEmptyUVector a))
+ Data.Vector.NonEmpty.Unboxed: izipWith :: (Unbox a, Unbox b, Unbox c) => (Int -> a -> b -> c) -> NonEmptyUVector a -> NonEmptyUVector b -> NonEmptyUVector c
+ Data.Vector.NonEmpty.Unboxed: izipWith3 :: (Unbox a, Unbox b, Unbox c, Unbox d) => (Int -> a -> b -> c -> d) -> NonEmptyUVector a -> NonEmptyUVector b -> NonEmptyUVector c -> NonEmptyUVector d
+ Data.Vector.NonEmpty.Unboxed: izipWith4 :: (Unbox a, Unbox b, Unbox c, Unbox d, Unbox e) => (Int -> a -> b -> c -> d -> e) -> NonEmptyUVector a -> NonEmptyUVector b -> NonEmptyUVector c -> NonEmptyUVector d -> NonEmptyUVector e
+ Data.Vector.NonEmpty.Unboxed: izipWith5 :: (Unbox a, Unbox b, Unbox c, Unbox d, Unbox e, Unbox f) => (Int -> a -> b -> c -> d -> e -> f) -> NonEmptyUVector a -> NonEmptyUVector b -> NonEmptyUVector c -> NonEmptyUVector d -> NonEmptyUVector e -> NonEmptyUVector f
+ Data.Vector.NonEmpty.Unboxed: izipWith6 :: (Unbox a, Unbox b, Unbox c, Unbox d, Unbox e, Unbox f, Unbox g) => (Int -> a -> b -> c -> d -> e -> f -> g) -> NonEmptyUVector a -> NonEmptyUVector b -> NonEmptyUVector c -> NonEmptyUVector d -> NonEmptyUVector e -> NonEmptyUVector f -> NonEmptyUVector g
+ Data.Vector.NonEmpty.Unboxed: izipWithM :: (Unbox a, Unbox b, Unbox c, Monad m) => (Int -> a -> b -> m c) -> NonEmptyUVector a -> NonEmptyUVector b -> m (NonEmptyUVector c)
+ Data.Vector.NonEmpty.Unboxed: izipWithM_ :: (Unbox a, Unbox b, Monad m) => (Int -> a -> b -> m c) -> NonEmptyUVector a -> NonEmptyUVector b -> m ()
+ Data.Vector.NonEmpty.Unboxed: last :: Unbox a => NonEmptyUVector a -> a
+ Data.Vector.NonEmpty.Unboxed: lastM :: (Monad m, Unbox a) => NonEmptyUVector a -> m a
+ Data.Vector.NonEmpty.Unboxed: length :: Unbox a => NonEmptyUVector a -> Int
+ Data.Vector.NonEmpty.Unboxed: map :: (Unbox a, Unbox b) => (a -> b) -> NonEmptyUVector a -> NonEmptyUVector b
+ Data.Vector.NonEmpty.Unboxed: mapM :: (Unbox a, Unbox b, Monad m) => (a -> m b) -> NonEmptyUVector a -> m (NonEmptyUVector b)
+ Data.Vector.NonEmpty.Unboxed: mapM_ :: (Unbox a, Monad m) => (a -> m b) -> NonEmptyUVector a -> m ()
+ Data.Vector.NonEmpty.Unboxed: mapMaybe :: (Unbox a, Unbox b) => (a -> Maybe b) -> NonEmptyUVector a -> Vector b
+ Data.Vector.NonEmpty.Unboxed: maxIndex :: (Unbox a, Ord a) => NonEmptyUVector a -> Int
+ Data.Vector.NonEmpty.Unboxed: maxIndexBy :: Unbox a => (a -> a -> Ordering) -> NonEmptyUVector a -> Int
+ Data.Vector.NonEmpty.Unboxed: maximum :: (Unbox a, Ord a) => NonEmptyUVector a -> a
+ Data.Vector.NonEmpty.Unboxed: maximumBy :: Unbox a => (a -> a -> Ordering) -> NonEmptyUVector a -> a
+ Data.Vector.NonEmpty.Unboxed: minIndex :: (Unbox a, Ord a) => NonEmptyUVector a -> Int
+ Data.Vector.NonEmpty.Unboxed: minIndexBy :: Unbox a => (a -> a -> Ordering) -> NonEmptyUVector a -> Int
+ Data.Vector.NonEmpty.Unboxed: minimum :: (Unbox a, Ord a) => NonEmptyUVector a -> a
+ Data.Vector.NonEmpty.Unboxed: minimumBy :: Unbox a => (a -> a -> Ordering) -> NonEmptyUVector a -> a
+ Data.Vector.NonEmpty.Unboxed: modify :: Unbox a => (forall s. () => MVector s a -> ST s ()) -> NonEmptyUVector a -> NonEmptyUVector a
+ Data.Vector.NonEmpty.Unboxed: notElem :: (Unbox a, Eq a) => a -> NonEmptyUVector a -> Bool
+ Data.Vector.NonEmpty.Unboxed: or :: NonEmptyUVector Bool -> Bool
+ Data.Vector.NonEmpty.Unboxed: partition :: Unbox a => (a -> Bool) -> NonEmptyUVector a -> (Vector a, Vector a)
+ Data.Vector.NonEmpty.Unboxed: partitionWith :: (Unbox a, Unbox b, Unbox c) => (a -> Either b c) -> NonEmptyUVector a -> (Vector b, Vector c)
+ Data.Vector.NonEmpty.Unboxed: postscanl :: (Unbox a, Unbox b) => (a -> b -> a) -> a -> NonEmptyUVector b -> NonEmptyUVector a
+ Data.Vector.NonEmpty.Unboxed: postscanl' :: (Unbox a, Unbox b) => (a -> b -> a) -> a -> NonEmptyUVector b -> NonEmptyUVector a
+ Data.Vector.NonEmpty.Unboxed: postscanr :: (Unbox a, Unbox b) => (a -> b -> b) -> b -> NonEmptyUVector a -> NonEmptyUVector b
+ Data.Vector.NonEmpty.Unboxed: postscanr' :: (Unbox a, Unbox b) => (a -> b -> b) -> b -> NonEmptyUVector a -> NonEmptyUVector b
+ Data.Vector.NonEmpty.Unboxed: prescanl :: (Unbox a, Unbox b) => (a -> b -> a) -> a -> NonEmptyUVector b -> NonEmptyUVector a
+ Data.Vector.NonEmpty.Unboxed: prescanl' :: (Unbox a, Unbox b) => (a -> b -> a) -> a -> NonEmptyUVector b -> NonEmptyUVector a
+ Data.Vector.NonEmpty.Unboxed: prescanr :: (Unbox a, Unbox b) => (a -> b -> b) -> b -> NonEmptyUVector a -> NonEmptyUVector b
+ Data.Vector.NonEmpty.Unboxed: prescanr' :: (Unbox a, Unbox b) => (a -> b -> b) -> b -> NonEmptyUVector a -> NonEmptyUVector b
+ Data.Vector.NonEmpty.Unboxed: product :: (Num a, Unbox a) => NonEmptyUVector a -> a
+ Data.Vector.NonEmpty.Unboxed: replicate :: Unbox a => Int -> a -> Maybe (NonEmptyUVector a)
+ Data.Vector.NonEmpty.Unboxed: replicate1 :: Unbox a => Int -> a -> NonEmptyUVector a
+ Data.Vector.NonEmpty.Unboxed: replicate1M :: (Monad m, Unbox a) => Int -> m a -> m (NonEmptyUVector a)
+ Data.Vector.NonEmpty.Unboxed: replicateM :: (Monad m, Unbox a) => Int -> m a -> m (Maybe (NonEmptyUVector a))
+ Data.Vector.NonEmpty.Unboxed: reverse :: Unbox a => NonEmptyUVector a -> NonEmptyUVector a
+ Data.Vector.NonEmpty.Unboxed: scanl :: (Unbox a, Unbox b) => (a -> b -> a) -> a -> NonEmptyUVector b -> NonEmptyUVector a
+ Data.Vector.NonEmpty.Unboxed: scanl' :: (Unbox a, Unbox b) => (a -> b -> a) -> a -> NonEmptyUVector b -> NonEmptyUVector a
+ Data.Vector.NonEmpty.Unboxed: scanl1 :: Unbox a => (a -> a -> a) -> NonEmptyUVector a -> NonEmptyUVector a
+ Data.Vector.NonEmpty.Unboxed: scanl1' :: Unbox a => (a -> a -> a) -> NonEmptyUVector a -> NonEmptyUVector a
+ Data.Vector.NonEmpty.Unboxed: scanr :: (Unbox a, Unbox b) => (a -> b -> b) -> b -> NonEmptyUVector a -> NonEmptyUVector b
+ Data.Vector.NonEmpty.Unboxed: scanr' :: (Unbox a, Unbox b) => (a -> b -> b) -> b -> NonEmptyUVector a -> NonEmptyUVector b
+ Data.Vector.NonEmpty.Unboxed: scanr1 :: Unbox a => (a -> a -> a) -> NonEmptyUVector a -> NonEmptyUVector a
+ Data.Vector.NonEmpty.Unboxed: scanr1' :: Unbox a => (a -> a -> a) -> NonEmptyUVector a -> NonEmptyUVector a
+ Data.Vector.NonEmpty.Unboxed: singleton :: Unbox a => a -> NonEmptyUVector a
+ Data.Vector.NonEmpty.Unboxed: slice :: Unbox a => Int -> Int -> NonEmptyUVector a -> Vector a
+ Data.Vector.NonEmpty.Unboxed: snoc :: Unbox a => NonEmptyUVector a -> a -> NonEmptyUVector a
+ Data.Vector.NonEmpty.Unboxed: snocV :: Unbox a => Vector a -> a -> NonEmptyUVector a
+ Data.Vector.NonEmpty.Unboxed: span :: Unbox a => (a -> Bool) -> NonEmptyUVector a -> (Vector a, Vector a)
+ Data.Vector.NonEmpty.Unboxed: splitAt :: Unbox a => Int -> NonEmptyUVector a -> (Vector a, Vector a)
+ Data.Vector.NonEmpty.Unboxed: sum :: (Num a, Unbox a) => NonEmptyUVector a -> a
+ Data.Vector.NonEmpty.Unboxed: tail :: Unbox a => NonEmptyUVector a -> Vector a
+ Data.Vector.NonEmpty.Unboxed: take :: Unbox a => Int -> NonEmptyUVector a -> Vector a
+ Data.Vector.NonEmpty.Unboxed: takeWhile :: Unbox a => (a -> Bool) -> NonEmptyUVector a -> Vector a
+ Data.Vector.NonEmpty.Unboxed: toList :: Unbox a => NonEmptyUVector a -> [a]
+ Data.Vector.NonEmpty.Unboxed: toNonEmpty :: Unbox a => NonEmptyUVector a -> NonEmpty a
+ Data.Vector.NonEmpty.Unboxed: toVector :: Unbox a => NonEmptyUVector a -> Vector a
+ Data.Vector.NonEmpty.Unboxed: uncons :: Unbox a => NonEmptyUVector a -> (a, Vector a)
+ Data.Vector.NonEmpty.Unboxed: unfoldr :: Unbox a => (b -> Maybe (a, b)) -> b -> Maybe (NonEmptyUVector a)
+ Data.Vector.NonEmpty.Unboxed: unfoldr1 :: Unbox a => (b -> Maybe (a, b)) -> a -> b -> NonEmptyUVector a
+ Data.Vector.NonEmpty.Unboxed: unfoldr1M :: (Monad m, Unbox a) => (b -> m (Maybe (a, b))) -> a -> b -> m (NonEmptyUVector a)
+ Data.Vector.NonEmpty.Unboxed: unfoldr1N :: Unbox a => Int -> (b -> Maybe (a, b)) -> a -> b -> NonEmptyUVector a
+ Data.Vector.NonEmpty.Unboxed: unfoldr1NM :: (Unbox a, Monad m) => Int -> (b -> m (Maybe (a, b))) -> a -> b -> m (NonEmptyUVector a)
+ Data.Vector.NonEmpty.Unboxed: unfoldrM :: (Unbox a, Monad m) => (b -> m (Maybe (a, b))) -> b -> m (Maybe (NonEmptyUVector a))
+ Data.Vector.NonEmpty.Unboxed: unfoldrN :: Unbox a => Int -> (b -> Maybe (a, b)) -> b -> Maybe (NonEmptyUVector a)
+ Data.Vector.NonEmpty.Unboxed: unfoldrNM :: (Unbox a, Monad m) => Int -> (b -> m (Maybe (a, b))) -> b -> m (Maybe (NonEmptyUVector a))
+ Data.Vector.NonEmpty.Unboxed: uniq :: (Unbox a, Eq a) => NonEmptyUVector a -> NonEmptyUVector a
+ Data.Vector.NonEmpty.Unboxed: unsafeAccum :: (Unbox a, Unbox b) => (a -> b -> a) -> NonEmptyUVector a -> [(Int, b)] -> NonEmptyUVector a
+ Data.Vector.NonEmpty.Unboxed: unsafeAccumulate :: (Unbox a, Unbox b) => (a -> b -> a) -> NonEmptyUVector a -> Vector (Int, b) -> NonEmptyUVector a
+ Data.Vector.NonEmpty.Unboxed: unsafeAccumulate_ :: (Unbox a, Unbox b) => (a -> b -> a) -> NonEmptyUVector a -> Vector Int -> Vector b -> NonEmptyUVector a
+ Data.Vector.NonEmpty.Unboxed: unsafeBackpermute :: Unbox a => NonEmptyUVector a -> NonEmptyUVector Int -> NonEmptyUVector a
+ Data.Vector.NonEmpty.Unboxed: unsafeCreate :: Unbox a => (forall s. () => ST s (MVector s a)) -> NonEmptyUVector a
+ Data.Vector.NonEmpty.Unboxed: unsafeCreateT :: (Traversable t, Unbox a) => (forall s. () => ST s (t (MVector s a))) -> t (NonEmptyUVector a)
+ Data.Vector.NonEmpty.Unboxed: unsafeDrop :: Unbox a => Int -> NonEmptyUVector a -> Vector a
+ Data.Vector.NonEmpty.Unboxed: unsafeFromList :: Unbox a => [a] -> NonEmptyUVector a
+ Data.Vector.NonEmpty.Unboxed: unsafeFromVector :: Unbox a => Vector a -> NonEmptyUVector a
+ Data.Vector.NonEmpty.Unboxed: unsafeIndex :: Unbox a => NonEmptyUVector a -> Int -> a
+ Data.Vector.NonEmpty.Unboxed: unsafeIndexM :: (Monad m, Unbox a) => NonEmptyUVector a -> Int -> m a
+ Data.Vector.NonEmpty.Unboxed: unsafeSlice :: Unbox a => Int -> Int -> NonEmptyUVector a -> Vector a
+ Data.Vector.NonEmpty.Unboxed: unsafeTake :: Unbox a => Int -> NonEmptyUVector a -> Vector a
+ Data.Vector.NonEmpty.Unboxed: unsafeUpd :: Unbox a => NonEmptyUVector a -> [(Int, a)] -> NonEmptyUVector a
+ Data.Vector.NonEmpty.Unboxed: unsafeUpdate :: Unbox a => NonEmptyUVector a -> Vector (Int, a) -> NonEmptyUVector a
+ Data.Vector.NonEmpty.Unboxed: unsafeUpdate_ :: Unbox a => NonEmptyUVector a -> Vector Int -> Vector a -> NonEmptyUVector a
+ Data.Vector.NonEmpty.Unboxed: unsnoc :: Unbox a => NonEmptyUVector a -> (Vector a, a)
+ Data.Vector.NonEmpty.Unboxed: unstablePartition :: Unbox a => (a -> Bool) -> NonEmptyUVector a -> (Vector a, Vector a)
+ Data.Vector.NonEmpty.Unboxed: unzip :: (Unbox a, Unbox b) => NonEmptyUVector (a, b) -> (NonEmptyUVector a, NonEmptyUVector b)
+ Data.Vector.NonEmpty.Unboxed: unzip3 :: (Unbox a, Unbox b, Unbox c) => NonEmptyUVector (a, b, c) -> (NonEmptyUVector a, NonEmptyUVector b, NonEmptyUVector c)
+ Data.Vector.NonEmpty.Unboxed: unzip4 :: (Unbox a, Unbox b, Unbox c, Unbox d) => NonEmptyUVector (a, b, c, d) -> (NonEmptyUVector a, NonEmptyUVector b, NonEmptyUVector c, NonEmptyUVector d)
+ Data.Vector.NonEmpty.Unboxed: unzip5 :: (Unbox a, Unbox b, Unbox c, Unbox d, Unbox e) => NonEmptyUVector (a, b, c, d, e) -> (NonEmptyUVector a, NonEmptyUVector b, NonEmptyUVector c, NonEmptyUVector d, NonEmptyUVector e)
+ Data.Vector.NonEmpty.Unboxed: unzip6 :: (Unbox a, Unbox b, Unbox c, Unbox d, Unbox e, Unbox f) => NonEmptyUVector (a, b, c, d, e, f) -> (NonEmptyUVector a, NonEmptyUVector b, NonEmptyUVector c, NonEmptyUVector d, NonEmptyUVector e, NonEmptyUVector f)
+ Data.Vector.NonEmpty.Unboxed: update :: Unbox a => NonEmptyUVector a -> Vector (Int, a) -> NonEmptyUVector a
+ Data.Vector.NonEmpty.Unboxed: update_ :: Unbox a => NonEmptyUVector a -> Vector Int -> Vector a -> NonEmptyUVector a
+ Data.Vector.NonEmpty.Unboxed: zip :: (Unbox a, Unbox b) => NonEmptyUVector a -> NonEmptyUVector b -> NonEmptyUVector (a, b)
+ Data.Vector.NonEmpty.Unboxed: zip3 :: (Unbox a, Unbox b, Unbox c) => NonEmptyUVector a -> NonEmptyUVector b -> NonEmptyUVector c -> NonEmptyUVector (a, b, c)
+ Data.Vector.NonEmpty.Unboxed: zip4 :: (Unbox a, Unbox b, Unbox c, Unbox d) => NonEmptyUVector a -> NonEmptyUVector b -> NonEmptyUVector c -> NonEmptyUVector d -> NonEmptyUVector (a, b, c, d)
+ Data.Vector.NonEmpty.Unboxed: zip5 :: (Unbox a, Unbox b, Unbox c, Unbox d, Unbox e) => NonEmptyUVector a -> NonEmptyUVector b -> NonEmptyUVector c -> NonEmptyUVector d -> NonEmptyUVector e -> NonEmptyUVector (a, b, c, d, e)
+ Data.Vector.NonEmpty.Unboxed: zip6 :: (Unbox a, Unbox b, Unbox c, Unbox d, Unbox e, Unbox f) => NonEmptyUVector a -> NonEmptyUVector b -> NonEmptyUVector c -> NonEmptyUVector d -> NonEmptyUVector e -> NonEmptyUVector f -> NonEmptyUVector (a, b, c, d, e, f)
+ Data.Vector.NonEmpty.Unboxed: zipWith :: (Unbox a, Unbox b, Unbox c) => (a -> b -> c) -> NonEmptyUVector a -> NonEmptyUVector b -> NonEmptyUVector c
+ Data.Vector.NonEmpty.Unboxed: zipWith3 :: (Unbox a, Unbox b, Unbox c, Unbox d) => (a -> b -> c -> d) -> NonEmptyUVector a -> NonEmptyUVector b -> NonEmptyUVector c -> NonEmptyUVector d
+ Data.Vector.NonEmpty.Unboxed: zipWith4 :: (Unbox a, Unbox b, Unbox c, Unbox d, Unbox e) => (a -> b -> c -> d -> e) -> NonEmptyUVector a -> NonEmptyUVector b -> NonEmptyUVector c -> NonEmptyUVector d -> NonEmptyUVector e
+ Data.Vector.NonEmpty.Unboxed: zipWith5 :: (Unbox a, Unbox b, Unbox c, Unbox d, Unbox e, Unbox f) => (a -> b -> c -> d -> e -> f) -> NonEmptyUVector a -> NonEmptyUVector b -> NonEmptyUVector c -> NonEmptyUVector d -> NonEmptyUVector e -> NonEmptyUVector f
+ Data.Vector.NonEmpty.Unboxed: zipWith6 :: (Unbox a, Unbox b, Unbox c, Unbox d, Unbox e, Unbox f, Unbox g) => (a -> b -> c -> d -> e -> f -> g) -> NonEmptyUVector a -> NonEmptyUVector b -> NonEmptyUVector c -> NonEmptyUVector d -> NonEmptyUVector e -> NonEmptyUVector f -> NonEmptyUVector g
+ Data.Vector.NonEmpty.Unboxed: zipWithM :: (Unbox a, Unbox b, Unbox c, Monad m) => (a -> b -> m c) -> NonEmptyUVector a -> NonEmptyUVector b -> m (NonEmptyUVector c)
+ Data.Vector.NonEmpty.Unboxed: zipWithM_ :: (Unbox a, Unbox b, Monad m) => (a -> b -> m c) -> NonEmptyUVector a -> NonEmptyUVector b -> m ()
+ Data.Vector.NonEmpty.Unboxed.Internal: NonEmptyMUVector :: MVector s a -> NonEmptyMUVector s a
+ Data.Vector.NonEmpty.Unboxed.Internal: NonEmptyUVector :: Vector a -> NonEmptyUVector a
+ Data.Vector.NonEmpty.Unboxed.Internal: [_neUvec] :: NonEmptyUVector a -> Vector a
+ Data.Vector.NonEmpty.Unboxed.Internal: [_nemUvec] :: NonEmptyMUVector s a -> MVector s a
+ Data.Vector.NonEmpty.Unboxed.Internal: instance (Data.Data.Data a, Data.Vector.Unboxed.Base.Unbox a) => Data.Data.Data (Data.Vector.NonEmpty.Unboxed.Internal.NonEmptyUVector a)
+ Data.Vector.NonEmpty.Unboxed.Internal: instance (Data.Vector.Unboxed.Base.Unbox a, GHC.Classes.Eq a) => GHC.Classes.Eq (Data.Vector.NonEmpty.Unboxed.Internal.NonEmptyUVector a)
+ Data.Vector.NonEmpty.Unboxed.Internal: instance (Data.Vector.Unboxed.Base.Unbox a, GHC.Classes.Ord a) => GHC.Classes.Ord (Data.Vector.NonEmpty.Unboxed.Internal.NonEmptyUVector a)
+ Data.Vector.NonEmpty.Unboxed.Internal: instance (Data.Vector.Unboxed.Base.Unbox a, GHC.Read.Read a) => GHC.Read.Read (Data.Vector.NonEmpty.Unboxed.Internal.NonEmptyUVector a)
+ Data.Vector.NonEmpty.Unboxed.Internal: instance (GHC.Show.Show a, Data.Vector.Unboxed.Base.Unbox a) => GHC.Show.Show (Data.Vector.NonEmpty.Unboxed.Internal.NonEmptyUVector a)
+ Data.Vector.NonEmpty.Unboxed.Internal: instance Control.DeepSeq.NFData (Data.Vector.NonEmpty.Unboxed.Internal.NonEmptyUVector a)
+ Data.Vector.NonEmpty.Unboxed.Internal: instance Data.Vector.Unboxed.Base.Unbox a => GHC.Base.Semigroup (Data.Vector.NonEmpty.Unboxed.Internal.NonEmptyUVector a)
+ Data.Vector.NonEmpty.Unboxed.Internal: newtype NonEmptyMUVector s a
+ Data.Vector.NonEmpty.Unboxed.Internal: newtype NonEmptyUVector a
+ Data.Vector.NonEmpty.Unboxed.Internal: type NonEmptyIOUVector = NonEmptyMUVector RealWorld
+ Data.Vector.NonEmpty.Unboxed.Internal: type NonEmptySTUVector s = NonEmptyMUVector s
+ Data.Vector.NonEmpty.Unboxed.Mutable: clear :: (PrimMonad m, Unbox a) => NonEmptyMUVector (PrimState m) a -> m ()
+ Data.Vector.NonEmpty.Unboxed.Mutable: clone :: (PrimMonad m, Unbox a) => NonEmptyMUVector (PrimState m) a -> m (NonEmptyMUVector (PrimState m) a)
+ Data.Vector.NonEmpty.Unboxed.Mutable: copy :: (PrimMonad m, Unbox a) => NonEmptyMUVector (PrimState m) a -> NonEmptyMUVector (PrimState m) a -> m ()
+ Data.Vector.NonEmpty.Unboxed.Mutable: data NonEmptyMUVector s a
+ Data.Vector.NonEmpty.Unboxed.Mutable: drop :: Unbox a => Int -> NonEmptyMUVector s a -> MVector s a
+ Data.Vector.NonEmpty.Unboxed.Mutable: fromMVector :: Unbox a => MVector s a -> Maybe (NonEmptyMUVector s a)
+ Data.Vector.NonEmpty.Unboxed.Mutable: grow :: (PrimMonad m, Unbox a) => NonEmptyMUVector (PrimState m) a -> Int -> m (NonEmptyMUVector (PrimState m) a)
+ Data.Vector.NonEmpty.Unboxed.Mutable: init :: Unbox a => NonEmptyMUVector s a -> MVector s a
+ Data.Vector.NonEmpty.Unboxed.Mutable: length :: Unbox a => NonEmptyMUVector s a -> Int
+ Data.Vector.NonEmpty.Unboxed.Mutable: modify :: (PrimMonad m, Unbox a) => NonEmptyMUVector (PrimState m) a -> (a -> a) -> Int -> m ()
+ Data.Vector.NonEmpty.Unboxed.Mutable: move :: (PrimMonad m, Unbox a) => NonEmptyMUVector (PrimState m) a -> NonEmptyMUVector (PrimState m) a -> m ()
+ Data.Vector.NonEmpty.Unboxed.Mutable: new :: (PrimMonad m, Unbox a) => Int -> m (Maybe (NonEmptyMUVector (PrimState m) a))
+ Data.Vector.NonEmpty.Unboxed.Mutable: new1 :: (PrimMonad m, Unbox a) => Int -> m (NonEmptyMUVector (PrimState m) a)
+ Data.Vector.NonEmpty.Unboxed.Mutable: nextPermutation :: (PrimMonad m, Ord e, Unbox e) => NonEmptyMUVector (PrimState m) e -> m Bool
+ Data.Vector.NonEmpty.Unboxed.Mutable: overlaps :: Unbox a => NonEmptyMUVector s a -> NonEmptyMUVector s a -> Bool
+ Data.Vector.NonEmpty.Unboxed.Mutable: read :: (PrimMonad m, Unbox a) => NonEmptyMUVector (PrimState m) a -> Int -> m a
+ Data.Vector.NonEmpty.Unboxed.Mutable: replicate :: (PrimMonad m, Unbox a) => Int -> a -> m (Maybe (NonEmptyMUVector (PrimState m) a))
+ Data.Vector.NonEmpty.Unboxed.Mutable: replicate1 :: (PrimMonad m, Unbox a) => Int -> a -> m (NonEmptyMUVector (PrimState m) a)
+ Data.Vector.NonEmpty.Unboxed.Mutable: replicate1M :: (PrimMonad m, Unbox a) => Int -> m a -> m (Maybe (NonEmptyMUVector (PrimState m) a))
+ Data.Vector.NonEmpty.Unboxed.Mutable: replicateM :: (PrimMonad m, Unbox a) => Int -> m a -> m (Maybe (NonEmptyMUVector (PrimState m) a))
+ Data.Vector.NonEmpty.Unboxed.Mutable: set :: (PrimMonad m, Unbox a) => NonEmptyMUVector (PrimState m) a -> a -> m ()
+ Data.Vector.NonEmpty.Unboxed.Mutable: slice :: Unbox a => Int -> Int -> NonEmptyMUVector s a -> MVector s a
+ Data.Vector.NonEmpty.Unboxed.Mutable: splitAt :: Unbox a => Int -> NonEmptyMUVector s a -> (MVector s a, MVector s a)
+ Data.Vector.NonEmpty.Unboxed.Mutable: swap :: (PrimMonad m, Unbox a) => NonEmptyMUVector (PrimState m) a -> Int -> Int -> m ()
+ Data.Vector.NonEmpty.Unboxed.Mutable: tail :: Unbox a => NonEmptyMUVector s a -> MVector s a
+ Data.Vector.NonEmpty.Unboxed.Mutable: take :: Unbox a => Int -> NonEmptyMUVector s a -> MVector s a
+ Data.Vector.NonEmpty.Unboxed.Mutable: toMVector :: Unbox a => NonEmptyMUVector s a -> MVector s a
+ Data.Vector.NonEmpty.Unboxed.Mutable: type NonEmptyIOUVector = NonEmptyMUVector RealWorld
+ Data.Vector.NonEmpty.Unboxed.Mutable: type NonEmptySTUVector s = NonEmptyMUVector s
+ Data.Vector.NonEmpty.Unboxed.Mutable: unsafeCopy :: (PrimMonad m, Unbox a) => NonEmptyMUVector (PrimState m) a -> NonEmptyMUVector (PrimState m) a -> m ()
+ Data.Vector.NonEmpty.Unboxed.Mutable: unsafeDrop :: Unbox a => Int -> NonEmptyMUVector s a -> MVector s a
+ Data.Vector.NonEmpty.Unboxed.Mutable: unsafeFromMVector :: Unbox a => MVector s a -> NonEmptyMUVector s a
+ Data.Vector.NonEmpty.Unboxed.Mutable: unsafeGrow :: (PrimMonad m, Unbox a) => NonEmptyMUVector (PrimState m) a -> Int -> m (NonEmptyMUVector (PrimState m) a)
+ Data.Vector.NonEmpty.Unboxed.Mutable: unsafeModify :: (PrimMonad m, Unbox a) => NonEmptyMUVector (PrimState m) a -> (a -> a) -> Int -> m ()
+ Data.Vector.NonEmpty.Unboxed.Mutable: unsafeMove :: (PrimMonad m, Unbox a) => NonEmptyMUVector (PrimState m) a -> NonEmptyMUVector (PrimState m) a -> m ()
+ Data.Vector.NonEmpty.Unboxed.Mutable: unsafeNew :: (PrimMonad m, Unbox a) => Int -> m (Maybe (NonEmptyMUVector (PrimState m) a))
+ Data.Vector.NonEmpty.Unboxed.Mutable: unsafeRead :: (PrimMonad m, Unbox a) => NonEmptyMUVector (PrimState m) a -> Int -> m a
+ Data.Vector.NonEmpty.Unboxed.Mutable: unsafeSlice :: Unbox a => Int -> Int -> NonEmptyMUVector s a -> MVector s a
+ Data.Vector.NonEmpty.Unboxed.Mutable: unsafeSwap :: (PrimMonad m, Unbox a) => NonEmptyMUVector (PrimState m) a -> Int -> Int -> m ()
+ Data.Vector.NonEmpty.Unboxed.Mutable: unsafeTake :: Unbox a => Int -> NonEmptyMUVector s a -> MVector s a
+ Data.Vector.NonEmpty.Unboxed.Mutable: unsafeWrite :: (PrimMonad m, Unbox a) => NonEmptyMUVector (PrimState m) a -> Int -> a -> m ()
+ Data.Vector.NonEmpty.Unboxed.Mutable: write :: (PrimMonad m, Unbox a) => NonEmptyMUVector (PrimState m) a -> Int -> a -> m ()

Files

CHANGELOG.md view
@@ -1,5 +1,15 @@ # Revision history for nonempty-vector +## 1.0++* Add immutable and mutable unboxed non-empty vectors in+  `Data.Vector.NonEmpty.Unboxed` and `Data.Vector.NonEmpty.Unboxed.Mutable`.+  Constructors are available through `Data.Vector.NonEmpty.Unboxed.Internal`.+* Add property tests for the unboxed API+* Delegate boxed `Foldable` methods to the underlying vector and specialize+  `Foldable1` operations, including strict folding and non-empty conversion.++Thanks to Koz Ross (@kozross) for the unboxed API! ## 0.3  * Add `group` and `groupBy`, returning non-empty lists of non-empty vector slices.
README.md view
@@ -2,6 +2,18 @@  ![Build Status](https://github.com/emilypi/nonempty-vector/actions/workflows/haskell-ci.yml/badge.svg) [![Hackage](https://img.shields.io/hackage/v/nonempty-vector.svg)](https://hackage.haskell.org/package/nonempty-vector) -This package presents thin wrappers around mutable and immutable [Data.Vector](https://hackage.haskell.org/package/vector) types that enforce non-emptiness. The entire Vector API is supported for both sets of boxed vectors, with future plans to support unboxed, primitive, storable, and generic vectors.+This package provides thin wrappers around mutable and immutable+[vector](https://hackage.haskell.org/package/vector) types that enforce+non-emptiness, with APIs for both boxed and unboxed storage. -There are no external dependencies that are not already in `base`.+| Storage | Immutable | Mutable |+| --- | --- | --- |+| Boxed | `Data.Vector.NonEmpty` | `Data.Vector.NonEmpty.Mutable` |+| Unboxed | `Data.Vector.NonEmpty.Unboxed` | `Data.Vector.NonEmpty.Unboxed.Mutable` |++The unboxed API requires `Unbox` instances for element types. Operations that can+produce an empty result return an ordinary vector or `Maybe`, as appropriate.+The `Internal` modules expose constructors for users who manage the non-emptiness+invariant themselves.++Library dependencies are `base`, `deepseq`, `primitive`, and `vector`.
nonempty-vector.cabal view
@@ -1,6 +1,6 @@ cabal-version:   3.0 name:            nonempty-vector-version:         0.3+version:         1.0 synopsis:        Non-empty vectors description:     Performant, non-empty mutable and immutable vectors homepage:        https://github.com/emilypi/nonempty-vector@@ -31,8 +31,11 @@ library   exposed-modules:     Data.Vector.NonEmpty+    Data.Vector.NonEmpty.Unboxed     Data.Vector.NonEmpty.Internal     Data.Vector.NonEmpty.Mutable+    Data.Vector.NonEmpty.Unboxed.Mutable+    Data.Vector.NonEmpty.Unboxed.Internal    build-depends:       base       >=4.16 && <4.23@@ -50,16 +53,27 @@   main-is:           Main.hs   other-modules:     Test.Data.Vector.NonEmpty.Accessors+    Test.Data.Vector.NonEmpty.AccessorsU     Test.Data.Vector.NonEmpty.Construction+    Test.Data.Vector.NonEmpty.ConstructionU     Test.Data.Vector.NonEmpty.Conversion+    Test.Data.Vector.NonEmpty.ConversionU     Test.Data.Vector.NonEmpty.Elementwise+    Test.Data.Vector.NonEmpty.ElementwiseU     Test.Data.Vector.NonEmpty.Folds+    Test.Data.Vector.NonEmpty.FoldsU     Test.Data.Vector.NonEmpty.Grouping+    Test.Data.Vector.NonEmpty.GroupingU     Test.Data.Vector.NonEmpty.Instances+    Test.Data.Vector.NonEmpty.InstancesU     Test.Data.Vector.NonEmpty.Modification+    Test.Data.Vector.NonEmpty.ModificationU     Test.Data.Vector.NonEmpty.Mutable+    Test.Data.Vector.NonEmpty.MutableU     Test.Data.Vector.NonEmpty.Predicates+    Test.Data.Vector.NonEmpty.PredicatesU     Test.Data.Vector.NonEmpty.Scans+    Test.Data.Vector.NonEmpty.ScansU     Test.Data.Vector.NonEmpty.Util    build-depends:
src/Data/Vector/NonEmpty/Internal.hs view
@@ -1,5 +1,6 @@ {-# LANGUAGE CPP #-} {-# LANGUAGE DeriveDataTypeable #-}+{-# LANGUAGE DeriveTraversable #-} {-# LANGUAGE GeneralizedNewtypeDeriving #-} {-# LANGUAGE LambdaCase #-} -- |@@ -37,6 +38,7 @@  import Data.Data (Data) import qualified Data.Foldable as Foldable+import Data.List.NonEmpty (NonEmpty((:|))) #if MIN_VERSION_base(4,18,0) import Data.Foldable1 (Foldable1) import qualified Data.Foldable1 as Foldable1@@ -76,6 +78,7 @@       , Functor, Applicative, Monad       , MonadZip       , Semigroup+      , Traversable       )  instance Show a => Show (NonEmptyVector a) where@@ -93,28 +96,46 @@  instance Foldable NonEmptyVector where     foldMap f = Foldable.foldMap f . _neVec+    foldr f x = Foldable.foldr f x . _neVec+    foldl f x = Foldable.foldl f x . _neVec+    foldr1 f = Foldable.foldr1 f . _neVec+    foldl1 f = Foldable.foldl1 f . _neVec+    foldr' f x = Foldable.foldr' f x . _neVec+    foldl' f x = Foldable.foldl' f x . _neVec+    toList = Foldable.toList . _neVec+    length = Foldable.length . _neVec+    null = const False+    elem x = Foldable.elem x . _neVec+    maximum = Foldable.maximum . _neVec+    minimum = Foldable.minimum . _neVec+    sum = Foldable.sum . _neVec+    product = Foldable.product . _neVec  #if MIN_VERSION_base(4,18,0) instance Foldable1 NonEmptyVector where-    foldMap1 f (NonEmptyVector v) =-        let-          h = V.unsafeHead v -- guaranteed head (nonemptiness)-          t = V.unsafeTail v -- guaranteed possibly empty tail-        in go (f h) t -- therefore this is a sound call-      where-        go x xs-          -- when xs is empty, vector is exhausted, return x-          | V.null xs = x-          | otherwise =-          -- if xs is not empty, then there are at least 2 elements in the list. Hence, h and t are sound calls to make.-            let-              h = V.unsafeHead xs-              t = V.unsafeTail xs-            in x <> go (f h) t+    foldMap1 f (NonEmptyVector v) = +        let +          projected = fmap f v+          h = V.unsafeHead projected -- guaranteed head (nonemptiness)+          t = V.unsafeTail projected -- guaranteed possibly empty tail+        -- Defer to `Vector`'s underlying folding mechanism.+        -- Direction doesn't matter since we're associative anyway.+        in V.foldl (<>) h t+    foldMap1' f (NonEmptyVector v) = +        let +          projected = fmap f v+          h = V.unsafeHead projected+          t = V.unsafeTail projected+        in V.foldl' (<>) h t+    toNonEmpty (NonEmptyVector v) = +        let h = V.unsafeHead v+            t = V.unsafeTail v+        in h :| V.toList t+    maximum = V.maximum . _neVec+    minimum = V.minimum . _neVec+    head = V.unsafeHead . _neVec+    last (NonEmptyVector v) = V.unsafeIndex v (V.length v - 1) #endif--instance Traversable NonEmptyVector where-    traverse f = fmap NonEmptyVector . traverse f . _neVec  -- ---------------------------------------------------------------------- -- -- Non-empty mutable vectors
+ src/Data/Vector/NonEmpty/Unboxed.hs view
@@ -0,0 +1,2768 @@+{-# LANGUAGE NoImplicitPrelude #-}+{-# LANGUAGE KindSignatures #-}+{-# LANGUAGE RankNTypes #-}+{-# LANGUAGE CPP #-}+-- |+-- Module       : Data.Vector.NonEmpty.Unboxed+-- Copyright 	: (c) 2019-2026 Emily Pillmore, Koz Ross+-- License	: BSD-style+-- Maintainer   : Emily Pillmore <emilypi@cohomolo.gy>+-- Stability    : Experimental+-- Portability  : DataTypeable, CPP+--+-- A library for non-empty unboxed vectors (that is, polymorphic arrays capable of+-- holding any value whose type has an 'V.Unbox' isntance). Non-empty vectors come in +-- two flavors:+--+--  * mutable+--+--  * immutable+--+-- This library attempts to provide support for all standard 'Vector' operations+-- in the API, with some slight variation in types and implementation. For example,+-- since 'head' and 'foldr' are always guaranteed to be over a non-empty 'Vector',+-- it is safe to make use of the 'unsafe-*' 'Vector' operations and semigroupal+-- folds available in the API in lieu of the standard implementations.+--+-- In contrast, some operations such as 'filter' may "break out" of a t'NonEmptyUVector'+-- due to the fact that there are no guarantees that may be made on the types of+-- 'Bool'-valued functions passed in, hence one could write the following:+--+-- @+-- filter (const false) v+-- @+--+-- which always produces an empty vector. Thus, some operations must return either+-- a 'Maybe' containing a t'NonEmptyUVector' or a 'Vector' whenever appropriate. Generally+-- The former is used in initialization and generation operations, and the latter+-- is used in iterative operations where the intent is not to create an instance+-- of t'NonEmptyUVector'.+--+-- Credit to Roman Leshchinskiy for the original Vector library  upon which this is based.+--+module Data.Vector.NonEmpty.Unboxed+( -- * Boxed non-empty vectors+  NonEmptyUVector++  -- * Accessors++  -- ** Length information+, length++  -- ** Indexing+, head, last, (!), (!?)+, unsafeIndex++  -- ** Monadic Indexing+, headM, lastM, indexM, unsafeIndexM++  -- ** Extracting subvectors (slicing)+, tail, slice, init, take, drop+, uncons, unsnoc, splitAt+, unsafeSlice, unsafeTake, unsafeDrop++  -- * Construction++  -- ** Initialization+, singleton+, replicate, replicate1+, generate, generate1+, iterateN, iterateN1++  -- ** Monad Initialization+, replicateM, replicate1M+, generateM, generate1M+, iterateNM, iterateN1M+, create, unsafeCreate+, createT, unsafeCreateT++  -- ** Unfolding+, unfoldr, unfoldr1+, unfoldrN, unfoldr1N+, unfoldrM, unfoldr1M+, unfoldrNM, unfoldr1NM+, constructN, constructrN++  -- ** Enumeration+, enumFromN, enumFromN1+, enumFromStepN, enumFromStepN1+, enumFromTo, enumFromThenTo++  -- ** Concatenation+, cons, consV, snoc, snocV, (++), concat, concat1++  -- ** Restricting memory usage+, force++  -- * Conversion++  -- ** To/from non-empty lists+, toNonEmpty, fromNonEmpty+, fromNonEmptyN, fromNonEmptyN1+, unsafeFromList++  -- ** To/from vector+, toVector, fromVector, unsafeFromVector++  -- ** To/from list+, toList, fromList, fromListN++  -- * Modifying non-empty vectors++  -- ** Bulk Updates+, (//), update, update_+, unsafeUpd, unsafeUpdate, unsafeUpdate_++  -- * Accumulations+, accum, accumulate, accumulate_+, unsafeAccum, unsafeAccumulate, unsafeAccumulate_++  -- * Permutations+, reverse, backpermute, unsafeBackpermute++  -- * Safe destructive updates+, modify++  -- * Elementwise operations++  -- ** Indexing+, indexed++  -- ** Mapping+, map, imap, concatMap++  -- ** Monadic mapping+, mapM, imapM, mapM_, imapM_+, forM, forM_++  -- ** Zipping+, zipWith, zipWith3, zipWith4, zipWith5, zipWith6+, izipWith, izipWith3, izipWith4, izipWith5, izipWith6+, zip, zip3, zip4, zip5, zip6++  -- ** Monadic Zipping+, zipWithM, zipWithM_, izipWithM, izipWithM_++  -- ** Unzipping+, unzip, unzip3, unzip4, unzip5, unzip6++  -- * Working with predicates++  -- ** Filtering+, uniq, mapMaybe, imapMaybe+, filter, ifilter, filterM, ifilterM+, takeWhile, dropWhile++  -- * Partitioning+, partition, partitionWith, unstablePartition, span, break++  -- * Searching+, elem, notElem, find, findIndex, findIndices, elemIndex+, elemIndices++  -- * Folding+, foldl, foldl1, foldl', foldl1'+, foldr, foldr1, foldr', foldr1'+, ifoldl, ifoldl', ifoldr, ifoldr'++  -- * Specialized folds+, all, any, and, or, sum, product+, maximum, maximumBy, minimum, minimumBy+, maxIndex, maxIndexBy, minIndex, minIndexBy++  -- * Monadic Folds+, foldM, foldM', fold1M, fold1M', foldM_, foldM'_, fold1M_+, fold1M'_, ifoldM, ifoldM', ifoldM_, ifoldM'_++  -- * Prefix sums (scans)+, prescanl, prescanl', postscanl, postscanl'+, scanl, scanl', scanl1, scanl1', iscanl, iscanl'+, prescanr, prescanr', postscanr, postscanr'+, scanr, scanr', scanr1, scanr1', iscanr, iscanr'++  -- ** Transformations+, intersperse++  -- ** Grouping+, group+, groupBy++) where+++import Prelude ( Bool, Eq, Ord, Num, Enum+               , (.), Ordering, max, uncurry, snd+               , pure, (+), otherwise, (>=), (-), (*), ($), (<=)+               , (==), not)++import Control.Monad (Monad)+import Control.Monad.ST++import qualified Data.Foldable as Foldable+import Data.Either (Either(..))+#if MIN_VERSION_base(4,19,0)+-- This import will only execute if compiling with base >= 4.19.0.0 (GHC 9.8+)+import Data.Functor hiding (unzip)+#else+import Data.Functor+#endif+import Data.Int+import Data.List.NonEmpty (NonEmpty(..), (<|))+import qualified Data.List.NonEmpty as NonEmpty+import Data.Kind (Type)+import Data.Maybe (Maybe(..))+import Data.Semigroup (Semigroup(..), (<>))+import Data.Traversable (Traversable)+import Data.Vector.Unboxed (Vector)+import qualified Data.Vector.Unboxed as V+import qualified Data.Vector.Generic as G+import Data.Vector.Unboxed.Mutable (MVector, unsafeWrite)+import Data.Vector.NonEmpty.Unboxed.Internal+++-- $setup+-- >>> import Prelude (Int, String, ($), (.), (+), (<), const, return, Maybe(..), Either(..))+-- >>> import Data.Bool+-- >>> import Data.Eq+-- >>> import qualified Prelude as P+-- >>> import qualified Data.Vector.Unboxed as V+-- >>> import Data.List.NonEmpty (NonEmpty(..))+-- >>> import qualified Data.List.NonEmpty as NEL+-- >>> :set -XTypeApplications+-- >>> :set -XScopedTypeVariables++-- ---------------------------------------------------------------------- --+-- Accessors + Indexing++-- | /O(1)/ Length.+--+-- >>> length $ unsafeFromList [1..10]+-- 10+--+length :: V.Unbox a => NonEmptyUVector a -> Int+length = V.length . _neUvec+{-# INLINE length #-}++-- | /O(1)/ First element. Since head is guaranteed, bounds checks+-- are bypassed by deferring to 'Data.Vector.unsafeHead'.+--+--+-- >>> head $ unsafeFromList [1..10]+-- 1+--+head :: V.Unbox a => NonEmptyUVector a -> a+head = V.unsafeHead . _neUvec+{-# INLINE head #-}++-- | /O(1)/ Last element. Since a last element is guaranteed, bounds checks+-- are bypassed by deferring to 'Data.Vector.unsafeLast'.+--+--+-- >>> last $ unsafeFromList [1..10]+-- 10+--+last :: V.Unbox a => NonEmptyUVector a -> a+last = V.unsafeLast . _neUvec+{-# INLINE last #-}++-- | /O(1)/ Indexing.+--+--+-- >>> (unsafeFromList [1..10]) ! 0+-- 1+--+(!) :: V.Unbox a => NonEmptyUVector a -> Int -> a+(!) (NonEmptyUVector as) n = as V.! n+{-# INLINE (!) #-}++-- | /O(1)/ Safe indexing.+--+--+-- >>> (unsafeFromList [1..10]) !? 0+-- Just 1+--+-- >>> (unsafeFromList [1..10]) !? 11+-- Nothing+--+(!?) :: V.Unbox a => NonEmptyUVector a -> Int -> Maybe a+(NonEmptyUVector as) !? n = as V.!? n+{-# INLINE (!?) #-}++-- | /O(1)/ Unsafe indexing without bounds checking+--+unsafeIndex :: V.Unbox a => NonEmptyUVector a -> Int -> a+unsafeIndex (NonEmptyUVector as) n = V.unsafeIndex as n+{-# INLINE unsafeIndex #-}++-- ---------------------------------------------------------------------- --+-- Monadic Indexing++-- | /O(1)/ Indexing in a monad.+--+-- The monad allows operations to be strict in the non-empty vector when+-- necessary.+--+-- See 'Data.Vector.indexM' for more details+--+--+-- >>> indexM @[] (unsafeFromList [1..10]) 3+-- [4]+--+indexM :: (Monad m, V.Unbox a) => NonEmptyUVector a -> Int -> m a+indexM (NonEmptyUVector v) n = V.indexM v n+{-# INLINE indexM #-}++-- | /O(1)/ First element of a non-empty vector in a monad.+--+-- See 'Data.Vector.indexM' for an explanation of why this is useful.+--+-- Note that this function defers to 'Data.Vector.unsafeHeadM' since head is+-- guaranteed to be safe by construction.+--+--+-- >>> headM @[] (unsafeFromList [1..10])+-- [1]+--+headM :: (Monad m, V.Unbox a) => NonEmptyUVector a -> m a+headM (NonEmptyUVector v) = V.unsafeHeadM v+{-# INLINE headM #-}++-- | /O(1)/ Last element of a non-empty vector in a monad. See 'Data.Vector.indexM'+-- for an explanation of why this is useful.+--+-- Note that this function defers to 'Data.Vector.unsafeLastM' since a last element is+-- guaranteed.+--+--+-- >>> lastM @[] (unsafeFromList [1..10])+-- [10]+--+lastM :: (Monad m, V.Unbox a) => NonEmptyUVector a -> m a+lastM (NonEmptyUVector v) = V.unsafeLastM v+{-# INLINE lastM #-}++-- | O(1) Indexing in a monad without bounds checks. See 'indexM' for an+-- explanation of why this is useful.+--+unsafeIndexM :: (Monad m, V.Unbox a) => NonEmptyUVector a -> Int -> m a+unsafeIndexM (NonEmptyUVector v) n = V.unsafeIndexM v n+{-# INLINE unsafeIndexM #-}++-- ---------------------------------------------------------------------- --+-- Extracting subvectors (slicing)++-- | /O(1)/ Yield all but the first element without copying. Since the+-- vector returned may be empty (i.e. input was a singleton), this function+-- returns a normal 'Vector'+--+--+-- >>> tail (unsafeFromList [1..10])+-- [2,3,4,5,6,7,8,9,10]+--+tail :: V.Unbox a => NonEmptyUVector a -> Vector a+tail = V.unsafeTail . _neUvec+{-# INLINE tail #-}++-- | /O(1)/ Yield a slice of a non-empty vector without copying at+-- the @0@th and @1@st indices.+--+--+-- >>> uncons (unsafeFromList [1..10])+-- (1,[2,3,4,5,6,7,8,9,10])+--+uncons :: V.Unbox a => NonEmptyUVector a -> (a, Vector a)+uncons v = (head v, tail v)+{-# INLINE uncons #-}++-- | /O(1)/ Yield a slice of a non-empty vector without copying at+-- the @n-1@th and @nth@ indices+--+--+-- >>> unsnoc (unsafeFromList [1..10])+-- ([1,2,3,4,5,6,7,8,9],10)+--+unsnoc :: V.Unbox a => NonEmptyUVector a -> (Vector a, a)+unsnoc v = (init v, last v)+{-# INLINE unsnoc #-}++-- | /O(1)/ Yield a slice of the non-empty vector without copying it.+-- The vector must contain at least i+n elements. Because this is not+-- guaranteed, this function returns a 'Vector' which could be empty+--+--+-- >>> slice 0 3 (unsafeFromList [1..10])+-- [1,2,3]+--+slice :: V.Unbox a => Int -> Int -> NonEmptyUVector a -> Vector a+slice i n = V.slice i n . _neUvec+{-# INLINE slice #-}++-- | /O(1)/ Yield all but the last element without copying. Since the+-- vector returned may be empty (i.e. input was a singleton), this function+-- returns a normal 'Vector'+--+--+-- >>> init (unsafeFromList [1..3])+-- [1,2]+--+init :: V.Unbox a => NonEmptyUVector a -> Vector a+init = V.unsafeInit . _neUvec+{-# INLINE init #-}++-- | /O(1)/ Yield at the first n elements without copying. The non-empty vector may+-- contain less than n elements in which case it is returned as a vector unchanged.+--+--+-- >>> take 2 (unsafeFromList [1..3])+-- [1,2]+--+take :: V.Unbox a => Int -> NonEmptyUVector a -> Vector a+take n = V.take n . _neUvec+{-# INLINE take #-}++-- | /O(1)/ Yield all but the first n elements without copying. The non-empty vector+-- may contain less than n elements in which case an empty vector is returned.+--+--+-- >>> drop 2 (unsafeFromList [1..3])+-- [3]+--+drop :: V.Unbox a => Int -> NonEmptyUVector a -> Vector a+drop n = V.drop n . _neUvec+{-# INLINE drop #-}++-- | /O(1)/ Yield the first n elements paired with the remainder without copying.+--+-- This function returns a pair of vectors, as one may slice a (0, n+1).+--+--+-- >>> splitAt 2 (unsafeFromList [1..3])+-- ([1,2],[3])+--+splitAt :: V.Unbox a => Int -> NonEmptyUVector a -> (Vector a, Vector a)+splitAt n = V.splitAt n . _neUvec+{-# INLINE splitAt #-}++-- | /O(1)/ Yield a slice of the vector without copying. The vector must contain at+-- least i+n elements but this is not checked.+--+unsafeSlice :: V.Unbox a => Int -> Int -> NonEmptyUVector a -> Vector a+unsafeSlice i n = V.unsafeSlice i n . _neUvec+{-# INLINE unsafeSlice #-}++-- | /O(1)/ Yield the first n elements without copying. The vector must contain at+-- least n elements but this is not checked.+--+unsafeTake :: V.Unbox a => Int -> NonEmptyUVector a -> Vector a+unsafeTake n = V.unsafeTake n . _neUvec+{-# INLINE unsafeTake #-}++-- | /O(1)/ Yield all but the first n elements without copying. The vector must contain+-- at least n elements but this is not checked.+--+unsafeDrop :: V.Unbox a => Int -> NonEmptyUVector a -> Vector a+unsafeDrop n = V.unsafeDrop n . _neUvec+{-# INLINE unsafeDrop #-}++-- ---------------------------------------------------------------------- --+-- Construction++-- | /O(1)/ Non-empty vector with exactly one element+--+--+-- >>> singleton "a"+-- ["a"]+--+singleton :: V.Unbox a => a -> NonEmptyUVector a+singleton = NonEmptyUVector . V.singleton+{-# INLINE singleton #-}++-- | /O(n)/ Non-empty vector of the given length with the same value in+-- each position.+--+-- When given a index n <= 0, then 'Nothing' is returned, otherwise 'Just'.+--+--+-- >>> replicate 3 "a"+-- Just ["a","a","a"]+--+-- >>> replicate 0 "a"+-- Nothing+--+replicate :: V.Unbox a => Int -> a -> Maybe (NonEmptyUVector a)+replicate n a = fromVector (V.replicate n a)+{-# INLINE replicate #-}++-- | /O(n)/ Non-empty vector of the given length with the same value in+-- each position.+--+-- This variant takes @max n 1@ for the supplied length parameter.+--+--+-- >>> replicate1 3 "a"+-- ["a","a","a"]+--+-- >>> replicate1 0 "a"+-- ["a"]+--+-- >>> replicate1 (-1) "a"+-- ["a"]+--+replicate1 :: V.Unbox a => Int -> a -> NonEmptyUVector a+replicate1 n a = unsafeFromVector (V.replicate (max n 1) a)+{-# INLINE replicate1 #-}++-- | /O(n)/ Construct a vector of the given length by applying the function to+-- each index.+--+-- When given a index n <= 0, then 'Nothing' is returned, otherwise 'Just'.+--+--+-- >>> let f 0 = "a"; f _ = "k"; f :: Int -> String+--+-- >>> generate 1 f+-- Just ["a"]+--+-- >>> generate 0 f+-- Nothing+--+-- >>> generate 2 f+-- Just ["a","k"]+--+generate :: V.Unbox a => Int -> (Int -> a) -> Maybe (NonEmptyUVector a)+generate n f = fromVector (V.generate n f)+{-# INLINE generate #-}++-- | /O(n)/ Construct a vector of the given length by applying the function to+-- each index.+--+-- This variant takes @max n 1@ for the supplied length parameter.+--+--+-- >>> let f 0 = "a"; f _ = "k"; f :: Int -> String+--+-- >>> generate1 2 f+-- ["a","k"]+--+-- >>> generate1 0 f+-- ["a"]+--+-- >>> generate1 (-1) f+-- ["a"]+--+generate1 :: V.Unbox a => Int -> (Int -> a) -> NonEmptyUVector a+generate1 n f = unsafeFromVector (V.generate (max n 1) f)+{-# INLINE generate1 #-}++-- | /O(n)/ Apply function n times to value. Zeroth element is original value.+--+-- When given a index n <= 0, then 'Nothing' is returned, otherwise 'Just'.+--+-- >>> iterateN 3 (+1) 0+-- Just [0,1,2]+--+-- >>> iterateN 0 (+1) 0+-- Nothing+--+-- >>> iterateN (-1) (+1) 0+-- Nothing+--+iterateN :: V.Unbox a => Int -> (a -> a) -> a -> Maybe (NonEmptyUVector a)+iterateN n f a = fromVector (V.iterateN n f a)+{-# INLINE iterateN #-}++-- | /O(n)/ Apply function n times to value. Zeroth element is original value.+--+-- This variant takes @max n 1@ for the supplied length parameter.+--+--+-- >>> iterateN1 3 (+1) 0+-- [0,1,2]+--+-- >>> iterateN1 0 (+1) 0+-- [0]+--+-- >>> iterateN1 (-1) (+1) 0+-- [0]+--+iterateN1 :: V.Unbox a => Int -> (a -> a) -> a -> NonEmptyUVector a+iterateN1 n f a = unsafeFromVector (V.iterateN (max n 1) f a)+{-# INLINE iterateN1 #-}++-- ---------------------------------------------------------------------- --+-- Monadic Initialization++-- | /O(n)/ Execute the monadic action the given number of times and store+-- the results in a vector.+--+-- When given a index n <= 0, then 'Nothing' is returned, otherwise 'Just'.+--+--+-- >>> replicateM @Maybe 3 (Just "a")+-- Just (Just ["a","a","a"])+--+-- >>> replicateM @Maybe 3 Nothing+-- Nothing+--+-- >>> replicateM @Maybe 0 (Just "a")+-- Just Nothing+--+-- >>> replicateM @Maybe (-1) (Just "a")+-- Just Nothing+--+replicateM :: (Monad m, V.Unbox a) => Int -> m a -> m (Maybe (NonEmptyUVector a))+replicateM n a = fmap fromVector (V.replicateM n a)+{-# INLINE replicateM #-}++-- | /O(n)/ Execute the monadic action the given number of times and store+-- the results in a vector.+--+-- This variant takes @max n 1@ for the supplied length parameter.+--+--+-- >>> replicate1M @Maybe 3 (Just "a")+-- Just ["a","a","a"]+--+-- >>> replicate1M @Maybe 3 Nothing+-- Nothing+--+-- >>> replicate1M @Maybe 0 (Just "a")+-- Just ["a"]+--+-- >>> replicate1M @Maybe (-1) (Just "a")+-- Just ["a"]+--+replicate1M :: (Monad m, V.Unbox a) => Int -> m a -> m (NonEmptyUVector a)+replicate1M n a = fmap unsafeFromVector (V.replicateM (max n 1) a)+{-# INLINE replicate1M #-}++-- | /O(n)/ Construct a vector of the given length by applying the monadic+-- action to each index+--+-- When given a index n <= 0, then 'Nothing' is returned, otherwise 'Just'.+--+-- >>> generateM 3 (\i -> if i P.< 1 then ["a"] else ["b"])+-- [Just ["a","b","b"]]+--+-- >>> generateM @[] @Int 3 (const [])+-- []+--+-- >>> generateM @[] @Int 0 (const [1])+-- [Nothing]+--+-- >>> generateM @Maybe @Int (-1) (const Nothing)+-- Just Nothing+--+generateM :: (Monad m, V.Unbox a) => Int -> (Int -> m a) -> m (Maybe (NonEmptyUVector a))+generateM n f = fmap fromVector (V.generateM n f)+{-# INLINE generateM #-}++-- | /O(n)/ Construct a vector of the given length by applying the monadic+-- action to each index+--+-- This variant takes @max n 1@ for the supplied length parameter.+--+-- >>> generate1M 3 (\i -> if i P.< 1 then Just "a" else Just "b")+-- Just ["a","b","b"]+--+-- >>> generate1M 3 (const [])+-- []+--+-- >>> generate1M 0 (const $ Just 1)+-- Just [1]+--+-- >>> generate1M (-1) (const Nothing)+-- Nothing+--+generate1M :: (Monad m, V.Unbox a) => Int -> (Int -> m a) -> m (NonEmptyUVector a)+generate1M n f = fmap unsafeFromVector (V.generateM (max n 1) f)+{-# INLINE generate1M #-}++-- | /O(n)/ Apply monadic function n times to value. Zeroth element is+-- original value.+--+-- When given a index n <= 0, then 'Nothing' is returned, otherwise 'Just'.+--+--+-- >>> iterateNM @Maybe 3 return "a"+-- Just (Just ["a","a","a"])+--+-- >>> iterateNM @Maybe 3 (const Nothing) "a"+-- Nothing+--+-- >>> iterateNM @Maybe 0 return "a"+-- Just Nothing+--+iterateNM :: (Monad m, V.Unbox a) => Int -> (a -> m a) -> a -> m (Maybe (NonEmptyUVector a))+iterateNM n f a = fmap fromVector (V.iterateNM n f a)+{-# INLINE iterateNM #-}++-- | /O(n)/ Apply monadic function n times to value. Zeroth element is+-- original value.+--+-- This variant takes @max n 1@ for the supplied length parameter.+--+--+-- >>> iterateN1M @Maybe 3 return "a"+-- Just ["a","a","a"]+--+-- >>> iterateN1M @Maybe 3 (const Nothing) "a"+-- Nothing+--+-- >>> iterateN1M @Maybe 0 return "a"+-- Just ["a"]+--+-- >>> iterateN1M @Maybe (-1) return "a"+-- Just ["a"]+--+iterateN1M :: (Monad m, V.Unbox a) => Int -> (a -> m a) -> a -> m (NonEmptyUVector a)+iterateN1M n f a = fmap unsafeFromVector (V.iterateNM (max n 1) f a)+{-# INLINE iterateN1M #-}++-- | Execute the monadic action and freeze the resulting non-empty vector.+--+create :: V.Unbox a => (forall s. ST s (MVector s a)) -> Maybe (NonEmptyUVector a)+create p = fromVector (G.create p)+{-# INLINE create #-}++-- | Execute the monadic action and freeze the resulting non-empty vector,+-- bypassing emptiness checks.+--+-- The onus is on the caller to guarantee the created vector is non-empty.+--+unsafeCreate :: V.Unbox a => (forall s. ST s (MVector s a)) -> NonEmptyUVector a+unsafeCreate p = unsafeFromVector (G.create p)+{-# INLINE unsafeCreate #-}++-- | Execute the monadic action and freeze the resulting non-empty vector.+--+createT+    :: (Traversable t, V.Unbox a)+    => (forall s. ST s (t (MVector s a)))+    -> t (Maybe (NonEmptyUVector a))+createT p = fmap fromVector (G.createT p)+{-# INLINE createT #-}++-- | Execute the monadic action and freeze the resulting non-empty vector.+--+-- The onus is on the caller to guarantee the created vector is non-empty.+--+unsafeCreateT+    :: (Traversable t, V.Unbox a)+    => (forall s. ST s (t (MVector s a)))+    -> t (NonEmptyUVector a)+unsafeCreateT p = fmap unsafeFromVector (G.createT p)+{-# INLINE unsafeCreateT #-}++-- ---------------------------------------------------------------------- --+-- Unfolding++-- | /O(n)/ Construct a non-empty vector by repeatedly applying the+-- generator function to a seed. The generator function yields 'Just' the+-- next element and the new seed or 'Nothing' if there are no more+-- elements.+--+-- If an unfold does not create meaningful values, 'Nothing' is+-- returned. Otherwise, 'Just' containing a non-empty vector is returned.+--+--+-- >>> unfoldr (\b -> case b of "a" -> Just ("a", "b"); _ ->  Nothing) "a"+-- Just ["a"]+--+-- >>> unfoldr (const Nothing) "a"+-- Nothing+--+unfoldr :: V.Unbox a => (b -> Maybe (a, b)) -> b -> Maybe (NonEmptyUVector a)+unfoldr f b = fromVector (V.unfoldr f b)+{-# INLINE unfoldr #-}++-- | /O(n)/ Construct a non-empty vector by repeatedly applying the+-- generator function to a seed and a first element.+--+-- This variant of 'unfoldr' guarantees the resulting vector is non-+-- empty by supplying an initial element @a@.+--+--+-- >>> unfoldr1 (\b -> case b of "a" -> Just ("a", "b"); _ ->  Nothing) "first" "a"+-- ["first","a"]+--+-- >>> unfoldr1 (const Nothing) "first" "a"+-- ["first"]+--+unfoldr1 :: V.Unbox a => (b -> Maybe (a, b)) -> a -> b -> NonEmptyUVector a+unfoldr1 f a b = cons a (unsafeFromVector (V.unfoldr f b))+{-# INLINE unfoldr1 #-}++-- | /O(n)/ Construct a vector with at most n elements by repeatedly+-- applying the generator function to a seed. The generator function yields+-- 'Just' the next element and the new seed or 'Nothing' if there are no+-- more elements.+--+-- If an unfold does not create meaningful values, 'Nothing' is+-- returned. Otherwise, 'Just' containing a non-empty vector is returned.+--+--+-- >>> unfoldrN 3 (\b -> Just (b+1, b+1)) 0+-- Just [1,2,3]+--+-- >>> unfoldrN 3 (const Nothing) 0+-- Nothing+--+-- >>> unfoldrN 0 (\b -> Just (b+1, b+1)) 0+-- Nothing+--+unfoldrN :: V.Unbox a => Int -> (b -> Maybe (a, b)) -> b -> Maybe (NonEmptyUVector a)+unfoldrN n f b = fromVector (V.unfoldrN n f b)+{-# INLINE unfoldrN #-}++-- | /O(n)/ Construct a vector with at most n elements by repeatedly+-- applying the generator function to a seed. The generator function yields+-- 'Just' the next element and the new seed or 'Nothing' if there are no+-- more elements.+--+-- This variant of 'unfoldrN' guarantees the resulting vector is non-+-- empty by supplying an initial element @a@.+--+--+-- >>> unfoldr1N 3 (\b -> Just (b+1, b+1)) 0 0+-- [0,1,2,3]+--+-- >>> unfoldr1N 3 (const Nothing) 0 0+-- [0]+--+-- >>> unfoldr1N 0 (\b -> Just (b+1, b+1)) 0 0+-- [0]+--+unfoldr1N+    :: V.Unbox a+    => Int+    -> (b -> Maybe (a, b))+    -> a+    -> b+    -> NonEmptyUVector a+unfoldr1N n f a b = cons a (unsafeFromVector (V.unfoldrN n f b))+{-# INLINE unfoldr1N #-}++-- | /O(n)/ Construct a non-empty vector by repeatedly applying the monadic generator+-- function to a seed. The generator function yields Just the next element+-- and the new seed or Nothing if there are no more elements.+--+-- If an unfold does not create meaningful values, 'Nothing' is+-- returned. Otherwise, 'Just' containing a non-empty vector is returned.+--+unfoldrM+    :: (V.Unbox a, Monad m)+    => (b -> m (Maybe (a, b)))+    -> b+    -> m (Maybe (NonEmptyUVector a))+unfoldrM f b = fmap fromVector (V.unfoldrM f b)+{-# INLINE unfoldrM #-}++-- | /O(n)/ Construct a non-empty vector by repeatedly applying the monadic generator+-- function to a seed. The generator function yields Just the next element+-- and the new seed or Nothing if there are no more elements.+--+-- This variant of 'unfoldrM' guarantees the resulting vector is non-+-- empty by supplying an initial element @a@.+--+unfoldr1M+    :: (Monad m, V.Unbox a)+    => (b -> m (Maybe (a, b)))+    -> a+    -> b+    -> m (NonEmptyUVector a)+unfoldr1M f a b = fmap (cons a . unsafeFromVector) (V.unfoldrM f b)+{-# INLINE unfoldr1M #-}++-- | /O(n)/ Construct a non-empty vector by repeatedly applying the monadic generator+-- function to a seed. The generator function yields Just the next element and+-- the new seed or Nothing if there are no more elements.+--+-- If an unfold does not create meaningful values, 'Nothing' is+-- returned. Otherwise, 'Just' containing a non-empty vector is returned.+--+unfoldrNM+    :: (V.Unbox a, Monad m)+    => Int+    -> (b -> m (Maybe (a, b)))+    -> b+    -> m (Maybe (NonEmptyUVector a))+unfoldrNM n f b = fmap fromVector (V.unfoldrNM n f b)+{-# INLINE unfoldrNM #-}++-- | /O(n)/ Construct a non-empty vector by repeatedly applying the monadic generator+-- function to a seed. The generator function yields Just the next element and+-- the new seed or Nothing if there are no more elements.+--+-- This variant of 'unfoldrNM' guarantees the resulting vector is non-+-- empty by supplying an initial element @a@.+--+unfoldr1NM+    :: (V.Unbox a, Monad m)+    => Int+    -> (b -> m (Maybe (a, b)))+    -> a+    -> b+    -> m (NonEmptyUVector a)+unfoldr1NM n f a b = fmap (cons a . unsafeFromVector) (V.unfoldrNM n f b)+{-# INLINE unfoldr1NM #-}++-- | /O(n)/ Construct a non-empty vector with n elements by repeatedly applying the+-- generator function to the already constructed part of the vector.+--+-- If 'constructN' does not create meaningful values, 'Nothing' is+-- returned. Otherwise, 'Just' containing a non-empty vector is returned.+--+constructN :: V.Unbox a => Int -> (Vector a -> a) -> Maybe (NonEmptyUVector a)+constructN n f = fromVector (V.constructN n f)+{-# INLINE constructN #-}++-- | /O(n)/ Construct a vector with n elements from right to left by repeatedly+-- applying the generator function to the already constructed part of the vector.+--+-- If 'constructrN' does not create meaningful values, 'Nothing' is+-- returned. Otherwise, 'Just' containing a non-empty vector is returned.+--+constructrN :: V.Unbox a => Int -> (Vector a -> a) -> Maybe (NonEmptyUVector a)+constructrN n f = fromVector (V.constructrN n f)+{-# INLINE constructrN #-}++-- ---------------------------------------------------------------------- --+-- Enumeration++-- | /O(n)/ Yield a non-emptyvector of the given length containing the+-- values x, x+1 etc. This operation is usually more efficient than+-- 'enumFromTo'.+--+-- If an enumeration does not use meaningful indices, 'Nothing' is returned,+-- otherwise, 'Just' containing a non-empty vector.+--+enumFromN :: (V.Unbox a, Num a) => a -> Int -> Maybe (NonEmptyUVector a)+enumFromN a n = fromVector (V.enumFromN a n)+{-# INLINE enumFromN #-}++-- | /O(n)/ Yield a non-emptyvector of length @max n 1@ containing the+-- values x, x+1 etc. This operation is usually more efficient than+-- 'enumFromTo'.+--+enumFromN1 :: (V.Unbox a, Num a) => a -> Int -> NonEmptyUVector a+enumFromN1 a n = unsafeFromVector (V.enumFromN a (max n 1))+{-# INLINE enumFromN1 #-}++-- | /O(n)/ Yield a non-empty vector of the given length containing the+-- values x, x+y, x+y+y etc. This operations is usually more efficient than+-- 'enumFromThenTo'.+--+-- If an enumeration does not use meaningful indices, 'Nothing' is returned,+-- otherwise, 'Just' containing a non-empty vector.+--+enumFromStepN :: (V.Unbox a, Num a) => a -> a -> Int -> Maybe (NonEmptyUVector a)+enumFromStepN a0 a1 n = fromVector (V.enumFromStepN a0 a1 n)+{-# INLINE enumFromStepN #-}++-- | /O(n)/ Yield a non-empty vector of length @max n 1@ containing the+-- values x, x+y, x+y+y etc. This operations is usually more efficient than+-- 'enumFromThenTo'.+--+enumFromStepN1 :: (V.Unbox a, Num a) => a -> a -> Int -> NonEmptyUVector a+enumFromStepN1 a0 a1 n = unsafeFromVector (V.enumFromStepN a0 a1 (max n 1))+{-# INLINE enumFromStepN1 #-}++-- | /O(n)/ Enumerate values from x to y.+--+-- If an enumeration does not use meaningful indices, 'Nothing' is returned,+-- otherwise, 'Just' containing a non-empty vector.+--+-- /WARNING/: This operation can be very inefficient. If at all possible,+-- use 'enumFromN' instead.+--+--+enumFromTo :: (V.Unbox a, Enum a) => a -> a -> Maybe (NonEmptyUVector a)+enumFromTo a0 a1 = fromVector (V.enumFromTo a0 a1)+{-# INLINE enumFromTo #-}++-- | /O(n)/ Enumerate values from x to y with a specific step z.+--+-- If an enumeration does not use meaningful indices, 'Nothing' is returned,+-- otherwise, 'Just' containing a non-empty vector.+--+-- /WARNING/: This operation can be very inefficient. If at all possible,+-- use 'enumFromStepN' instead.+enumFromThenTo :: (V.Unbox a, Enum a) => a -> a -> a -> Maybe (NonEmptyUVector a)+enumFromThenTo a0 a1 a2 = fromVector (V.enumFromThenTo a0 a1 a2)+{-# INLINE enumFromThenTo #-}++-- ---------------------------------------------------------------------- --+-- Concatenation++-- | /O(n)/ Prepend an element+--+-- >>> cons 1 (unsafeFromList [2,3])+-- [1,2,3]+--+cons :: V.Unbox a => a -> NonEmptyUVector a -> NonEmptyUVector a+cons a (NonEmptyUVector as) = consV a as+{-# INLINE cons #-}++-- | /O(n)/ Prepend an element to a Vector+--+-- >>> consV 1 (V.fromList [2,3])+-- [1,2,3]+--+consV :: V.Unbox a => a -> Vector a -> NonEmptyUVector a+consV a = NonEmptyUVector . V.cons a+{-# INLINE consV #-}++-- | /O(n)/ Append an element+--+-- >>> snoc (unsafeFromList [1,2]) 3+-- [1,2,3]+--+snoc :: V.Unbox a => NonEmptyUVector a -> a -> NonEmptyUVector a+snoc (NonEmptyUVector as) = snocV as+{-# INLINE snoc #-}++-- | /O(n)/ Append an element to a Vector+--+-- >>> snocV (V.fromList [1,2]) 3+-- [1,2,3]+--+snocV :: V.Unbox a => Vector a -> a -> NonEmptyUVector a+snocV as = NonEmptyUVector . V.snoc as+{-# INLINE snocV #-}++-- | /O(m+n)/ Concatenate two non-empty vectors+--+-- >>> (unsafeFromList [1..3]) ++ (unsafeFromList [4..6])+-- [1,2,3,4,5,6]+--+(++) :: V.Unbox a => NonEmptyUVector a -> NonEmptyUVector a -> NonEmptyUVector a+NonEmptyUVector v ++ NonEmptyUVector v' = NonEmptyUVector (v <> v')+{-# INLINE (++) #-}++-- | /O(n)/ Concatenate all non-empty vectors in the list+--+-- If list is empty, 'Nothing' is returned, otherwise 'Just'+-- containing the concatenated non-empty vectors+--+-- >>> concat [(unsafeFromList [1..3]), (unsafeFromList [4..6])]+-- Just [1,2,3,4,5,6]+--+concat :: V.Unbox a => [NonEmptyUVector a] -> Maybe (NonEmptyUVector a)+concat [] = Nothing+concat (a:as) = Just (concat1 (a :| as))+{-# INLINE concat #-}++-- | O(n) Concatenate all non-empty vectors in a non-empty list.+--+-- >>> concat1 ((unsafeFromList [1..3]) :| [(unsafeFromList [4..6])])+-- [1,2,3,4,5,6]+--+concat1 :: V.Unbox a => NonEmpty (NonEmptyUVector a) -> NonEmptyUVector a+concat1 = NonEmptyUVector . Foldable.foldl' go V.empty+  where+    go v (NonEmptyUVector a) = v <> a+{-# INLINE concat1 #-}++-- ---------------------------------------------------------------------- --+-- Conversions++-- | /O(n)/ Convert a non-empty vector to a non-empty list.+--+-- >>> toNonEmpty (unsafeFromList [1..3])+-- 1 :| [2,3]+--+toNonEmpty :: V.Unbox a => NonEmptyUVector a -> NonEmpty a+toNonEmpty = NonEmpty.fromList . V.toList . _neUvec+{-# INLINE toNonEmpty #-}++-- | O(n) Convert from a non-empty list to a non-empty vector.+--+-- >>> fromNonEmpty (1 :| [2,3])+-- [1,2,3]+--+fromNonEmpty :: V.Unbox a => NonEmpty a -> NonEmptyUVector a+fromNonEmpty = NonEmptyUVector . V.fromList . Foldable.toList+{-# INLINE fromNonEmpty #-}++-- | O(n) Convert from the first n-elements of a non-empty list to a+-- non-empty vector.+--+-- Returns 'Nothing' if indices are <= 0, otherwise 'Just' containing+-- the non-empty vector.+--+-- >>> fromNonEmptyN 3 (1 :| [2..5])+-- Just [1,2,3]+--+-- >>> fromNonEmptyN 0 (1 :| [2..5])+-- Nothing+--+fromNonEmptyN :: V.Unbox a => Int -> NonEmpty a -> Maybe (NonEmptyUVector a)+fromNonEmptyN n a = fromVector (V.fromListN n (Foldable.toList a))+{-# INLINE fromNonEmptyN #-}++-- | O(n) Convert from the first n-elements of a non-empty list to a+-- non-empty vector. This is a safe version of `fromNonEmptyN` which+-- takes @max n 1@ of the first n-elements of the non-empty list.+--+--+-- >>> fromNonEmptyN1 3 (1 :| [2..5])+-- [1,2,3]+--+-- >>> fromNonEmptyN1 0 (1 :| [2..5])+-- [1]+--+fromNonEmptyN1 :: V.Unbox a => Int -> NonEmpty a -> NonEmptyUVector a+fromNonEmptyN1 n = unsafeFromVector+    . V.fromListN (max n 1)+    . Foldable.toList+{-# INLINE fromNonEmptyN1 #-}++-- | /O(1)/ Convert from a non-empty vector to a vector.+--+--+-- >>> let nev :: NonEmptyUVector Int = unsafeFromList [1..3] in toVector nev+-- [1,2,3]+--+toVector :: V.Unbox a => NonEmptyUVector a -> Vector a+toVector = _neUvec+{-# INLINE toVector #-}++-- | /O(1)/ Convert from a vector to a non-empty vector.+--+-- If the vector is empty, then 'Nothing' is returned,+-- otherwise 'Just' containing the non-empty vector.+--+-- >>> fromVector $ V.fromList [1..3]+-- Just [1,2,3]+--+-- >>> fromVector $ V.fromList []+-- Nothing+--+fromVector :: V.Unbox a => Vector a -> Maybe (NonEmptyUVector a)+fromVector v = if V.null v then Nothing else Just (NonEmptyUVector v)+{-# INLINE fromVector #-}++-- | /O(1)/ Convert from a vector to a non-empty vector without+-- checking bounds.+--+-- /Warning/: the onus is on the user to ensure that their vector+-- is not empty, otherwise all bets are off!+--+--+-- >>> unsafeFromVector $ V.fromList [1..3]+-- [1,2,3]+--+unsafeFromVector :: V.Unbox a => Vector a -> NonEmptyUVector a+unsafeFromVector = NonEmptyUVector+{-# INLINE unsafeFromVector #-}++-- | /O(n)/ Convert from a non-empty vector to a list.+--+--+-- >>> let nev :: NonEmptyUVector Int = unsafeFromList [1..3] in toList nev+-- [1,2,3]+--+toList :: V.Unbox a => NonEmptyUVector a -> [a]+toList = V.toList . _neUvec+{-# INLINE toList #-}++-- | /O(n)/ Convert from a list to a non-empty vector.+--+--+-- >>> fromList [1..3]+-- Just [1,2,3]+--+-- >>> fromList []+-- Nothing+--+fromList :: V.Unbox a => [a] -> Maybe (NonEmptyUVector a)+fromList = fromVector . V.fromList+{-# INLINE fromList #-}++-- | /O(n)/ Convert from a list to a non-empty vector.+--+-- /Warning/: the onus is on the user to ensure that their vector+-- is not empty, otherwise all bets are off!+--+-- >>> unsafeFromList [1..3]+-- [1,2,3]+--+unsafeFromList :: V.Unbox a => [a] -> NonEmptyUVector a+unsafeFromList = unsafeFromVector . V.fromList+{-# INLINE unsafeFromList #-}++-- | /O(n)/ Convert the first n elements of a list to a non-empty vector.+--+-- If the list is empty or <= 0 elements are chosen, 'Nothing' is+-- returned, otherwise 'Just' containing the non-empty vector+--+-- >>> fromListN 3 [1..5]+-- Just [1,2,3]+--+-- >>> fromListN 3 []+-- Nothing+--+-- >>> fromListN 0 [1..5]+-- Nothing+--+fromListN :: V.Unbox a => Int -> [a] -> Maybe (NonEmptyUVector a)+fromListN n as = fromVector (V.fromListN n as)+{-# INLINE fromListN #-}++-- ---------------------------------------------------------------------- --+-- Restricting memory usage++-- | /O(n)/ Yield the argument but force it not to retain any extra memory,+-- possibly by copying it.+--+force :: V.Unbox a => NonEmptyUVector a -> NonEmptyUVector a+force (NonEmptyUVector a) = NonEmptyUVector (V.force a)+{-# INLINE force #-}++-- ---------------------------------------------------------------------- --+-- Bulk Updates++-- | /O(m+n)/ For each pair (i,a) from the list, replace the non-empty vector+-- element at position i by a.+--+-- >>> unsafeFromList [1..3] // [(2,4)]+-- [1,2,4]+--+-- >>> unsafeFromList [1..3] // []+-- [1,2,3]+--+(//) :: V.Unbox a => NonEmptyUVector a -> [(Int, a)] -> NonEmptyUVector a+NonEmptyUVector v // us = NonEmptyUVector (v V.// us)+{-# INLINE (//) #-}++-- | O(m+n) For each pair (i,a) from the vector of index/value pairs,+-- replace the vector element at position i by a.+--+-- >>> unsafeFromList [1..3] `update` V.fromList [(2,4)]+-- [1,2,4]+--+-- >>> unsafeFromList [1..3] `update` V.empty+-- [1,2,3]+--+update :: V.Unbox a => NonEmptyUVector a -> Vector (Int, a) -> NonEmptyUVector a+update (NonEmptyUVector v) v' = NonEmptyUVector (V.update v v')+{-# INLINE update #-}++-- | /O(m+min(n1,n2))/ For each index i from the index vector and the+-- corresponding value a from the value vector, replace the element of+-- the initial vector at position i by a.+--+--+-- >>> update_ (unsafeFromList [1..3]) (V.fromList [2]) (V.fromList [4])+-- [1,2,4]+--+-- >>> update_ (unsafeFromList [1..3]) V.empty V.empty+-- [1,2,3]+--+update_ :: V.Unbox a => NonEmptyUVector a -> Vector Int -> Vector a -> NonEmptyUVector a+update_ (NonEmptyUVector v) is as = NonEmptyUVector (V.update_ v is as)+{-# INLINE update_ #-}++-- | Same as '(//)' but without bounds checking.+--+unsafeUpd :: V.Unbox a => NonEmptyUVector a -> [(Int, a)] -> NonEmptyUVector a+unsafeUpd (NonEmptyUVector v) us = NonEmptyUVector (V.unsafeUpd v us)+{-# INLINE unsafeUpd #-}++-- | Same as 'update' but without bounds checking.+--+unsafeUpdate :: V.Unbox a => NonEmptyUVector a -> Vector (Int, a) -> NonEmptyUVector a+unsafeUpdate (NonEmptyUVector v) us = NonEmptyUVector (V.unsafeUpdate v us)+{-# INLINE unsafeUpdate #-}++-- | Same as 'update_' but without bounds checking.+--+unsafeUpdate_ :: V.Unbox a => NonEmptyUVector a -> Vector Int -> Vector a -> NonEmptyUVector a+unsafeUpdate_ (NonEmptyUVector v) is as = NonEmptyUVector (V.unsafeUpdate_ v is as)+{-# INLINE unsafeUpdate_ #-}++-- ---------------------------------------------------------------------- --+-- Accumulation++-- | /O(m+n)/ For each pair @(i,b)@ from the non-empty list, replace the+-- non-empty vector element @a@ at position @i@ by @f a b@.+--+--+-- >>> accum (+) (unsafeFromList [1..3]) [(2,10)]+-- [1,2,13]+--+-- >>> accum (+) (unsafeFromList [1..3]) []+-- [1,2,3]+--+accum+    :: (V.Unbox a, V.Unbox b)+    => (a -> b -> a)+      -- ^ accumulating function @f@+    -> NonEmptyUVector a+      -- ^ initial non-empty vector (of length @m@)+    -> [(Int, b)]+      -- ^ list of index/value pairs (of length @n@)+    -> NonEmptyUVector a+accum f (NonEmptyUVector v) u = NonEmptyUVector (V.accum f v u)+{-# INLINE accum #-}++-- | /O(m+n)/ For each pair @(i,b)@ from the vector of pairs, replace the+-- non-empty vector element @a@ at position @i@ by @f a b@.+--+-- >>> accumulate (+) (unsafeFromList [1..3]) (V.fromList [(2,10)])+-- [1,2,13]+--+-- >>> accumulate (+) (unsafeFromList [1..3]) V.empty+-- [1,2,3]+--+accumulate+    :: (V.Unbox a, V.Unbox b)+    => (a -> b -> a)+      -- ^ accumulating function @f@+    -> NonEmptyUVector a+      -- ^ initial non-empty vector (of length @m@)+    -> Vector (Int, b)+      -- ^ vector of index/value pairs (of length @n@)+    -> NonEmptyUVector a+accumulate f (NonEmptyUVector v) u = NonEmptyUVector (V.accumulate f v u)+{-# INLINE accumulate #-}++-- | /O(m+min(n1,n2))/ For each index @i@ from the index vector and the+-- corresponding value @b@ from the the value vector, replace the element+-- of the initial non-empty vector at position @i@ by @f a b@.+--+-- >>> accumulate_ (+) (unsafeFromList [1..3]) (V.fromList [2]) (V.fromList [10])+-- [1,2,13]+--+-- >>> accumulate_ (+) (unsafeFromList [1..3]) V.empty V.empty+-- [1,2,3]+--+accumulate_+    :: (V.Unbox a, V.Unbox b)+    => (a -> b -> a)+      -- ^ accumulating function @f@+    -> NonEmptyUVector a+      -- ^ initial non-empty vector (of length @m@)+    -> Vector Int+       -- ^ vector of indices (of length @n1@)+    -> Vector b+       -- ^ vector of values (of length @n2@)+    -> NonEmptyUVector a+accumulate_ f (NonEmptyUVector v) i b = NonEmptyUVector (V.accumulate_ f v i b)+{-# INLINE accumulate_ #-}++-- | Same as 'accum' but without bounds checking.+--+unsafeAccum+    :: (V.Unbox a, V.Unbox b)+    => (a -> b -> a)+      -- ^ accumulating function @f@+    -> NonEmptyUVector a+      -- ^ initial non-empty vector (of length @m@)+    -> [(Int, b)]+      -- ^ list of index/value pairs (of length @n@)+    -> NonEmptyUVector a+unsafeAccum f (NonEmptyUVector v) u = NonEmptyUVector (V.unsafeAccum f v u)+{-# INLINE unsafeAccum #-}++-- | Same as 'accumulate' but without bounds checking.+--+unsafeAccumulate+    :: (V.Unbox a, V.Unbox b) +    => (a -> b -> a)+      -- ^ accumulating function @f@+    -> NonEmptyUVector a+      -- ^ initial non-empty vector (of length @m@)+    -> Vector (Int, b)+      -- ^ vector of index/value pairs (of length @n@)+    -> NonEmptyUVector a+unsafeAccumulate f v u = NonEmptyUVector (V.unsafeAccumulate f v' u)+  where+    v' = _neUvec v+{-# INLINE unsafeAccumulate #-}++-- | Same as 'accumulate_' but without bounds checking.+--+unsafeAccumulate_+    :: (V.Unbox a, V.Unbox b)+    => (a -> b -> a)+      -- ^ accumulating function @f@+    -> NonEmptyUVector a+      -- ^ initial non-empty vector (of length @m@)+    -> Vector Int+      -- ^ vector of indices of length @n1@+    -> Vector b+      -- ^ vector of values (of length @n2@)+    -> NonEmptyUVector a+unsafeAccumulate_ f v i b = NonEmptyUVector (V.unsafeAccumulate_ f v' i b)+  where+    v' = _neUvec v+{-# INLINE unsafeAccumulate_ #-}++-- ---------------------------------------------------------------------- --+-- Permutations++-- | /O(n)/ Reverse a non-empty vector+--+-- >>> reverse $ unsafeFromList [1..3]+-- [3,2,1]+--+reverse :: V.Unbox a => NonEmptyUVector a -> NonEmptyUVector a+reverse = NonEmptyUVector . V.reverse . _neUvec+{-# INLINE reverse #-}++-- | /O(n)/ Yield the non-empty vector obtained by replacing each element+-- @i@ of the non-empty index vector by @xs'!'i@. This is equivalent to+-- @'map' (xs'!') is@ but is often much more efficient.+--+-- >>> backpermute (unsafeFromList [1..3]) (unsafeFromList [2,0])+-- [3,1]+--+backpermute :: V.Unbox a => NonEmptyUVector a -> NonEmptyUVector Int -> NonEmptyUVector a+backpermute (NonEmptyUVector v) (NonEmptyUVector i)+    = NonEmptyUVector (V.backpermute v i)+{-# INLINE backpermute #-}++-- | Same as 'backpermute' but without bounds checking.+--+unsafeBackpermute+    :: V.Unbox a+    => NonEmptyUVector a+    -> NonEmptyUVector Int+    -> NonEmptyUVector a+unsafeBackpermute (NonEmptyUVector v) (NonEmptyUVector i)+    = NonEmptyUVector (V.unsafeBackpermute v i)+{-# INLINE unsafeBackpermute #-}++-- ---------------------------------------------------------------------- --+-- Safe destructive updates++-- | Apply a destructive operation to a non-empty vector. The operation+-- will be performed in place if it is safe to do so and will modify a+-- copy of the non-empty vector otherwise.+--+modify+    :: V.Unbox a+    => (forall s. MVector s a -> ST s ())+    -> NonEmptyUVector a+    -> NonEmptyUVector a+modify p (NonEmptyUVector v) = NonEmptyUVector (V.modify p v)+{-# INLINE modify #-}++-- ---------------------------------------------------------------------- --+-- Indexing++-- | /O(n)/ Pair each element in a vector with its index.+--+-- >>> indexed $ unsafeFromList ["a","b","c"]+-- [(0,"a"),(1,"b"),(2,"c")]+--+indexed :: (V.Unbox a) => NonEmptyUVector a -> NonEmptyUVector (Int, a)+indexed = NonEmptyUVector . V.indexed . _neUvec+{-# INLINE indexed #-}++-- ---------------------------------------------------------------------- --+-- Mapping++-- | /O(n)/ Map a function over a non-empty vector.+--+-- >>> map (+1) $ unsafeFromList [1..3]+-- [2,3,4]+--+map :: (V.Unbox a, V.Unbox b) => (a -> b) -> NonEmptyUVector a -> NonEmptyUVector b+map f = NonEmptyUVector . V.map f . _neUvec+{-# INLINE map #-}++-- | /O(n)/ Apply a function to every element of a non-empty vector and+-- its index.+--+-- >>> imap (\i a -> if i == 2 then a+1 else a+0) $ unsafeFromList [1..3]+-- [1,2,4]+--+imap :: (V.Unbox a, V.Unbox b) => (Int -> a -> b) -> NonEmptyUVector a -> NonEmptyUVector b+imap f = NonEmptyUVector . V.imap f . _neUvec+{-# INLINE imap #-}++-- | Map a function over a vector and concatenate the results.+--+-- >>> concatMap (\a -> unsafeFromList [a,a]) (unsafeFromList [1,2,3])+-- [1,1,2,2,3,3]+--+concatMap+    :: (V.Unbox a, V.Unbox b)+    => (a -> NonEmptyUVector b)+    -> NonEmptyUVector a+    -> NonEmptyUVector b+concatMap f = NonEmptyUVector . V.concatMap (_neUvec . f) . _neUvec+{-# INLINE concatMap #-}++-- ---------------------------------------------------------------------- --+-- Monadic Mapping++-- | /O(n)/ Apply the monadic action to all elements of the non-empty+-- vector, yielding non-empty vector of results.+--+-- >>> mapM Just (unsafeFromList [1..3])+-- Just [1,2,3]+--+-- >>> mapM (const Nothing) (unsafeFromList [1..3])+-- Nothing+--+mapM :: (V.Unbox a, V.Unbox b, Monad m) => (a -> m b) -> NonEmptyUVector a -> m (NonEmptyUVector b)+mapM f = fmap NonEmptyUVector . V.mapM f . _neUvec+{-# INLINE mapM #-}++-- | /O(n)/ Apply the monadic action to every element of a non-empty+-- vector and its index, yielding a non-empty vector of results.+--+-- >>> imapM (\i a -> if i == 1 then Just a else Just 0) (unsafeFromList [1..3])+-- Just [0,2,0]+--+-- >>> imapM (\_ _ -> Nothing) (unsafeFromList [1..3])+-- Nothing+--+imapM+    :: (V.Unbox a, V.Unbox b, Monad m)+    => (Int -> a -> m b)+    -> NonEmptyUVector a+    -> m (NonEmptyUVector b)+imapM f = fmap NonEmptyUVector . V.imapM f . _neUvec+{-# INLINE imapM #-}++-- | /O(n)/ Apply the monadic action to all elements of a non-empty vector+-- and ignore the results.+--+-- >>> mapM_ (const $ Just ()) (unsafeFromList [1..3])+-- Just ()+--+-- >>> mapM_ (const Nothing) (unsafeFromList [1..3])+-- Nothing+--+mapM_ :: (V.Unbox a, Monad m) => (a -> m b) -> NonEmptyUVector a -> m ()+mapM_ f = V.mapM_ f . _neUvec+{-# INLINE mapM_ #-}++-- | /O(n)/ Apply the monadic action to every element of a non-emptpy+-- vector and its index, ignoring the results+--+-- >>> imapM_ (\i a -> if i == 1 then P.print a else P.putStrLn "0") (unsafeFromList [1..3])+-- 0+-- 2+-- 0+--+-- >>> imapM_ (\_ _ -> Nothing) (unsafeFromList [1..3])+-- Nothing+--+imapM_ :: (V.Unbox a, Monad m) => (Int -> a -> m b) -> NonEmptyUVector a -> m ()+imapM_ f = V.imapM_ f . _neUvec+{-# INLINE imapM_ #-}++-- | /O(n)/ Apply the monadic action to all elements of the non-empty+-- vector, yielding a  non0empty vector of results.+--+-- Equivalent to @flip 'mapM'@.+--+forM :: (V.Unbox a, V.Unbox b, Monad m) => NonEmptyUVector a -> (a -> m b) -> m (NonEmptyUVector b)+forM (NonEmptyUVector v) f = fmap NonEmptyUVector (V.forM v f)+{-# INLINE forM #-}++-- | /O(n)/ Apply the monadic action to all elements of a non-empty+-- vector and ignore the results.+--+-- Equivalent to @flip 'mapM_'@.+--+forM_ :: (V.Unbox a, Monad m) => NonEmptyUVector a -> (a -> m b) -> m ()+forM_ (NonEmptyUVector v) f = V.forM_ v f+{-# INLINE forM_ #-}++-- ---------------------------------------------------------------------- --+-- Zipping++-- | /O(min(m,n))/ Zip two non-empty vectors with the given function.+--+-- >>> zipWith (+) (unsafeFromList [1..3]) (unsafeFromList [1..3])+-- [2,4,6]+--+zipWith+    :: (V.Unbox a, V.Unbox b, V.Unbox c)+    => (a -> b -> c)+    -> NonEmptyUVector a+    -> NonEmptyUVector b+    -> NonEmptyUVector c+zipWith f a b = NonEmptyUVector (V.zipWith f a' b')+  where+    a' = _neUvec a+    b' = _neUvec b+{-# INLINE zipWith #-}++-- | Zip three non-empty vectors with the given function.+--+--+zipWith3+    :: (V.Unbox a, V.Unbox b, V.Unbox c, V.Unbox d)+    => (a -> b -> c -> d)+    -> NonEmptyUVector a+    -> NonEmptyUVector b+    -> NonEmptyUVector c+    -> NonEmptyUVector d+zipWith3 f a b c = NonEmptyUVector (V.zipWith3 f a' b' c')+  where+    a' = _neUvec a+    b' = _neUvec b+    c' = _neUvec c+{-# INLINE zipWith3 #-}++-- | Zip four non-empty vectors with the given function.+--+zipWith4+    :: (V.Unbox a, V.Unbox b, V.Unbox c, V.Unbox d, V.Unbox e)+    => (a -> b -> c -> d -> e)+    -> NonEmptyUVector a+    -> NonEmptyUVector b+    -> NonEmptyUVector c+    -> NonEmptyUVector d+    -> NonEmptyUVector e+zipWith4 f a b c d = NonEmptyUVector (V.zipWith4 f a' b' c' d')+  where+    a' = _neUvec a+    b' = _neUvec b+    c' = _neUvec c+    d' = _neUvec d+{-# INLINE zipWith4 #-}++-- | Zip five non-empty vectors with the given function.+--+zipWith5+    :: (V.Unbox a, V.Unbox b, V.Unbox c, V.Unbox d, V.Unbox e, V.Unbox f)+    => (a -> b -> c -> d -> e -> f)+    -> NonEmptyUVector a+    -> NonEmptyUVector b+    -> NonEmptyUVector c+    -> NonEmptyUVector d+    -> NonEmptyUVector e+    -> NonEmptyUVector f+zipWith5 f a b c d e = NonEmptyUVector (V.zipWith5 f a' b' c' d' e')+  where+    a' = _neUvec a+    b' = _neUvec b+    c' = _neUvec c+    d' = _neUvec d+    e' = _neUvec e+{-# INLINE zipWith5 #-}++-- | Zip six non-empty vectors with the given function.+--+zipWith6+    :: (V.Unbox a, V.Unbox b, V.Unbox c, V.Unbox d, V.Unbox e, V.Unbox f, V.Unbox g)+    => (a -> b -> c -> d -> e -> f -> g)+    -> NonEmptyUVector a+    -> NonEmptyUVector b+    -> NonEmptyUVector c+    -> NonEmptyUVector d+    -> NonEmptyUVector e+    -> NonEmptyUVector f+    -> NonEmptyUVector g+zipWith6 k a b c d e f = NonEmptyUVector (V.zipWith6 k a' b' c' d' e' f')+  where+    a' = _neUvec a+    b' = _neUvec b+    c' = _neUvec c+    d' = _neUvec d+    e' = _neUvec e+    f' = _neUvec f+{-# INLINE zipWith6 #-}+++-- | /O(min(m,n))/ Zip two non-empty vectors with a function that also+-- takes the elements' indices.+--+izipWith+    :: (V.Unbox a, V.Unbox b, V.Unbox c)+    => (Int -> a -> b -> c)+    -> NonEmptyUVector a+    -> NonEmptyUVector b+    -> NonEmptyUVector c+izipWith f a b = NonEmptyUVector (V.izipWith f a' b')+  where+    a' = _neUvec a+    b' = _neUvec b+{-# INLINE izipWith #-}++-- | Zip three non-empty vectors and their indices with the given function.+--+izipWith3+    :: (V.Unbox a, V.Unbox b, V.Unbox c, V.Unbox d)+    => (Int -> a -> b -> c -> d)+    -> NonEmptyUVector a+    -> NonEmptyUVector b+    -> NonEmptyUVector c+    -> NonEmptyUVector d+izipWith3 f a b c = NonEmptyUVector (V.izipWith3 f a' b' c')+  where+    a' = _neUvec a+    b' = _neUvec b+    c' = _neUvec c+{-# INLINE izipWith3 #-}++-- | Zip four non-empty vectors and their indices with the given function.+--+izipWith4+    :: (V.Unbox a, V.Unbox b, V.Unbox c, V.Unbox d, V.Unbox e)+    => (Int -> a -> b -> c -> d -> e)+    -> NonEmptyUVector a+    -> NonEmptyUVector b+    -> NonEmptyUVector c+    -> NonEmptyUVector d+    -> NonEmptyUVector e+izipWith4 f a b c d = NonEmptyUVector (V.izipWith4 f a' b' c' d')+  where+    a' = _neUvec a+    b' = _neUvec b+    c' = _neUvec c+    d' = _neUvec d+{-# INLINE izipWith4 #-}++-- | Zip five non-empty vectors and their indices with the given function.+--+izipWith5+    :: (V.Unbox a, V.Unbox b, V.Unbox c, V.Unbox d, V.Unbox e, V.Unbox f)+    => (Int -> a -> b -> c -> d -> e -> f)+    -> NonEmptyUVector a+    -> NonEmptyUVector b+    -> NonEmptyUVector c+    -> NonEmptyUVector d+    -> NonEmptyUVector e+    -> NonEmptyUVector f+izipWith5 f a b c d e = NonEmptyUVector (V.izipWith5 f a' b' c' d' e')+  where+    a' = _neUvec a+    b' = _neUvec b+    c' = _neUvec c+    d' = _neUvec d+    e' = _neUvec e+{-# INLINE izipWith5 #-}++-- | Zip six non-empty vectors and their indices with the given function.+--+izipWith6+    :: (V.Unbox a, V.Unbox b, V.Unbox c, V.Unbox d, V.Unbox e, V.Unbox f, V.Unbox g)+    => (Int -> a -> b -> c -> d -> e -> f -> g)+    -> NonEmptyUVector a+    -> NonEmptyUVector b+    -> NonEmptyUVector c+    -> NonEmptyUVector d+    -> NonEmptyUVector e+    -> NonEmptyUVector f+    -> NonEmptyUVector g+izipWith6 k a b c d e f = NonEmptyUVector (V.izipWith6 k a' b' c' d' e' f')+  where+    a' = _neUvec a+    b' = _neUvec b+    c' = _neUvec c+    d' = _neUvec d+    e' = _neUvec e+    f' = _neUvec f+{-# INLINE izipWith6 #-}++-- | /O(min(n,m))/ Elementwise pairing of non-empty vector elements. This is a special case+-- of 'zipWith' where the function argument is @(,)@+--+zip :: (V.Unbox a, V.Unbox b) => NonEmptyUVector a -> NonEmptyUVector b -> NonEmptyUVector (a, b)+zip a b = NonEmptyUVector (V.zip a' b')+  where+    a' = _neUvec a+    b' = _neUvec b+{-# INLINE zip #-}++-- | Zip together three non-empty vectors.+--+zip3+    :: (V.Unbox a, V.Unbox b, V.Unbox c)+    => NonEmptyUVector a+    -> NonEmptyUVector b+    -> NonEmptyUVector c+    -> NonEmptyUVector (a, b, c)+zip3 a b c = NonEmptyUVector (V.zip3 a' b' c')+  where+    a' = _neUvec a+    b' = _neUvec b+    c' = _neUvec c+{-# INLINE zip3 #-}++-- | Zip together four non-empty vectors.+--+zip4+    :: (V.Unbox a, V.Unbox b, V.Unbox c, V.Unbox d)+    => NonEmptyUVector a+    -> NonEmptyUVector b+    -> NonEmptyUVector c+    -> NonEmptyUVector d+    -> NonEmptyUVector (a, b, c, d)+zip4 a b c d = NonEmptyUVector (V.zip4 a' b' c' d')+  where+    a' = _neUvec a+    b' = _neUvec b+    c' = _neUvec c+    d' = _neUvec d+{-# INLINE zip4 #-}++-- | Zip together five non-empty vectors.+--+zip5+    :: (V.Unbox a, V.Unbox b, V.Unbox c, V.Unbox d, V.Unbox e)+    => NonEmptyUVector a+    -> NonEmptyUVector b+    -> NonEmptyUVector c+    -> NonEmptyUVector d+    -> NonEmptyUVector e+    -> NonEmptyUVector (a, b, c, d, e)+zip5 a b c d e = NonEmptyUVector (V.zip5 a' b' c' d' e')+  where+    a' = _neUvec a+    b' = _neUvec b+    c' = _neUvec c+    d' = _neUvec d+    e' = _neUvec e+{-# INLINE zip5 #-}++-- | Zip together six non-empty vectors.+--+zip6+    :: (V.Unbox a, V.Unbox b, V.Unbox c, V.Unbox d, V.Unbox e, V.Unbox f)+    => NonEmptyUVector a+    -> NonEmptyUVector b+    -> NonEmptyUVector c+    -> NonEmptyUVector d+    -> NonEmptyUVector e+    -> NonEmptyUVector f+    -> NonEmptyUVector (a, b, c, d, e, f)+zip6 a b c d e f = NonEmptyUVector (V.zip6 a' b' c' d' e' f')+  where+    a' = _neUvec a+    b' = _neUvec b+    c' = _neUvec c+    d' = _neUvec d+    e' = _neUvec e+    f' = _neUvec f+{-# INLINE zip6 #-}++-- ---------------------------------------------------------------------- --+-- Monadic Zipping++-- | /O(min(m,n))/ Zip the two non-empty vectors with the monadic action+-- and yield a non-empty vector of results.+--+zipWithM+    :: (V.Unbox a, V.Unbox b, V.Unbox c, Monad m)+    => (a -> b -> m c)+    -> NonEmptyUVector a+    -> NonEmptyUVector b+    -> m (NonEmptyUVector c)+zipWithM f a b = fmap NonEmptyUVector (V.zipWithM f a' b')+  where+    a' = _neUvec a+    b' = _neUvec b+{-# INLINE zipWithM #-}++-- | /O(min(m,n))/ Zip the two non-empty vectors with a monadic action+-- that also takes the element index and yield a vector of results.+--+izipWithM+    :: (V.Unbox a, V.Unbox b, V.Unbox c, Monad m)+    => (Int -> a -> b -> m c)+    -> NonEmptyUVector a+    -> NonEmptyUVector b+    -> m (NonEmptyUVector c)+izipWithM f a b = fmap NonEmptyUVector (V.izipWithM f a' b')+  where+    a' = _neUvec a+    b' = _neUvec b+{-# INLINE izipWithM #-}++-- | /O(min(m,n))/ Zip the two non-empty vectors with the monadic action+-- and ignore the results.+--+zipWithM_+    :: (V.Unbox a, V.Unbox b, Monad m)+    => (a -> b -> m c)+    -> NonEmptyUVector a+    -> NonEmptyUVector b+    -> m ()+zipWithM_ f a b = V.zipWithM_ f (_neUvec a) (_neUvec b)+{-# INLINE zipWithM_ #-}++-- | /O(min(m,n))/ Zip the two non-empty vectors with a monadic action+-- that also takes the element index and ignore the results.+--+izipWithM_+    :: (V.Unbox a, V.Unbox b, Monad m)+    => (Int -> a -> b -> m c)+    -> NonEmptyUVector a+    -> NonEmptyUVector b+    -> m ()+izipWithM_ f a b = V.izipWithM_ f (_neUvec a) (_neUvec b)+{-# INLINE izipWithM_ #-}++-- ---------------------------------------------------------------------- --+-- Unzipping++-- | /O(min(m,n))/ Unzip a non-empty vector of pairs.+--+unzip :: (V.Unbox a, V.Unbox b) => NonEmptyUVector (a, b) -> (NonEmptyUVector a, NonEmptyUVector b)+unzip (NonEmptyUVector v) = case V.unzip v of+    ~(a,b) -> (NonEmptyUVector a, NonEmptyUVector b)+{-# INLINE unzip #-}++-- | Unzip a non-empty vector of triples.+--+unzip3+    :: (V.Unbox a, V.Unbox b, V.Unbox c) +    => NonEmptyUVector (a, b, c)+    -> (NonEmptyUVector a, NonEmptyUVector b, NonEmptyUVector c)+unzip3 (NonEmptyUVector v) = case V.unzip3 v of+    ~(a,b,c) ->+      ( NonEmptyUVector a+      , NonEmptyUVector b+      , NonEmptyUVector c+      )+{-# INLINE unzip3 #-}++-- | Unzip a non-empty vector of quadruples.+--+unzip4+    :: (V.Unbox a, V.Unbox b, V.Unbox c, V.Unbox d) +    => NonEmptyUVector (a, b, c, d)+    -> ( NonEmptyUVector a+       , NonEmptyUVector b+       , NonEmptyUVector c+       , NonEmptyUVector d+       )+unzip4 (NonEmptyUVector v) = case V.unzip4 v of+    ~(a,b,c,d) ->+      ( NonEmptyUVector a+      , NonEmptyUVector b+      , NonEmptyUVector c+      , NonEmptyUVector d+      )+{-# INLINE unzip4 #-}++-- | Unzip a non-empty vector of quintuples.+--+unzip5+    :: (V.Unbox a, V.Unbox b, V.Unbox c, V.Unbox d, V.Unbox e) +    => NonEmptyUVector (a, b, c, d, e)+    -> ( NonEmptyUVector a+       , NonEmptyUVector b+       , NonEmptyUVector c+       , NonEmptyUVector d+       , NonEmptyUVector e+       )+unzip5 (NonEmptyUVector v) = case V.unzip5 v of+    ~(a,b,c,d,e) ->+      ( NonEmptyUVector a+      , NonEmptyUVector b+      , NonEmptyUVector c+      , NonEmptyUVector d+      , NonEmptyUVector e+      )+{-# INLINE unzip5 #-}++-- | Unzip a non-empty vector of sextuples.+--+unzip6+    :: (V.Unbox a, V.Unbox b, V.Unbox c, V.Unbox d, V.Unbox e, V.Unbox f) +    => NonEmptyUVector (a, b, c, d, e, f)+    -> ( NonEmptyUVector a+       , NonEmptyUVector b+       , NonEmptyUVector c+       , NonEmptyUVector d+       , NonEmptyUVector e+       , NonEmptyUVector f+       )+unzip6 (NonEmptyUVector v) = case V.unzip6 v of+    ~(a,b,c,d,e,f) ->+      ( NonEmptyUVector a+      , NonEmptyUVector b+      , NonEmptyUVector c+      , NonEmptyUVector d+      , NonEmptyUVector e+      , NonEmptyUVector f+      )+{-# INLINE unzip6 #-}++-- ---------------------------------------------------------------------- --+-- Filtering++-- | /O(n)/ Drop elements that do not satisfy the predicate.+--+-- If no elements satisfy the predicate, the resulting vector may be empty.+--+-- >>> filter (\a -> if a == 2 then False else True) (unsafeFromList [1..3])+-- [1,3]+--+-- >>> filter (const False) (unsafeFromList [1..3])+-- []+--+filter :: V.Unbox a => (a -> Bool) -> NonEmptyUVector a -> Vector a+filter f = V.filter f . _neUvec+{-# INLINE filter #-}++-- | /O(n)/ Drop elements that do not satisfy the predicate which is+-- applied to values and their indices.+--+-- If no elements satisfy the predicate, the resulting vector may be empty.+--+-- >>> ifilter (\i a -> if a == 2 || i == 0 then False else True) (unsafeFromList [1..3])+-- [3]+--+-- >>> ifilter (\_ _ -> False) (unsafeFromList [1..3])+-- []+--+ifilter+    :: V.Unbox a+    => (Int -> a -> Bool)+    -> NonEmptyUVector a+    -> Vector a+ifilter f = V.ifilter f . _neUvec+{-# INLINE ifilter #-}++-- | /O(n)/ Drop elements that do not satisfy the monadic predicate.+--+-- If no elements satisfy the predicate, the resulting vector may be empty.+--+-- >>> filterM (\a -> if a == 2 then Just False else Just True) (unsafeFromList [1..3])+-- Just [1,3]+--+-- >>> filterM (\a -> if a == 2 then Nothing else Just True) (unsafeFromList [1..3])+-- Nothing+--+-- >>> filterM (const $ Just False) (unsafeFromList [1..3])+-- Just []+--+filterM+    :: (V.Unbox a, Monad m)+    => (a -> m Bool)+    -> NonEmptyUVector a+    -> m (Vector a)+filterM f = V.filterM f . _neUvec+{-# INLINE filterM #-}++-- | /O(n)/ Drop elements that do not satisfy the monadic predicate that is+-- a function of index and value.+--+-- If no elements satisfy the predicate, the resulting vector may be empty.+--+-- TODO: this should be a more efficient function in @vector@.+--+-- >>> ifilterM (\i a -> if a == 2 || i == 0 then Just False else Just True) (unsafeFromList [1..3])+-- Just [3]+--+-- >>> ifilterM (\i a -> if a == 2 || i == 0 then Nothing else Just True) (unsafeFromList [1..3])+-- Nothing+--+-- >>> ifilterM (\_ _ -> Just False) (unsafeFromList [1..3])+-- Just []+--+ifilterM+    :: (V.Unbox a, Monad m)+    => (Int -> a -> m Bool)+    -> NonEmptyUVector a+    -> m (Vector a)+ifilterM f = fmap (V.map snd)+    . V.filterM (uncurry f)+    . V.indexed+    . _neUvec+{-# INLINE ifilterM #-}++-- | /O(n)/ Drop repeated adjacent elements.+--+-- >>> uniq $ unsafeFromList [1,1,2,2,3,3,1]+-- [1,2,3,1]+--+uniq :: (V.Unbox a, Eq a) => NonEmptyUVector a -> NonEmptyUVector a+uniq = NonEmptyUVector . V.uniq . _neUvec+{-# INLINE uniq #-}++-- | /O(n)/ Drop elements when predicate returns Nothing+--+-- If no elements satisfy the predicate, the resulting vector may be empty.+--+-- >>> mapMaybe (\a -> if a == 2 then Nothing else Just a) (unsafeFromList [1..3])+-- [1,3]+--+mapMaybe+    :: (V.Unbox a, V.Unbox b)+    => (a -> Maybe b)+    -> NonEmptyUVector a+    -> Vector b+mapMaybe f = V.mapMaybe f . _neUvec+{-# INLINE mapMaybe #-}++-- | /O(n)/ Drop elements when predicate, applied to index and value, returns Nothing+--+-- If no elements satisfy the predicate, the resulting vector may be empty.+--+-- >>> imapMaybe (\i a -> if a == 2 || i == 2 then Nothing else Just a) (unsafeFromList [1..3])+-- [1]+--+imapMaybe+    :: (V.Unbox a, V.Unbox b) +    => (Int -> a -> Maybe b)+    -> NonEmptyUVector a+    -> Vector b+imapMaybe f = V.imapMaybe f . _neUvec+{-# INLINE imapMaybe #-}++-- | /O(n)/ Yield the longest prefix of elements satisfying the predicate+-- without copying.+--+-- If no elements satisfy the predicate, the resulting vector may be empty.+--+-- >>> takeWhile (/= 3) (unsafeFromList [1..3])+-- [1,2]+--+takeWhile :: V.Unbox a => (a -> Bool) -> NonEmptyUVector a -> Vector a+takeWhile f = V.takeWhile f . _neUvec+{-# INLINE takeWhile #-}++-- | /O(n)/ Drop the longest prefix of elements that satisfy the predicate+-- without copying.+--+-- If all elements satisfy the predicate, the resulting vector may be empty.+--+-- >>> dropWhile (/= 3) (unsafeFromList [1..3])+-- [3]+--+dropWhile :: V.Unbox a => (a -> Bool) -> NonEmptyUVector a -> Vector a+dropWhile f = V.dropWhile f . _neUvec+{-# INLINE dropWhile #-}++-- ---------------------------------------------------------------------- --+-- Partitioning++-- | /O(n)/ Split the non-empty vector in two parts, the first one+-- containing those elements that satisfy the predicate and the second+-- one those that don't. The relative order of the elements is preserved+-- at the cost of a sometimes reduced performance compared to+-- 'unstablePartition'.+--+-- If all or no elements satisfy the predicate, one of the resulting vectors+-- may be empty.+--+-- >>> partition (< 3) (unsafeFromList [1..5])+-- ([1,2],[3,4,5])+--+partition :: V.Unbox a => (a -> Bool) -> NonEmptyUVector a -> (Vector a, Vector a)+partition f = V.partition f . _neUvec+{-# INLINE partition #-}++-- | /O(n)/ Split the non-empty vector in two parts, the first one+-- containing the Left elements and the second containing the+-- Right elements. The relative order of the elements is preserved.+--+-- If all elements produce a Left (or Right), one of the+-- resulting vectors may be empty.+--+-- >>> partitionWith (\a -> if a < 3 then Left a else Right (P.show a)) (unsafeFromList [1..5])+-- ([1,2],["3","4","5"])+--+partitionWith :: (V.Unbox a, V.Unbox b, V.Unbox c) => +  (a -> Either b c) -> NonEmptyUVector a -> (Vector b, Vector c)+partitionWith f = V.partitionWith f . _neUvec+{-# INLINE partitionWith #-}++-- | /O(n)/ Split the non-empty vector in two parts, the first one+-- containing those elements that satisfy the predicate and the second+-- one those that don't. The order of the elements is not preserved but+-- the operation is often faster than 'partition'.+--+-- If all or no elements satisfy the predicate, one of the resulting vectors+-- may be empty.+--+unstablePartition+    :: V.Unbox a+    => (a -> Bool)+    -> NonEmptyUVector a+    -> (Vector a, Vector a)+unstablePartition f = V.unstablePartition f . _neUvec+{-# INLINE unstablePartition #-}++-- | /O(n)/ Split the non-empty vector into the longest prefix of elements+-- that satisfy the predicate and the rest without copying.+--+-- If all or no elements satisfy the predicate, one of the resulting vectors+-- may be empty.+--+-- >>> span (== 1) (unsafeFromList [1,1,2,3,1])+-- ([1,1],[2,3,1])+--+span :: V.Unbox a => (a -> Bool) -> NonEmptyUVector a -> (Vector a, Vector a)+span f = V.span f . _neUvec+{-# INLINE span #-}++-- | /O(n)/ Split the vector into the longest prefix of elements that do not+-- satisfy the predicate and the rest without copying.+--+-- If all or no elements satisfy the predicate, one of the resulting vectors+-- may be empty.+--+-- >>> break (== 2) (unsafeFromList [1,1,2,3,1])+-- ([1,1],[2,3,1])+--+break :: V.Unbox a => (a -> Bool) -> NonEmptyUVector a -> (Vector a, Vector a)+break f = V.break f . _neUvec+{-# INLINE break #-}++-- ---------------------------------------------------------------------- --+-- Searching++-- | /O(n)/ Check if the non-empty vector contains an element+--+-- >>> elem 1 $ unsafeFromList [1..3]+-- True+-- >>> elem 4 $ unsafeFromList [1..3]+-- False+--+elem :: (V.Unbox a, Eq a) => a -> NonEmptyUVector a -> Bool+elem a = V.elem a . _neUvec+{-# INLINE elem #-}++-- | /O(n)/ Check if the non-empty vector does not contain an element+-- (inverse of 'elem')+--+-- >>> notElem 1 $ unsafeFromList [1..3]+-- False+--+-- >>> notElem 4 $ unsafeFromList [1..3]+-- True+--+notElem :: (V.Unbox a, Eq a) => a -> NonEmptyUVector a -> Bool+notElem a = V.notElem a . _neUvec+{-# INLINE notElem #-}++-- | /O(n)/ Yield 'Just' the first element matching the predicate or+-- 'Nothing' if no such element exists.+--+-- >>> find (< 2) $ unsafeFromList [1..3]+-- Just 1+--+-- >>> find (< 0) $ unsafeFromList [1..3]+-- Nothing+--+find :: V.Unbox a => (a -> Bool) -> NonEmptyUVector a -> Maybe a+find f = V.find f . _neUvec+{-# INLINE find #-}++-- | /O(n)/ Yield 'Just' the index of the first element matching the+-- predicate or 'Nothing' if no such element exists.+--+-- >>> findIndex (< 2) $ unsafeFromList [1..3]+-- Just 0+--+-- >>> findIndex (< 0) $ unsafeFromList [1..3]+-- Nothing+--+findIndex :: V.Unbox a => (a -> Bool) -> NonEmptyUVector a -> Maybe Int+findIndex f = V.findIndex f . _neUvec+{-# INLINE findIndex #-}++-- | /O(n)/ Yield the indices of elements satisfying the predicate in+-- ascending order.+--+-- >>> findIndices (< 3) $ unsafeFromList [1..3]+-- [0,1]+--+-- >>> findIndices (< 0) $ unsafeFromList [1..3]+-- []+--+findIndices :: V.Unbox a => (a -> Bool) -> NonEmptyUVector a -> Vector Int+findIndices f = V.findIndices f . _neUvec+{-# INLINE findIndices #-}++-- | /O(n)/ Yield 'Just' the index of the first occurence of the given+-- element or 'Nothing' if the non-empty vector does not contain the+-- element. This is a specialised version of 'findIndex'.+--+-- >>> elemIndex 1 $ unsafeFromList [1..3]+-- Just 0+--+-- >>> elemIndex 0 $ unsafeFromList [1..3]+-- Nothing+--+elemIndex :: (V.Unbox a, Eq a) => a -> NonEmptyUVector a -> Maybe Int+elemIndex a = V.elemIndex a . _neUvec+{-# INLINE elemIndex #-}++-- | /O(n)/ Yield the indices of all occurences of the given element in+-- ascending order. This is a specialised version of 'findIndices'.+--+-- >>> elemIndices 1 $ unsafeFromList [1,2,3,1]+-- [0,3]+--+-- >>> elemIndices 0 $ unsafeFromList [1..3]+-- []+--+elemIndices :: (V.Unbox a, Eq a) => a -> NonEmptyUVector a -> Vector Int+elemIndices a = V.elemIndices a . _neUvec+{-# INLINE elemIndices #-}++-- ---------------------------------------------------------------------- --+-- Folding++-- | /O(n)/ Left monoidal fold+--+foldl :: V.Unbox b => (a -> b -> a) -> a -> NonEmptyUVector b -> a+foldl f a = V.foldl f a . _neUvec+{-# INLINE foldl #-}++-- | /O(n)/ Left semigroupal fold+--+foldl1 :: V.Unbox a => (a -> a -> a) -> NonEmptyUVector a -> a+foldl1 f = V.foldl1 f . _neUvec+{-# INLINE foldl1 #-}++-- | /O(n)/ Strict Left monoidal fold+--+foldl' :: V.Unbox b => (a -> b -> a) -> a -> NonEmptyUVector b -> a+foldl' f a = V.foldl' f a . _neUvec+{-# INLINE foldl' #-}++-- | /O(n)/ Strict Left semigroupal fold+--+foldl1' :: V.Unbox a => (a -> a -> a) -> NonEmptyUVector a -> a+foldl1' f = V.foldl1' f . _neUvec+{-# INLINE foldl1' #-}++-- | /O(n)/ Right monoidal fold+--+foldr :: V.Unbox a => (a -> b -> b) -> b -> NonEmptyUVector a -> b+foldr f b = V.foldr f b . _neUvec+{-# INLINE foldr #-}++-- | /O(n)/ Right semigroupal fold+--+foldr1 :: V.Unbox a => (a -> a -> a) -> NonEmptyUVector a -> a+foldr1 f = V.foldr1 f . _neUvec+{-# INLINE foldr1 #-}++-- | /O(n)/ Strict right monoidal fold+--+foldr' :: V.Unbox a => (a -> b -> b) -> b -> NonEmptyUVector a -> b+foldr' f b = V.foldr' f b. _neUvec+{-# INLINE foldr' #-}++-- | /O(n)/ Strict right semigroupal fold+--+foldr1' :: V.Unbox a => (a -> a -> a) -> NonEmptyUVector a -> a+foldr1' f = V.foldr1' f . _neUvec+{-# INLINE foldr1' #-}++-- | /O(n)/ Left monoidal fold with function applied to each element+-- and its index+--+ifoldl :: V.Unbox b => (a -> Int -> b -> a) -> a -> NonEmptyUVector b -> a+ifoldl f a = V.ifoldl f a . _neUvec+{-# INLINE ifoldl #-}++-- | /O(n)/ Strict left monoidal fold with function applied to each element+-- and its index+--+ifoldl' :: V.Unbox b => (a -> Int -> b -> a) -> a -> NonEmptyUVector b -> a+ifoldl' f a = V.ifoldl' f a . _neUvec+{-# INLINE ifoldl' #-}++-- | /O(n)/ Right monoidal fold with function applied to each element+-- and its index+--+ifoldr :: V.Unbox a => (Int -> a -> b -> b) -> b -> NonEmptyUVector a -> b+ifoldr f b = V.ifoldr f b . _neUvec+{-# INLINE ifoldr #-}++-- | /O(n)/ strict right monoidal fold with function applied to each element+-- and its index+--+ifoldr' :: V.Unbox a => (Int -> a -> b -> b) -> b -> NonEmptyUVector a -> b+ifoldr' f b = V.ifoldr' f b . _neUvec+{-# INLINE ifoldr' #-}++-- ---------------------------------------------------------------------- --+-- Specialised folds++-- | /O(n)/ Check if all elements satisfy the predicate.+--+all :: V.Unbox a => (a -> Bool) -> NonEmptyUVector a -> Bool+all f = V.all f . _neUvec+{-# INLINE all #-}++-- | /O(n)/ Check if any element satisfies the predicate.+--+any :: V.Unbox a => (a -> Bool) -> NonEmptyUVector a -> Bool+any f = V.any f . _neUvec+{-# INLINE any #-}++-- | /O(n)/ Check if all elements are @True@.+--+and :: NonEmptyUVector Bool -> Bool+and = V.and . _neUvec+{-# INLINE and #-}++-- | /O(n)/ Check if any element is @True@+--+or :: NonEmptyUVector Bool -> Bool+or = V.or . _neUvec+{-# INLINE or #-}++-- | /O(n)/ Compute the sum of the elements+--+sum :: (Num a, V.Unbox a) => NonEmptyUVector a -> a+sum = V.sum . _neUvec+{-# INLINE sum #-}++-- | /O(n)/ Compute the produce of the elements+--+product :: (Num a, V.Unbox a) => NonEmptyUVector a -> a+product = V.product . _neUvec+{-# INLINE product #-}++-- | /O(n)/ Yield the maximum element of the non-empty vector.+--+maximum :: (V.Unbox a, Ord a) => NonEmptyUVector a -> a+maximum = V.maximum . _neUvec+{-# INLINE maximum #-}++-- | /O(n)/ Yield the maximum element of a non-empty vector+-- according to the given comparison function.+--+maximumBy :: V.Unbox a => (a -> a -> Ordering) -> NonEmptyUVector a -> a+maximumBy f = V.maximumBy f . _neUvec+{-# INLINE maximumBy #-}++-- | /O(n)/ Yield the minimum element of the non-empty vector.+--+minimum :: (V.Unbox a, Ord a) => NonEmptyUVector a -> a+minimum = V.minimum . _neUvec+{-# INLINE minimum #-}++-- | /O(n)/ Yield the minimum element of the non-empty vector+-- according to the given comparison function.+--+minimumBy :: V.Unbox a => (a -> a -> Ordering) -> NonEmptyUVector a -> a+minimumBy f = V.minimumBy f . _neUvec+{-# INLINE minimumBy #-}++-- | /O(n)/ Yield the index of the minimum element of the+-- non-empty vector.+--+minIndex :: (V.Unbox a, Ord a) => NonEmptyUVector a -> Int+minIndex = V.minIndex . _neUvec+{-# INLINE minIndex #-}++-- | /O(n)/ Yield the index of the minimum element of the vector+-- according to the given comparison function.+--+minIndexBy :: V.Unbox a => (a -> a -> Ordering) -> NonEmptyUVector a -> Int+minIndexBy f = V.minIndexBy f . _neUvec+{-# INLINE minIndexBy #-}++-- | /O(n)/ Yield the index of the maximum element of the+-- non-empty vector.+--+maxIndex :: (V.Unbox a, Ord a) => NonEmptyUVector a -> Int+maxIndex = V.maxIndex . _neUvec+{-# INLINE maxIndex #-}++-- | /O(n)/ Yield the index of the maximum element of the vector+-- according to the given comparison function.+--+maxIndexBy :: V.Unbox a => (a -> a -> Ordering) -> NonEmptyUVector a -> Int+maxIndexBy f = V.maxIndexBy f . _neUvec+{-# INLINE maxIndexBy #-}++-- ---------------------------------------------------------------------- --+-- Monadic folds++-- | /O(n)/ Monadic fold+--+foldM :: (V.Unbox b, Monad m) => (a -> b -> m a) -> a -> NonEmptyUVector b -> m a+foldM f a = V.foldM f a . _neUvec+{-# INLINE foldM #-}++-- | /O(n)/ Monadic fold (action applied to each element and its index)+--+ifoldM :: (V.Unbox b, Monad m) => (a -> Int -> b -> m a) -> a -> NonEmptyUVector b -> m a+ifoldM f a = V.ifoldM f a . _neUvec+{-# INLINE ifoldM #-}++-- | /O(n)/ Strict monadic fold+--+foldM' :: (V.Unbox b, Monad m) => (a -> b -> m a) -> a -> NonEmptyUVector b -> m a+foldM' f a = V.foldM' f a . _neUvec+{-# INLINE foldM' #-}++-- | /O(n)/ Strict monadic fold (action applied to each element and its index)+--+ifoldM' :: (V.Unbox b, Monad m) => (a -> Int -> b -> m a) -> a -> NonEmptyUVector b -> m a+ifoldM' f a = V.ifoldM' f a . _neUvec+{-# INLINE ifoldM' #-}++-- | /O(n)/ Monadic semigroupal fold+--+fold1M :: (V.Unbox a, Monad m) => (a -> a -> m a) -> NonEmptyUVector a -> m a+fold1M f = V.fold1M f . _neUvec+{-# INLINE fold1M #-}++-- | /O(n)/ Strict monadic semigroupal fold+--+fold1M' :: (V.Unbox a, Monad m) => (a -> a -> m a) -> NonEmptyUVector a -> m a+fold1M' f = V.fold1M' f . _neUvec+{-# INLINE fold1M' #-}++-- | /O(n)/ Monadic fold that discards the result+--+foldM_ :: (V.Unbox b, Monad m) => (a -> b -> m a) -> a -> NonEmptyUVector b -> m ()+foldM_ f a = V.foldM_ f a . _neUvec+{-# INLINE foldM_ #-}++-- | /O(n)/ Monadic fold that discards the result (action applied to each+-- element and its index)+--+ifoldM_ :: (V.Unbox b, Monad m) => (a -> Int -> b -> m a) -> a -> NonEmptyUVector b -> m ()+ifoldM_ f a = V.ifoldM_ f a . _neUvec+{-# INLINE ifoldM_ #-}++-- | /O(n)/ Strict monadic fold that discards the result+--+foldM'_ :: (V.Unbox b, Monad m) => (a -> b -> m a) -> a -> NonEmptyUVector b -> m ()+foldM'_ f a = V.foldM'_ f a . _neUvec+{-# INLINE foldM'_ #-}++-- | /O(n)/ Strict monadic fold that discards the result (action applied to each+-- element and its index)+--+ifoldM'_ :: (V.Unbox b, Monad m) => (a -> Int -> b -> m a) -> a -> NonEmptyUVector b -> m ()+ifoldM'_ f a = V.ifoldM'_ f a . _neUvec+{-# INLINE ifoldM'_ #-}++-- | /O(n)/ Monadic semigroupal fold that discards the result+--+fold1M_ :: (V.Unbox a, Monad m) => (a -> a -> m a) -> NonEmptyUVector a -> m ()+fold1M_ f = V.fold1M_ f . _neUvec+{-# INLINE fold1M_ #-}++-- | /O(n)/ Strict monadic semigroupal fold that discards the result+--+fold1M'_ :: (V.Unbox a, Monad m) => (a -> a -> m a) -> NonEmptyUVector a -> m ()+fold1M'_ f = V.fold1M'_ f . _neUvec+{-# INLINE fold1M'_ #-}++-- ---------------------------------------------------------------------- --+-- Prefix sums (scans)++-- | /O(n)/ Prescan+--+prescanl :: (V.Unbox a, V.Unbox b) => (a -> b -> a) -> a -> NonEmptyUVector b -> NonEmptyUVector a+prescanl f a = NonEmptyUVector . V.prescanl f a . _neUvec+{-# INLINE prescanl #-}++-- | /O(n)/ Prescan with strict accumulator+--+prescanl' :: (V.Unbox a, V.Unbox b) => (a -> b -> a) -> a -> NonEmptyUVector b -> NonEmptyUVector a+prescanl' f a = NonEmptyUVector . V.prescanl' f a . _neUvec+{-# INLINE prescanl' #-}++-- | /O(n)/ Scan+--+postscanl :: (V.Unbox a, V.Unbox b) => (a -> b -> a) -> a -> NonEmptyUVector b -> NonEmptyUVector a+postscanl f a = NonEmptyUVector . V.postscanl f a . _neUvec+{-# INLINE postscanl #-}++-- | /O(n)/ Scan with a strict accumulator+--+postscanl' :: (V.Unbox a, V.Unbox b) => (a -> b -> a) -> a -> NonEmptyUVector b -> NonEmptyUVector a+postscanl' f a = NonEmptyUVector . V.postscanl' f a . _neUvec+{-# INLINE postscanl' #-}++-- | /O(n)/ Haskell-style scan+--+scanl :: (V.Unbox a, V.Unbox b) => (a -> b -> a) -> a -> NonEmptyUVector b -> NonEmptyUVector a+scanl f a = NonEmptyUVector . V.scanl f a . _neUvec+{-# INLINE scanl #-}++-- | /O(n)/ Haskell-style scan with strict accumulator+--+scanl' :: (V.Unbox a, V.Unbox b) => (a -> b -> a) -> a -> NonEmptyUVector b -> NonEmptyUVector a+scanl' f a = NonEmptyUVector . V.scanl' f a . _neUvec+{-# INLINE scanl' #-}++-- | /O(n)/ Semigroupal left scan+--+scanl1 :: V.Unbox a => (a -> a -> a) -> NonEmptyUVector a -> NonEmptyUVector a+scanl1 f = NonEmptyUVector . V.scanl1 f . _neUvec+{-# INLINE scanl1 #-}++-- | /O(n)/ Strict semigroupal scan+--+scanl1' :: V.Unbox a => (a -> a -> a) -> NonEmptyUVector a -> NonEmptyUVector a+scanl1' f = NonEmptyUVector . V.scanl1' f . _neUvec+{-# INLINE scanl1' #-}++-- | /O(n)/ Scan over a vector with its index+--+iscanl :: (V.Unbox a, V.Unbox b) => (Int -> a -> b -> a) -> a -> NonEmptyUVector b -> NonEmptyUVector a+iscanl f a = NonEmptyUVector . V.iscanl f a . _neUvec+{-# INLINE iscanl #-}++-- | /O(n)/ Scan over a vector with its index with strict accumulator+--+iscanl' :: (V.Unbox a, V.Unbox b) => (Int -> a -> b -> a) -> a -> NonEmptyUVector b -> NonEmptyUVector a+iscanl' f a = NonEmptyUVector . V.iscanl' f a . _neUvec+{-# INLINE iscanl' #-}++-- | /O(n)/ Right-to-left prescan+--+prescanr :: (V.Unbox a, V.Unbox b) => (a -> b -> b) -> b -> NonEmptyUVector a -> NonEmptyUVector b+prescanr f b = NonEmptyUVector . V.prescanr f b . _neUvec+{-# INLINE prescanr #-}++-- | /O(n)/ Right-to-left prescan with strict accumulator+--+prescanr' :: (V.Unbox a, V.Unbox b) => (a -> b -> b) -> b -> NonEmptyUVector a -> NonEmptyUVector b+prescanr' f b = NonEmptyUVector . V.prescanr' f b . _neUvec+{-# INLINE prescanr' #-}++-- | /O(n)/ Right-to-left scan+--+postscanr :: (V.Unbox a, V.Unbox b) => (a -> b -> b) -> b -> NonEmptyUVector a -> NonEmptyUVector b+postscanr f b = NonEmptyUVector . V.postscanr f b . _neUvec+{-# INLINE postscanr #-}++-- | /O(n)/ Right-to-left scan with strict accumulator+--+postscanr' :: (V.Unbox a, V.Unbox b) => (a -> b -> b) -> b -> NonEmptyUVector a -> NonEmptyUVector b+postscanr' f b = NonEmptyUVector . V.postscanr' f b . _neUvec+{-# INLINE postscanr' #-}++-- | /O(n)/ Right-to-left Haskell-style scan+--+scanr :: (V.Unbox a, V.Unbox b) => (a -> b -> b) -> b -> NonEmptyUVector a -> NonEmptyUVector b+scanr f b = NonEmptyUVector . V.scanr f b . _neUvec+{-# INLINE scanr #-}++-- | /O(n)/ Right-to-left Haskell-style scan with strict accumulator+--+scanr' :: (V.Unbox a, V.Unbox b) => (a -> b -> b) -> b -> NonEmptyUVector a -> NonEmptyUVector b+scanr' f b = NonEmptyUVector . V.scanr' f b . _neUvec+{-# INLINE scanr' #-}++-- | /O(n)/ Right-to-left Haskell-style semigroupal scan+--+scanr1 :: V.Unbox a => (a -> a -> a) -> NonEmptyUVector a -> NonEmptyUVector a+scanr1 f = NonEmptyUVector . V.scanr1 f . _neUvec+{-# INLINE scanr1 #-}++-- | /O(n)/ Right-to-left Haskell-style semigroupal scan with strict accumulator+--+scanr1' :: V.Unbox a => (a -> a -> a) -> NonEmptyUVector a -> NonEmptyUVector a+scanr1' f = NonEmptyUVector . V.scanr1' f . _neUvec+{-# INLINE scanr1' #-}++-- | /O(n)/ Right-to-left scan over a vector with its index+--+iscanr :: (V.Unbox a, V.Unbox b) => (Int -> a -> b -> b) -> b -> NonEmptyUVector a -> NonEmptyUVector b+iscanr f b = NonEmptyUVector . V.iscanr f b . _neUvec+{-# INLINE iscanr #-}++-- | /O(n)/ Right-to-left scan over a vector with its index and a strict+-- accumulator+--+iscanr' :: (V.Unbox a, V.Unbox b) => (Int -> a -> b -> b) -> b -> NonEmptyUVector a -> NonEmptyUVector b+iscanr' f b = NonEmptyUVector . V.iscanr' f b . _neUvec+{-# INLINE iscanr' #-}++-- | /O(n)/ The 'intersperse' function takes an element and a 'NonEmptyUVector'+-- and "intersperses" that element between the elements of the 'NonEmptyUVector'.+--+-- >>> intersperse 0 (unsafeFromList [1,2,3])+-- [1,0,2,0,3]+--+-- >>> intersperse 0 (singleton 1)+-- [1]+--+intersperse :: forall (a :: Type) . V.Unbox a => a -> NonEmptyUVector a -> NonEmptyUVector a+intersperse sep nev@(NonEmptyUVector v)+    | V.length v <= 1 = nev+    | otherwise = unsafeCreate $ do+        let n = V.length v+        let newLen = 2*n - 1+        mv <- V.unsafeThaw $ V.replicate newLen (V.unsafeHead v)  -- Create mutable vector++        -- Fill the first element+        unsafeWrite mv 0 (V.unsafeIndex v 0)++        -- Fill remaining elements with separators+        let go i j+              | j >= n    = pure ()+              | otherwise = do+                  unsafeWrite mv i sep+                  unsafeWrite mv (i+1) (V.unsafeIndex v j)+                  go (i+2) (j+1)++        go 1 1+        pure mv+{-# INLINE intersperse #-}++-- | /O(n)/ Split a vector into a list of slices of the input vector.+--+-- The concatenation of this list of slices is equal to the argument vector,+-- and each slice contains only equal elements. Returns nothing if no equal+-- elements are found.+--+-- This is the equivalent of 'groupBy (==)'.+--+-- >>> import qualified Data.NonEmptyUVector as NEV+-- >>> NEV.group (NEV.unsafeFromList "Mississippi")+-- "M" :| ["i","ss","i","ss","i","pp","i"]+--+-- See also 'Data.Vector.group'.+--+-- @since 1.0+--+group :: (V.Unbox a, Eq a) => NonEmptyUVector a -> NonEmpty (NonEmptyUVector a)+group = groupBy (==)++-- | /O(n)/ Split a vector into a list of slices.+--+--+-- The concatenation of this list of slices is equal to the argument vector,+-- and each slice contains only equal elements, as determined by the equality+-- predicate function.+--++-- >>> import qualified Data.NonEmptyUVector as NEV+-- >>> import Data.Char (isUpper)+-- >>> NEV.groupBy (\a b -> isUpper a == isUpper b) (NEV.unsafeFromList "Mississippi River")+-- "M" :| ["ississippi ","R","iver"]+--+-- See also 'Data.Vector.groupBy'.+--+-- @since 1.0+--+groupBy+    :: (Eq a, V.Unbox a)+    => (a -> a -> Bool)+    -> NonEmptyUVector a+    -> NonEmpty (NonEmptyUVector a)+groupBy f = go+  where+    go v =+      let+        h = head v+        t = NonEmptyUVector $ tail v+      in case findIndex (not . f h) t of+           Nothing -> v :| []+           Just n ->+             let+               z = NonEmptyUVector $ unsafeTake (n+1) v+               x = NonEmptyUVector $ unsafeDrop (n+1) v+             in z <| go x
+ src/Data/Vector/NonEmpty/Unboxed/Internal.hs view
@@ -0,0 +1,110 @@+{-# LANGUAGE CPP #-}+{-# LANGUAGE DeriveDataTypeable #-}+{-# LANGUAGE DerivingVia #-}+{-# LANGUAGE GeneralizedNewtypeDeriving #-}+{-# LANGUAGE LambdaCase #-}+{-# LANGUAGE StandaloneDeriving #-}+-- |+-- Module      : Data.Vector.NonEmpty.Unboxed.Internal+-- Copyright   : (c) 2019-2026 Emily Pillmore, Koz Ross+-- License     : BSD-style+--+-- Maintainer  : Emily Pillmore <emilypi@cohomolo.gy>+-- Stability   : experimental+-- Portability : non-portable+--+-- Internal module exposing the constructors for+-- t'NonEmptyUVector' and t'NonEmptyMUVector'.+--+-- /Warning/: Since the constructors are exposed here, by using this+-- module, you take on the risks that you break the non-emptiness+-- invariants of the main modules. Use at your own risk.+--+-- @since 1.0+--+module Data.Vector.NonEmpty.Unboxed.Internal+( -- * Immutable unboxed vectors+  NonEmptyUVector(..)+  -- * Mutable unboxed vectors+, NonEmptyMUVector(..)+  -- ** Mutable unboxed vector aliases+, NonEmptyIOUVector+, NonEmptySTUVector+) where+++import Control.DeepSeq (NFData)+import Control.Monad.ST++import Data.Data (Data)+import qualified Data.Vector.Unboxed as V+#if __GLASGOW_HASKELL__ < 912+import Data.Typeable (Typeable)+#endif+import Data.Vector.Unboxed.Mutable (MVector)++import qualified Text.Read as Read+++-- ---------------------------------------------------------------------- --+-- Non-empty immutable unboxed vectors++-- | t'NonEmptyUVector' is a thin wrapper around 'Data.Vector.Unboxed.Vector' that+-- witnesses an API requiring non-empty construction,+-- initialization, and generation of non-empty vectors by design.+--+-- A newtype wrapper was chosen so that no new pointer indirection+-- is introduced when working with 'Data.Vector.Unboxed.Vector's, and all performance+-- characteristics inherited from the "Data.Unboxed.Vector" API still apply.+--+-- @since 1.0+--+newtype NonEmptyUVector a = NonEmptyUVector+    { _neUvec :: V.Vector a+    } deriving+      ( Eq, Ord+      , Data, NFData+      , Semigroup+#if __GLASGOW_HASKELL__ < 912+      , Typeable+#endif+      ) ++deriving via (V.Vector a) instance (Show a, V.Unbox a) => +  Show (NonEmptyUVector a)++instance (V.Unbox a, Read a) => Read (NonEmptyUVector a) where+    readPrec = Read.readPrec >>= \case+      [] -> Read.pfail+      as -> return (NonEmptyUVector $ V.fromList as)++-- ---------------------------------------------------------------------- --+-- Non-empty unboxed mutable vectors++-- | t'NonEmptyMUVector' is a thin wrapper around 'MVector' that+-- witnesses an API requiring non-empty construction,+-- initialization, and generation of non-empty vectors by design.+--+-- A newtype wrapper was chosen so that no new pointer indirection+-- is introduced when working with 'MVector's, and all performance+-- characteristics inherited from the 'MVector' API still apply.+--+-- @since 1.0+--+newtype NonEmptyMUVector s a = NonEmptyMUVector+    { _nemUvec :: MVector s a }+#if __GLASGOW_HASKELL__ < 912+    deriving (Typeable)+#endif++-- | t'NonEmptyMUVector' parametrized by 'Control.Monad.Primitive.PrimState' 'IO'.+--+-- @since 1.0+--+type NonEmptyIOUVector = NonEmptyMUVector RealWorld++-- | t'NonEmptyMUVector' parametrized by @t'Control.Monad.Primitive.PrimState' ('ST' s)@.+--+-- @since 1.0+--+type NonEmptySTUVector s = NonEmptyMUVector s
+ src/Data/Vector/NonEmpty/Unboxed/Mutable.hs view
@@ -0,0 +1,452 @@+{-# LANGUAGE DeriveDataTypeable #-}+{-# LANGUAGE BangPatterns #-}+{-# LANGUAGE NoImplicitPrelude #-}+-- |+-- Module      : Data.Vector.NonEmpty.Unboxed.Mutable+-- Copyright   : (c) 2019-2026 Emily Pillmore, Koz Ross+-- License     : BSD-style+--+-- Maintainer  : Emily Pillmore <emilypi@cohomolo.gy>+-- Stability   : experimental+-- Portability : non-portable+--+-- Non-empty mutable unboxed vectors.+--+module Data.Vector.NonEmpty.Unboxed.Mutable+( -- * Mutable boxed vectors+  NonEmptyMUVector+, NonEmptyIOUVector+, NonEmptySTUVector++  -- * Accessors+  -- ** Length information+, length++  -- ** Extracting subvectors+, slice, init, tail, take, drop, splitAt+, unsafeSlice, unsafeTake, unsafeDrop++  -- ** Overlapping+, overlaps++  -- ** Conversions+, fromMVector, toMVector, unsafeFromMVector++  -- ** Initialisation+, new, new1, unsafeNew+, replicate, replicate1+, replicateM, replicate1M+, clone++  -- ** Growing+, grow, unsafeGrow++  -- ** Restricting memory usage+, clear++  -- * Accessing individual elements+, read, write, modify, swap+, unsafeRead, unsafeWrite, unsafeModify, unsafeSwap++  -- * Modifying vectors+, nextPermutation++  -- ** Filling and copying+, set, copy, move, unsafeCopy, unsafeMove+) where+++import Prelude (Bool, Int, Ord, (.), max)++import Control.Monad.Primitive++import Data.Functor+import Data.Maybe (Maybe(..))+import Data.Vector.Unboxed.Mutable (MVector)+import qualified Data.Vector.Unboxed.Mutable as M+import Data.Vector.NonEmpty.Unboxed.Internal+++-- ---------------------------------------------------------------------- --+-- Length information++-- | Length of the mutable vector.+length :: M.Unbox a => NonEmptyMUVector s a -> Int+length = M.length . _nemUvec+{-# INLINE length #-}++-- ---------------------------------------------------------------------- --+-- Extracting subvectors++-- | Yield a part of the mutable vector without copying.+--+slice :: M.Unbox a => Int -> Int -> NonEmptyMUVector s a -> MVector s a+slice n m = M.slice n m . _nemUvec+{-# INLINE slice #-}++-- | Yield at the first n elements without copying.+--+take :: M.Unbox a => Int -> NonEmptyMUVector s a -> MVector s a+take n = M.take n . _nemUvec+{-# INLINE take #-}++-- | Yield all but the first n elements without copying.+--+drop :: M.Unbox a => Int -> NonEmptyMUVector s a -> MVector s a+drop n = M.drop n . _nemUvec+{-# INLINE drop #-}++-- | Yield the first n elements paired with the remainder without copying.+--+splitAt :: M.Unbox a => Int -> NonEmptyMUVector s a -> (MVector s a, MVector s a)+splitAt n = M.splitAt n . _nemUvec+{-# INLINE splitAt #-}++-- | Yield all but the last element without copying.+--+init :: M.Unbox a => NonEmptyMUVector s a -> MVector s a+init = M.unsafeInit . _nemUvec+{-# INLINE init #-}++-- | Yield all but the first element without copying.+--+tail :: M.Unbox a => NonEmptyMUVector s a -> MVector s a+tail = M.unsafeTail . _nemUvec+{-# INLINE tail #-}++-- | Yield a part of the mutable vector without copying it. No bounds checks+-- are performed.+--+unsafeSlice+    :: M.Unbox a+    => Int+      -- ^ starting index+    -> Int+      -- ^ length of the slice+    -> NonEmptyMUVector s a+    -> MVector s a+unsafeSlice n m = M.unsafeSlice n m . _nemUvec+{-# INLINE unsafeSlice #-}++-- | Yield the first n elements without copying. The vector must contain at+-- least n elements but this is not checked.+--+unsafeTake :: M.Unbox a => Int -> NonEmptyMUVector s a -> MVector s a+unsafeTake n = M.unsafeTake n . _nemUvec+{-# INLINE unsafeTake #-}++-- | Yield all but the first n elements without copying. The vector must+-- contain at least n elements but this is not checked.+--+unsafeDrop :: M.Unbox a => Int -> NonEmptyMUVector s a -> MVector s a+unsafeDrop n = M.unsafeDrop n . _nemUvec+{-# INLINE unsafeDrop #-}++-- ---------------------------------------------------------------------- --+-- Overlapping++-- | Check whether two vectors overlap.+--+overlaps :: M.Unbox a => NonEmptyMUVector s a -> NonEmptyMUVector s a -> Bool+overlaps (NonEmptyMUVector v) (NonEmptyMUVector u) = M.overlaps v u+{-# INLINE overlaps #-}++-- ---------------------------------------------------------------------- --+-- Conversion++-- | Convert a mutable vector to a non-empty mutable vector+--+fromMVector :: M.Unbox a => MVector s a -> Maybe (NonEmptyMUVector s a)+fromMVector v = if M.null v then Nothing else Just (NonEmptyMUVector v)++-- | Convert a non-empty mutable vector to a mutable vector+--+toMVector :: M.Unbox a => NonEmptyMUVector s a -> MVector s a+toMVector = _nemUvec++-- | Convert a mutable vector to a non-empty mutable vector+--+-- /Warning:/ this function is unsafe and can result in empty non-empty+-- mutable vectors. If you call this function, the onus is on you to+-- make sure the mutable vector being converted is not empty.+--+unsafeFromMVector :: M.Unbox a => MVector s a -> NonEmptyMUVector s a+unsafeFromMVector = NonEmptyMUVector+{-# INLINE unsafeFromMVector #-}++-- ---------------------------------------------------------------------- --+-- Initialisation++-- | Create a mutable vector of the given length.+--+new+    :: (PrimMonad m, M.Unbox a)+    => Int+    -> m (Maybe (NonEmptyMUVector (PrimState m) a))+new = fmap fromMVector . M.new+{-# INLINE new #-}++-- | Create a mutable vector of the given length which is+-- @max n 1@.+--+new1+    :: (PrimMonad m, M.Unbox a)+    => Int+    -> m (NonEmptyMUVector (PrimState m) a)+new1 n = fmap unsafeFromMVector (M.new (max n 1))+{-# INLINE new1 #-}++-- | Create a mutable vector of the given length. The memory is not initialized.+--+unsafeNew+    :: (PrimMonad m, M.Unbox a)+    => Int+    -> m (Maybe (NonEmptyMUVector (PrimState m) a))+unsafeNew = fmap fromMVector . M.unsafeNew+{-# INLINE unsafeNew #-}++-- | Create a mutable vector of the given length (0 if the length is negative)+-- and fill it with an initial value.+--+replicate+    :: (PrimMonad m, M.Unbox a)+    => Int+    -> a+    -> m (Maybe (NonEmptyMUVector (PrimState m) a))+replicate n a = fmap fromMVector (M.replicate n a)+{-# INLINE replicate #-}++-- | Create a mutable vector of the length @max n 1@ for a given length,+-- and fill it with an initial value.+--+replicate1+    :: (PrimMonad m, M.Unbox a)+    => Int+    -> a+    -> m (NonEmptyMUVector (PrimState m) a)+replicate1 n a = fmap unsafeFromMVector (M.replicate (max n 1) a)+{-# INLINE replicate1 #-}++-- | Create a mutable vector of the given length (0 if the length is negative)+-- and fill it with values produced by repeatedly executing the monadic action.+--+replicateM+    :: (PrimMonad m, M.Unbox a)+    => Int+    -> m a+    -> m (Maybe (NonEmptyMUVector (PrimState m) a))+replicateM  n a = fmap fromMVector (M.replicateM n a)+{-# INLINE replicateM #-}++-- | Create a mutable vector of the length @max n 1@ for a given length,+-- and fill it with values produced by repeatedly executing the monadic action.+--+replicate1M+    :: (PrimMonad m, M.Unbox a)+    => Int+    -> m a+    -> m (Maybe (NonEmptyMUVector (PrimState m) a))+replicate1M n a = fmap fromMVector (M.replicateM (max n 1) a)+{-# INLINE replicate1M #-}++-- | Create a copy of a mutable vector.+--+clone+    :: (PrimMonad m, M.Unbox a)+    => NonEmptyMUVector (PrimState m) a+    -> m (NonEmptyMUVector (PrimState m) a)+clone (NonEmptyMUVector v) = fmap NonEmptyMUVector (M.clone v)+{-# INLINE clone #-}++-- ---------------------------------------------------------------------- --+-- Growing++-- | Grow a vector by the given number of elements. The number must be+-- positive.+--+grow+    :: (PrimMonad m, M.Unbox a)+    => NonEmptyMUVector (PrimState m) a+    -> Int+    -> m (NonEmptyMUVector (PrimState m) a)+grow (NonEmptyMUVector v) n = fmap NonEmptyMUVector (M.grow v n)+{-# INLINE grow #-}++-- | Grow a vector by the given number of elements. The number must be+-- positive but this is not checked.+unsafeGrow+    :: (PrimMonad m, M.Unbox a)+    => NonEmptyMUVector (PrimState m) a+    -> Int+    -> m (NonEmptyMUVector (PrimState m) a)+unsafeGrow (NonEmptyMUVector v) n = fmap NonEmptyMUVector (M.unsafeGrow v n)+{-# INLINE unsafeGrow #-}++-- ---------------------------------------------------------------------- --+-- Restricting memory usage++-- | Reset all elements of the vector to some undefined value, clearing all+-- references to external objects. This is usually a noop for unboxed vectors.+clear :: (PrimMonad m, M.Unbox a) => NonEmptyMUVector (PrimState m) a -> m ()+clear = M.clear . _nemUvec+{-# INLINE clear #-}++-- ---------------------------------------------------------------------- --+-- Accessing individual elements++-- | Yield the element at the given position.+--+read+    :: (PrimMonad m, M.Unbox a)+    => NonEmptyMUVector (PrimState m) a+    -> Int+    -> m a+read (NonEmptyMUVector v) n = M.read v n+{-# INLINE read #-}++-- | Replace the element at the given position.+--+write+    :: (PrimMonad m, M.Unbox a)+    => NonEmptyMUVector (PrimState m) a+    -> Int+    -> a+    -> m ()+write (NonEmptyMUVector v) n a = M.write v n a+{-# INLINE write #-}++-- | Modify the element at the given position.+--+modify+    :: (PrimMonad m, M.Unbox a)+    => NonEmptyMUVector (PrimState m) a+    -> (a -> a)+    -> Int+    -> m ()+modify (NonEmptyMUVector v) f n = M.modify v f n+{-# INLINE modify #-}++-- | Swap the elements at the given positions.+--+swap+    :: (PrimMonad m, M.Unbox a)+    => NonEmptyMUVector (PrimState m) a+    -> Int+    -> Int+    -> m ()+swap (NonEmptyMUVector v) n m = M.swap v n m+{-# INLINE swap #-}++-- | Yield the element at the given position. No bounds checks are performed.+--+unsafeRead+    :: (PrimMonad m, M.Unbox a)+    => NonEmptyMUVector (PrimState m) a+    -> Int+    -> m a+unsafeRead (NonEmptyMUVector v) n = M.unsafeRead v n+{-# INLINE unsafeRead #-}++-- | Replace the element at the given position. No bounds checks are performed.+--+unsafeWrite+    :: (PrimMonad m, M.Unbox a)+    => NonEmptyMUVector (PrimState m) a+    -> Int+    -> a+    -> m ()+unsafeWrite (NonEmptyMUVector v) n a = M.unsafeWrite v n a+{-# INLINE unsafeWrite #-}++-- | Modify the element at the given position. No bounds checks are performed.+--+unsafeModify+    :: (PrimMonad m, M.Unbox a)+    => NonEmptyMUVector (PrimState m) a+    -> (a -> a)+    -> Int+    -> m ()+unsafeModify (NonEmptyMUVector v) f n = M.unsafeModify v f n+{-# INLINE unsafeModify #-}++-- | Swap the elements at the given positions. No bounds checks are performed.+--+unsafeSwap :: (PrimMonad m, M.Unbox a) => NonEmptyMUVector (PrimState m) a -> Int -> Int -> m ()+unsafeSwap (NonEmptyMUVector v) n m = M.unsafeSwap v n m+{-# INLINE unsafeSwap #-}++-- ---------------------------------------------------------------------- --+-- Filling and copying++-- | Set all elements of the vector to the given value.+--+set :: (PrimMonad m, M.Unbox a) => NonEmptyMUVector (PrimState m) a -> a -> m ()+set (NonEmptyMUVector v) a = M.set v a+{-# INLINE set #-}++-- | Copy a vector. The two vectors must have the same length and may not+-- overlap.+--+copy+    :: (PrimMonad m, M.Unbox a)+    => NonEmptyMUVector (PrimState m) a+    -> NonEmptyMUVector (PrimState m) a+    -> m ()+copy (NonEmptyMUVector v) (NonEmptyMUVector v') = M.copy v v'+{-# INLINE copy #-}++-- | Copy a vector. The two vectors must have the same length and may not+-- overlap. This is not checked.+--+unsafeCopy+    :: (PrimMonad m, M.Unbox a)+    => NonEmptyMUVector (PrimState m) a+      -- ^ target+    -> NonEmptyMUVector (PrimState m) a+      -- ^ source+    -> m ()+unsafeCopy (NonEmptyMUVector v) (NonEmptyMUVector v') = M.unsafeCopy v v'+{-# INLINE unsafeCopy #-}++-- | Move the contents of a vector. The two vectors must have the same+-- length.+--+-- If the vectors do not overlap, then this is equivalent to 'copy'.+-- Otherwise, the copying is performed as if the source vector were+-- copied to a temporary vector and then the temporary vector was copied+-- to the target vector.+--+move+    :: (PrimMonad m, M.Unbox a)+    => NonEmptyMUVector (PrimState m) a+    -> NonEmptyMUVector (PrimState m) a -> m ()+move (NonEmptyMUVector v) (NonEmptyMUVector v') = M.move v v'+{-# INLINE move #-}++-- | Move the contents of a vector. The two vectors must have the same+-- length, but this is not checked.+--+-- If the vectors do not overlap, then this is equivalent to 'unsafeCopy'.+-- Otherwise, the copying is performed as if the source vector were+-- copied to a temporary vector and then the temporary vector was copied+-- to the target vector.+--+unsafeMove+    :: (PrimMonad m, M.Unbox a)+    => NonEmptyMUVector (PrimState m) a+      -- ^ target+    -> NonEmptyMUVector (PrimState m) a+      -- ^ source+    -> m ()+unsafeMove (NonEmptyMUVector v) (NonEmptyMUVector v') = M.unsafeMove v v'+{-# INLINE unsafeMove #-}++-- | Compute the next (lexicographically) permutation of given vector in-place.+--   Returns False when input is the last permtuation+--+nextPermutation+    :: (PrimMonad m,Ord e, M.Unbox e)+    => NonEmptyMUVector (PrimState m) e+    -> m Bool+nextPermutation = M.nextPermutation . _nemUvec+{-# INLINE nextPermutation #-}
test/Main.hs view
@@ -1,6 +1,6 @@ -- | -- Module       : Main (tests)--- Copyright 	: (c) 2019-2026 Emily Pillmore+-- Copyright 	: (c) 2019-2026 Emily Pillmore, Koz Ross -- License	: BSD -- Maintainer   : Emily Pillmore <emilypi@cohomolo.gy> -- Stability    : Experimental@@ -12,16 +12,27 @@   import qualified Test.Data.Vector.NonEmpty.Accessors as Accessors+import qualified Test.Data.Vector.NonEmpty.AccessorsU as AccessorsU import qualified Test.Data.Vector.NonEmpty.Construction as Construction+import qualified Test.Data.Vector.NonEmpty.ConstructionU as ConstructionU import qualified Test.Data.Vector.NonEmpty.Conversion as Conversion+import qualified Test.Data.Vector.NonEmpty.ConversionU as ConversionU import qualified Test.Data.Vector.NonEmpty.Elementwise as Elementwise+import qualified Test.Data.Vector.NonEmpty.ElementwiseU as ElementwiseU import qualified Test.Data.Vector.NonEmpty.Folds as Folds+import qualified Test.Data.Vector.NonEmpty.FoldsU as FoldsU import qualified Test.Data.Vector.NonEmpty.Grouping as Grouping+import qualified Test.Data.Vector.NonEmpty.GroupingU as GroupingU import qualified Test.Data.Vector.NonEmpty.Instances as Instances+import qualified Test.Data.Vector.NonEmpty.InstancesU as InstancesU import qualified Test.Data.Vector.NonEmpty.Modification as Modification+import qualified Test.Data.Vector.NonEmpty.ModificationU as ModificationU import qualified Test.Data.Vector.NonEmpty.Mutable as Mutable+import qualified Test.Data.Vector.NonEmpty.MutableU as MutableU import qualified Test.Data.Vector.NonEmpty.Predicates as Predicates+import qualified Test.Data.Vector.NonEmpty.PredicatesU as PredicatesU import qualified Test.Data.Vector.NonEmpty.Scans as Scans+import qualified Test.Data.Vector.NonEmpty.ScansU as ScansU  import Test.Tasty @@ -29,14 +40,25 @@ main :: IO () main = defaultMain $ testGroup "NonEmptyVector tests"     [ Accessors.tests+    , AccessorsU.tests     , Construction.tests+    , ConstructionU.tests     , Conversion.tests+    , ConversionU.tests     , Modification.tests+    , ModificationU.tests     , Elementwise.tests+    , ElementwiseU.tests     , Predicates.tests+    , PredicatesU.tests     , Grouping.tests+    , GroupingU.tests     , Folds.tests+    , FoldsU.tests     , Scans.tests+    , ScansU.tests     , Instances.tests+    , InstancesU.tests     , Mutable.tests+    , MutableU.tests     ]
+ test/Test/Data/Vector/NonEmpty/AccessorsU.hs view
@@ -0,0 +1,181 @@+-- |+-- Module      : Test.Data.Vector.NonEmpty.AccessorsU+-- Copyright   : (c) 2019-2026 Emily Pillmore, Koz Ross+-- License     : BSD-style+--+-- Maintainer  : Emily Pillmore <emilypi@cohomolo.gy>+-- Stability   : experimental+-- Portability : non-portable+--+-- Properties for length information, indexing, and slicing.+--+module Test.Data.Vector.NonEmpty.AccessorsU+( tests+) where+++import Data.Functor.Identity (Identity(..))+import qualified Data.List as List+import qualified Data.Vector.Unboxed as V+import Data.Vector.NonEmpty.Unboxed (NonEmptyUVector)+import qualified Data.Vector.NonEmpty.Unboxed as NEV++import Test.Data.Vector.NonEmpty.Util+import Test.QuickCheck+import Test.Tasty+import Test.Tasty.QuickCheck+++tests :: TestTree+tests = testGroup "Accessors (unboxed)"+    [ testGroup "Length information"+      [ testProperty "prop_length" prop_length+      ]+    , testGroup "Indexing"+      [ testProperty "prop_head" prop_head+      , testProperty "prop_last" prop_last+      , testProperty "prop_index" prop_index+      , testProperty "prop_index_out_of_bounds" prop_index_out_of_bounds+      , testProperty "prop_index_maybe" prop_index_maybe+      , testProperty "prop_unsafeIndex" prop_unsafeIndex+      ]+    , testGroup "Monadic indexing"+      [ testProperty "prop_headM" prop_headM+      , testProperty "prop_lastM" prop_lastM+      , testProperty "prop_indexM" prop_indexM+      , testProperty "prop_indexM_out_of_bounds" prop_indexM_out_of_bounds+      , testProperty "prop_unsafeIndexM" prop_unsafeIndexM+      ]+    , testGroup "Slicing"+      [ testProperty "prop_tail" prop_tail+      , testProperty "prop_init" prop_init+      , testProperty "prop_uncons" prop_uncons+      , testProperty "prop_unsnoc" prop_unsnoc+      , testProperty "prop_slice" prop_slice+      , testProperty "prop_slice_out_of_bounds" prop_slice_out_of_bounds+      , testProperty "prop_take" prop_take+      , testProperty "prop_drop" prop_drop+      , testProperty "prop_splitAt" prop_splitAt+      , testProperty "prop_unsafeSlice" prop_unsafeSlice+      , testProperty "prop_unsafeTake" prop_unsafeTake+      , testProperty "prop_unsafeDrop" prop_unsafeDrop+      ]+    ]++-- ---------------------------------------------------------------------- --+-- Length information++prop_length :: NonEmptyUVector Int -> Property+prop_length v = NEV.length v === List.length (elemsU v)++-- ---------------------------------------------------------------------- --+-- Indexing++prop_head :: NonEmptyUVector Int -> Property+prop_head v = [NEV.head v] === List.take 1 (elemsU v)++prop_last :: NonEmptyUVector Int -> Property+prop_last v = [NEV.last v] === List.take 1 (List.reverse (elemsU v))++prop_index :: NonEmptyUVector Int -> Property+prop_index v = forAll (genIndexU v) $ \i ->+    Just (v NEV.! i) === lookupList i (elemsU v)++prop_index_out_of_bounds :: NonEmptyUVector Int -> Property+prop_index_out_of_bounds v = forAll (genOutOfBoundsU v) $ \i ->+    throws (v NEV.! i)++prop_index_maybe :: NonEmptyUVector Int -> Int -> Property+prop_index_maybe v i = v NEV.!? i === lookupList i (elemsU v)++prop_unsafeIndex :: NonEmptyUVector Int -> Property+prop_unsafeIndex v = forAll (genIndexU v) $ \i ->+    Just (NEV.unsafeIndex v i) === lookupList i (elemsU v)++-- ---------------------------------------------------------------------- --+-- Monadic indexing++prop_headM :: NonEmptyUVector Int -> Property+prop_headM v = [runIdentity (NEV.headM v)] === List.take 1 (elemsU v)++prop_lastM :: NonEmptyUVector Int -> Property+prop_lastM v =+    [runIdentity (NEV.lastM v)] === List.take 1 (List.reverse (elemsU v))++prop_indexM :: NonEmptyUVector Int -> Property+prop_indexM v = forAll (genIndexU v) $ \i ->+    Just (runIdentity (NEV.indexM v i)) === lookupList i (elemsU v)++prop_indexM_out_of_bounds :: NonEmptyUVector Int -> Property+prop_indexM_out_of_bounds v = forAll (genOutOfBoundsU v) $ \i ->+    throws (runIdentity (NEV.indexM v i))++prop_unsafeIndexM :: NonEmptyUVector Int -> Property+prop_unsafeIndexM v = forAll (genIndexU v) $ \i ->+    Just (runIdentity (NEV.unsafeIndexM v i)) === lookupList i (elemsU v)++-- ---------------------------------------------------------------------- --+-- Slicing++prop_tail :: NonEmptyUVector Int -> Property+prop_tail v = V.toList (NEV.tail v) === List.drop 1 (elemsU v)++prop_init :: NonEmptyUVector Int -> Property+prop_init v =+    V.toList (NEV.init v) === List.take (List.length as - 1) as+  where+    as = elemsU v++prop_uncons :: NonEmptyUVector Int -> Property+prop_uncons v = ([a], V.toList as) === List.splitAt 1 (elemsU v)+  where+    (a, as) = NEV.uncons v++prop_unsnoc :: NonEmptyUVector Int -> Property+prop_unsnoc v =+    (V.toList as, [a]) === List.splitAt (List.length (elemsU v) - 1) (elemsU v)+  where+    (as, a) = NEV.unsnoc v++prop_slice :: NonEmptyUVector Int -> Property+prop_slice v = forAll (genSliceU v) $ \(i, m) ->+    V.toList (NEV.slice i m v) === List.take m (List.drop i (elemsU v))++prop_slice_out_of_bounds :: NonEmptyUVector Int -> Property+prop_slice_out_of_bounds v = forAll genBadSlice $ \(i, m) ->+    throws (V.toList (NEV.slice i m v))+  where+    n = NEV.length v++    genBadSlice = oneof+      [ (,) <$> choose (-10, -1) <*> choose (0, n)+      , (,) <$> choose (0, n) <*> choose (-10, -1)+      , do+          i <- choose (0, n)+          m <- choose (n - i + 1, n - i + 10)+          pure (i, m)+      ]++prop_take :: Int -> NonEmptyUVector Int -> Property+prop_take n v = V.toList (NEV.take n v) === List.take n (elemsU v)++prop_drop :: Int -> NonEmptyUVector Int -> Property+prop_drop n v = V.toList (NEV.drop n v) === List.drop n (elemsU v)++prop_splitAt :: Int -> NonEmptyUVector Int -> Property+prop_splitAt n v =+    (V.toList as, V.toList bs) === List.splitAt n (elemsU v)+  where+    (as, bs) = NEV.splitAt n v++prop_unsafeSlice :: NonEmptyUVector Int -> Property+prop_unsafeSlice v = forAll (genSliceU v) $ \(i, m) ->+    V.toList (NEV.unsafeSlice i m v) === List.take m (List.drop i (elemsU v))++prop_unsafeTake :: NonEmptyUVector Int -> Property+prop_unsafeTake v = forAll (choose (0, NEV.length v)) $ \n ->+    V.toList (NEV.unsafeTake n v) === List.take n (elemsU v)++prop_unsafeDrop :: NonEmptyUVector Int -> Property+prop_unsafeDrop v = forAll (choose (0, NEV.length v)) $ \n ->+    V.toList (NEV.unsafeDrop n v) === List.drop n (elemsU v)
+ test/Test/Data/Vector/NonEmpty/ConstructionU.hs view
@@ -0,0 +1,316 @@+-- |+-- Module      : Test.Data.Vector.NonEmpty.Construction+-- Copyright   : (c) 2019-2026 Emily Pillmore, Koz Ross+-- License     : BSD-style+--+-- Maintainer  : Emily Pillmore <emilypi@cohomolo.gy>+-- Stability   : experimental+-- Portability : non-portable+--+-- Properties for initialization, unfolding, enumeration, and+-- concatenation.+--+-- The 'Maybe'-valued constructors must yield 'Nothing' exactly when the+-- result would be empty, and the @*1@ variants must clamp their size to at+-- least one.+--+module Test.Data.Vector.NonEmpty.ConstructionU+( tests+) where+++import qualified Data.List as List+import Data.List.NonEmpty (NonEmpty(..))+import qualified Data.Vector.Unboxed as V+import qualified Data.Vector.NonEmpty.Unboxed as NEV+import Data.Vector.NonEmpty.Unboxed.Internal (NonEmptyUVector(..))++import Test.Data.Vector.NonEmpty.Util+import Test.QuickCheck+import Test.Tasty+import Test.Tasty.QuickCheck+++tests :: TestTree+tests = testGroup "Construction (unboxed)"+    [ testGroup "Initialization"+      [ testProperty "prop_singleton" prop_singleton+      , testProperty "prop_replicate" prop_replicate+      , testProperty "prop_replicate1" prop_replicate1+      , testProperty "prop_generate" prop_generate+      , testProperty "prop_generate1" prop_generate1+      , testProperty "prop_iterateN" prop_iterateN+      , testProperty "prop_iterateN1" prop_iterateN1+      ]+    , testGroup "Monadic initialization"+      [ testProperty "prop_replicateM" prop_replicateM+      , testProperty "prop_replicate1M" prop_replicate1M+      , testProperty "prop_generateM" prop_generateM+      , testProperty "prop_generate1M" prop_generate1M+      , testProperty "prop_iterateNM" prop_iterateNM+      , testProperty "prop_iterateN1M" prop_iterateN1M+      , testProperty "prop_create" prop_create+      , testProperty "prop_unsafeCreate" prop_unsafeCreate+      , testProperty "prop_createT" prop_createT+      , testProperty "prop_unsafeCreateT" prop_unsafeCreateT+      ]+    , testGroup "Unfolding"+      [ testProperty "prop_unfoldr" prop_unfoldr+      , testProperty "prop_unfoldr1" prop_unfoldr1+      , testProperty "prop_unfoldrN" prop_unfoldrN+      , testProperty "prop_unfoldr1N" prop_unfoldr1N+      , testProperty "prop_unfoldrM" prop_unfoldrM+      , testProperty "prop_unfoldr1M" prop_unfoldr1M+      , testProperty "prop_unfoldrNM" prop_unfoldrNM+      , testProperty "prop_unfoldr1NM" prop_unfoldr1NM+      , testProperty "prop_constructN" prop_constructN+      , testProperty "prop_constructrN" prop_constructrN+      ]+    , testGroup "Enumeration"+      [ testProperty "prop_enumFromN" prop_enumFromN+      , testProperty "prop_enumFromN1" prop_enumFromN1+      , testProperty "prop_enumFromStepN" prop_enumFromStepN+      , testProperty "prop_enumFromStepN1" prop_enumFromStepN1+      , testProperty "prop_enumFromTo" prop_enumFromTo+      , testProperty "prop_enumFromThenTo" prop_enumFromThenTo+      ]+    , testGroup "Concatenation"+      [ testProperty "prop_cons" prop_cons+      , testProperty "prop_consV" prop_consV+      , testProperty "prop_snoc" prop_snoc+      , testProperty "prop_snocV" prop_snocV+      , testProperty "prop_append" prop_append+      , testProperty "prop_concat" prop_concat+      , testProperty "prop_concat1" prop_concat1+      ]+    , testGroup "Restricting memory usage"+      [ testProperty "prop_force" prop_force+      ]+    ]++-- ---------------------------------------------------------------------- --+-- Initialization++prop_singleton :: Int -> Property+prop_singleton a = elemsU (NEV.singleton a) === [a]++prop_replicate :: Int -> Int -> Property+prop_replicate n a =+    fmap elemsU (NEV.replicate n a) === whenNonEmpty (List.replicate n a)++prop_replicate1 :: Int -> Int -> Property+prop_replicate1 n a =+    elemsU (NEV.replicate1 n a) === List.replicate (max n 1) a++prop_generate :: Int -> Fun Int Int -> Property+prop_generate n (Fn f) =+    fmap elemsU (NEV.generate n f) === whenNonEmpty (fmap f [0 .. n - 1])++prop_generate1 :: Int -> Fun Int Int -> Property+prop_generate1 n (Fn f) =+    elemsU (NEV.generate1 n f) === fmap f [0 .. max n 1 - 1]++prop_iterateN :: Int -> Fun Int Int -> Int -> Property+prop_iterateN n (Fn f) a =+    fmap elemsU (NEV.iterateN n f a)+      === whenNonEmpty (List.take n (List.iterate f a))++prop_iterateN1 :: Int -> Fun Int Int -> Int -> Property+prop_iterateN1 n (Fn f) a =+    elemsU (NEV.iterateN1 n f a) === List.take (max n 1) (List.iterate f a)++-- ---------------------------------------------------------------------- --+-- Monadic initialization++prop_replicateM :: Int -> Int -> Property+prop_replicateM n a =+    fmap (fmap elemsU) (NEV.replicateM n (logged () a))+      === (List.replicate n (), whenNonEmpty (List.replicate n a))++prop_replicate1M :: Int -> Int -> Property+prop_replicate1M n a =+    fmap elemsU (NEV.replicate1M n (logged () a))+      === (List.replicate n' (), List.replicate n' a)+  where+    n' = max n 1++prop_generateM :: Int -> Fun Int Int -> Property+prop_generateM n (Fn f) =+    fmap (fmap elemsU) (NEV.generateM n (\i -> logged i (f i)))+      === (is, whenNonEmpty (fmap f is))+  where+    is = [0 .. n - 1]++prop_generate1M :: Int -> Fun Int Int -> Property+prop_generate1M n (Fn f) =+    fmap elemsU (NEV.generate1M n (\i -> logged i (f i)))+      === (is, fmap f is)+  where+    is = [0 .. max n 1 - 1]++-- The step function runs once per element after the seed.+prop_iterateNM :: Int -> Fun Int Int -> Int -> Property+prop_iterateNM n (Fn f) a =+    fmap (fmap elemsU) (NEV.iterateNM n (\b -> logged b (f b)) a)+      === (List.take (n - 1) as, whenNonEmpty (List.take n as))+  where+    as = List.iterate f a++prop_iterateN1M :: Int -> Fun Int Int -> Int -> Property+prop_iterateN1M n (Fn f) a =+    fmap elemsU (NEV.iterateN1M n (\b -> logged b (f b)) a)+      === (List.take (n' - 1) as, List.take n' as)+  where+    n' = max n 1+    as = List.iterate f a++prop_create :: [Int] -> Property+prop_create as =+    fmap elemsU (NEV.create (V.thaw (V.fromList as))) === whenNonEmpty as++prop_unsafeCreate :: NonEmptyUVector Int -> Property+prop_unsafeCreate v =+    elemsU (NEV.unsafeCreate (V.thaw (V.fromList (elemsU v)))) === elemsU v++prop_createT :: [[Int]] -> Property+prop_createT ass =+    fmap (fmap elemsU) (NEV.createT (traverse (V.thaw . V.fromList) ass))+      === fmap whenNonEmpty ass++prop_unsafeCreateT :: [NonEmptyUVector Int] -> Property+prop_unsafeCreateT vs =+    fmap elemsU (NEV.unsafeCreateT (traverse (V.thaw . V.fromList . elemsU) vs))+      === fmap elemsU vs++-- ---------------------------------------------------------------------- --+-- Unfolding++prop_unfoldr :: Fun Int Int -> Int -> Property+prop_unfoldr (Fn f) b =+    fmap elemsU (NEV.unfoldr (unfoldStep f) b)+      === whenNonEmpty (List.unfoldr (unfoldStep f) b)++prop_unfoldr1 :: Fun Int Int -> Int -> Int -> Property+prop_unfoldr1 (Fn f) a b =+    elemsU (NEV.unfoldr1 (unfoldStep f) a b)+      === a : List.unfoldr (unfoldStep f) b++prop_unfoldrN :: Int -> Fun Int Int -> Int -> Property+prop_unfoldrN n (Fn f) b =+    fmap elemsU (NEV.unfoldrN n (unfoldStep f) b)+      === whenNonEmpty (List.take n (List.unfoldr (unfoldStep f) b))++-- The initial element is supplied in addition to at most @n@ unfolded ones.+prop_unfoldr1N :: Int -> Fun Int Int -> Int -> Int -> Property+prop_unfoldr1N n (Fn f) a b =+    elemsU (NEV.unfoldr1N n (unfoldStep f) a b)+      === a : List.take n (List.unfoldr (unfoldStep f) b)++prop_unfoldrM :: Fun Int Int -> Int -> Property+prop_unfoldrM (Fn f) b =+    fmap (fmap elemsU) (NEV.unfoldrM step b)+      === fmap whenNonEmpty (unfoldrMList step b)+  where+    step s = logged s (unfoldStep f s)++prop_unfoldr1M :: Fun Int Int -> Int -> Int -> Property+prop_unfoldr1M (Fn f) a b =+    fmap elemsU (NEV.unfoldr1M step a b) === fmap (a :) (unfoldrMList step b)+  where+    step s = logged s (unfoldStep f s)++prop_unfoldrNM :: Int -> Fun Int Int -> Int -> Property+prop_unfoldrNM n (Fn f) b =+    fmap (fmap elemsU) (NEV.unfoldrNM n step b)+      === fmap whenNonEmpty (unfoldrNMList n step b)+  where+    step s = logged s (unfoldStep f s)++prop_unfoldr1NM :: Int -> Fun Int Int -> Int -> Int -> Property+prop_unfoldr1NM n (Fn f) a b =+    fmap elemsU (NEV.unfoldr1NM n step a b)+      === fmap (a :) (unfoldrNMList n step b)+  where+    step s = logged s (unfoldStep f s)++-- Each element is generated from the prefix constructed so far.+prop_constructN :: Fun [Int] Int -> Property+prop_constructN (Fn f) = forAll (choose (0, 30)) $ \n ->+    fmap elemsU (NEV.constructN n (f . V.toList))+      === whenNonEmpty (construct n [])+  where+    construct n acc+      | List.length acc >= n = acc+      | otherwise = construct n (acc ++ [f acc])++-- Each element is generated from the suffix constructed so far.+prop_constructrN :: Fun [Int] Int -> Property+prop_constructrN (Fn f) = forAll (choose (0, 30)) $ \n ->+    fmap elemsU (NEV.constructrN n (f . V.toList))+      === whenNonEmpty (construct n [])+  where+    construct n acc+      | List.length acc >= n = acc+      | otherwise = construct n (f acc : acc)++-- ---------------------------------------------------------------------- --+-- Enumeration++prop_enumFromN :: Int -> Int -> Property+prop_enumFromN a n =+    fmap elemsU (NEV.enumFromN a n) === whenNonEmpty (fmap (a +) [0 .. n - 1])++prop_enumFromN1 :: Int -> Int -> Property+prop_enumFromN1 a n =+    elemsU (NEV.enumFromN1 a n) === fmap (a +) [0 .. max n 1 - 1]++prop_enumFromStepN :: Int -> Int -> Int -> Property+prop_enumFromStepN a s n =+    fmap elemsU (NEV.enumFromStepN a s n)+      === whenNonEmpty [ a + s * i | i <- [0 .. n - 1] ]++prop_enumFromStepN1 :: Int -> Int -> Int -> Property+prop_enumFromStepN1 a s n =+    elemsU (NEV.enumFromStepN1 a s n) === [ a + s * i | i <- [0 .. max n 1 - 1] ]++prop_enumFromTo :: Int -> Int -> Property+prop_enumFromTo a b = fmap elemsU (NEV.enumFromTo a b) === whenNonEmpty [a .. b]++-- A zero step would enumerate forever.+prop_enumFromThenTo :: Int -> Int -> Int -> Property+prop_enumFromThenTo a b c = a /= b ==>+    fmap elemsU (NEV.enumFromThenTo a b c) === whenNonEmpty [a, b .. c]++-- ---------------------------------------------------------------------- --+-- Concatenation++prop_cons :: Int -> NonEmptyUVector Int -> Property+prop_cons a v = elemsU (NEV.cons a v) === a : elemsU v++prop_consV :: Int -> [Int] -> Property+prop_consV a as = elemsU (NEV.consV a (V.fromList as)) === a : as++prop_snoc :: NonEmptyUVector Int -> Int -> Property+prop_snoc v a = elemsU (NEV.snoc v a) === elemsU v ++ [a]++prop_snocV :: [Int] -> Int -> Property+prop_snocV as a = elemsU (NEV.snocV (V.fromList as) a) === as ++ [a]++prop_append :: NonEmptyUVector Int -> NonEmptyUVector Int -> Property+prop_append v w = elemsU (v NEV.++ w) === elemsU v ++ elemsU w++prop_concat :: [NonEmptyUVector Int] -> Property+prop_concat vs =+    fmap elemsU (NEV.concat vs) === whenNonEmpty (List.concatMap elemsU vs)++prop_concat1 :: NonEmptyUVector Int -> [NonEmptyUVector Int] -> Property+prop_concat1 v vs =+    elemsU (NEV.concat1 (v :| vs)) === List.concatMap elemsU (v : vs)++-- ---------------------------------------------------------------------- --+-- Restricting memory usage++prop_force :: NonEmptyUVector Int -> Property+prop_force v = forAll (genSliceU v) $ \(i, m) -> m > 0 ==>+    let w = NonEmptyUVector (V.slice i m (_neUvec v))+    in elemsU (NEV.force w) === List.take m (List.drop i (elemsU v))
+ test/Test/Data/Vector/NonEmpty/ConversionU.hs view
@@ -0,0 +1,115 @@+-- |+-- Module      : Test.Data.Vector.NonEmpty.ConversionU+-- Copyright   : (c) 2019-2026 Emily Pillmore, Koz Ross+-- License     : BSD-style+--+-- Maintainer  : Emily Pillmore <emilypi@cohomolo.gy>+-- Stability   : experimental+-- Portability : non-portable+--+-- Properties for conversions to and from non-empty lists, vectors, and+-- lists.+--+module Test.Data.Vector.NonEmpty.ConversionU+( tests+) where+++import qualified Data.List as List+import Data.List.NonEmpty (NonEmpty(..))+import qualified Data.Vector.Unboxed as V+import Data.Vector.NonEmpty.Unboxed (NonEmptyUVector)+import qualified Data.Vector.NonEmpty.Unboxed as NEV++import Test.Data.Vector.NonEmpty.Util+import Test.QuickCheck+import Test.Tasty+import Test.Tasty.QuickCheck+++tests :: TestTree+tests = testGroup "Conversion"+    [ testGroup "To/from non-empty lists"+      [ testProperty "prop_toNonEmpty" prop_toNonEmpty+      , testProperty "prop_fromNonEmpty" prop_fromNonEmpty+      , testProperty "prop_from_to_nonempty" prop_from_to_nonempty+      , testProperty "prop_fromNonEmptyN" prop_fromNonEmptyN+      , testProperty "prop_fromNonEmptyN1" prop_fromNonEmptyN1+      , testProperty "prop_unsafeFromList" prop_unsafeFromList+      ]+    , testGroup "To/from vector"+      [ testProperty "prop_toVector" prop_toVector+      , testProperty "prop_fromVector" prop_fromVector+      , testProperty "prop_unsafeFromVector" prop_unsafeFromVector+      , testProperty "prop_from_to_vec" prop_from_to_vec+      ]+    , testGroup "To/from list"+      [ testProperty "prop_toList" prop_toList+      , testProperty "prop_fromList" prop_fromList+      , testProperty "prop_fromListN" prop_fromListN+      , testProperty "prop_from_to_list" prop_from_to_list+      ]+    ]++-- ---------------------------------------------------------------------- --+-- To/from non-empty lists++prop_toNonEmpty :: NonEmptyUVector Int -> Property+prop_toNonEmpty v = NEV.toNonEmpty v === elems1U v++prop_fromNonEmpty :: Int -> [Int] -> Property+prop_fromNonEmpty a as = elemsU (NEV.fromNonEmpty (a :| as)) === a : as++prop_from_to_nonempty :: NonEmptyUVector Int -> Property+prop_from_to_nonempty v = NEV.fromNonEmpty (NEV.toNonEmpty v) === v++prop_fromNonEmptyN :: Int -> Int -> [Int] -> Property+prop_fromNonEmptyN n a as =+    fmap elemsU (NEV.fromNonEmptyN n (a :| as))+      === whenNonEmpty (List.take n (a : as))++prop_fromNonEmptyN1 :: Int -> Int -> [Int] -> Property+prop_fromNonEmptyN1 n a as =+    elemsU (NEV.fromNonEmptyN1 n (a :| as)) === List.take (max n 1) (a : as)++prop_unsafeFromList :: NonEmptyList Int -> Property+prop_unsafeFromList (NonEmpty as) = elemsU (NEV.unsafeFromList as) === as++-- ---------------------------------------------------------------------- --+-- To/from vector++prop_toVector :: NonEmptyUVector Int -> Property+prop_toVector v = V.toList (NEV.toVector v) === elemsU v++prop_fromVector :: [Int] -> Property+prop_fromVector as =+    fmap elemsU (NEV.fromVector (V.fromList as)) === whenNonEmpty as++prop_unsafeFromVector :: NonEmptyList Int -> Property+prop_unsafeFromVector (NonEmpty as) =+    elemsU (NEV.unsafeFromVector (V.fromList as)) === as++prop_from_to_vec :: NonEmptyUVector Int -> NonEmptyList Int -> Property+prop_from_to_vec t (NonEmpty as) =+    NEV.fromVector (NEV.toVector t) === Just t+      .&&. (NEV.toVector <$> NEV.fromVector u) === Just u+  where+    u = V.fromList as++-- ---------------------------------------------------------------------- --+-- To/from list++prop_toList :: NonEmptyUVector Int -> Property+prop_toList v = NEV.toList v === elemsU v++prop_fromList :: [Int] -> Property+prop_fromList as = fmap elemsU (NEV.fromList as) === whenNonEmpty as++prop_fromListN :: Int -> [Int] -> Property+prop_fromListN n as =+    fmap elemsU (NEV.fromListN n as) === whenNonEmpty (List.take n as)++prop_from_to_list :: NonEmptyUVector Int -> NonEmptyList Int -> Property+prop_from_to_list t (NonEmpty u) =+    NEV.fromList (NEV.toList t) === Just t+      .&&. fmap NEV.toList (NEV.fromList u) === Just u
+ test/Test/Data/Vector/NonEmpty/ElementwiseU.hs view
@@ -0,0 +1,288 @@+-- |+-- Module      : Test.Data.Vector.NonEmpty.ElementwiseU+-- Copyright   : (c) 2019-2026 Emily Pillmore, Koz Ross+-- License     : BSD-style+--+-- Maintainer  : Emily Pillmore <emilypi@cohomolo.gy>+-- Stability   : experimental+-- Portability : non-portable+--+-- Properties for indexing, mapping, zipping, and unzipping.+--+-- Monadic operations run in a writer-style @([w], -)@ monad so that the+-- order and number of effects are observable.+--+module Test.Data.Vector.NonEmpty.ElementwiseU+( tests+) where+++import qualified Data.List as List+import Data.Vector.NonEmpty.Unboxed (NonEmptyUVector)+import qualified Data.Vector.NonEmpty.Unboxed as NEV++import Test.Data.Vector.NonEmpty.Util+import Test.QuickCheck+import Test.Tasty+import Test.Tasty.QuickCheck+++tests :: TestTree+tests = testGroup "Elementwise"+    [ testGroup "Indexing"+      [ testProperty "prop_indexed" prop_indexed+      ]+    , testGroup "Mapping"+      [ testProperty "prop_map" prop_map+      , testProperty "prop_imap" prop_imap+      , testProperty "prop_concatMap" prop_concatMap+      ]+    , testGroup "Monadic mapping"+      [ testProperty "prop_mapM" prop_mapM+      , testProperty "prop_imapM" prop_imapM+      , testProperty "prop_mapM_" prop_mapM_+      , testProperty "prop_imapM_" prop_imapM_+      , testProperty "prop_forM" prop_forM+      , testProperty "prop_forM_" prop_forM_+      ]+    , testGroup "Zipping"+      [ testProperty "prop_zipWith" prop_zipWith+      , testProperty "prop_zipWith3" prop_zipWith3+      {-+      , testProperty "prop_zipWith4" prop_zipWith4+      , testProperty "prop_zipWith5" prop_zipWith5+      , testProperty "prop_zipWith6" prop_zipWith6+      , testProperty "prop_izipWith" prop_izipWith+      , testProperty "prop_izipWith3" prop_izipWith3+      , testProperty "prop_izipWith4" prop_izipWith4+      , testProperty "prop_izipWith5" prop_izipWith5+      , testProperty "prop_izipWith6" prop_izipWith6+      -}+      , testProperty "prop_zip" prop_zip+      , testProperty "prop_zip3" prop_zip3+      , testProperty "prop_zip4" prop_zip4+      , testProperty "prop_zip5" prop_zip5+      , testProperty "prop_zip6" prop_zip6+      ]+    , testGroup "Monadic zipping"+      [ testProperty "prop_zipWithM" prop_zipWithM+      , testProperty "prop_zipWithM_" prop_zipWithM_+      , testProperty "prop_izipWithM" prop_izipWithM+      , testProperty "prop_izipWithM_" prop_izipWithM_+      ]+    , testGroup "Unzipping"+      [ testProperty "prop_unzip" prop_unzip+      , testProperty "prop_unzip3" prop_unzip3+      , testProperty "prop_unzip4" prop_unzip4+      , testProperty "prop_unzip5" prop_unzip5+      , testProperty "prop_unzip6" prop_unzip6+      ]+    ]++type V = NonEmptyUVector Int++-- ---------------------------------------------------------------------- --+-- Indexing++prop_indexed :: V -> Property+prop_indexed v = elemsU (NEV.indexed v) === List.zip [0 ..] (elemsU v)++-- ---------------------------------------------------------------------- --+-- Mapping++prop_map :: Fun Int Int -> V -> Property+prop_map (Fn f) v = elemsU (NEV.map f v) === List.map f (elemsU v)++prop_imap :: Fun (Int, Int) Int -> V -> Property+prop_imap (Fn2 f) v = elemsU (NEV.imap f v) === List.zipWith f [0 ..] (elemsU v)++prop_concatMap :: Fun Int V -> V -> Property+prop_concatMap (Fn f) v =+    elemsU (NEV.concatMap f v) === List.concatMap (elemsU . f) (elemsU v)++-- ---------------------------------------------------------------------- --+-- Monadic mapping++prop_mapM :: Fun Int Int -> V -> Property+prop_mapM (Fn f) v =+    fmap elemsU (NEV.mapM (\a -> logged a (f a)) v)+      === (elemsU v, List.map f (elemsU v))++prop_imapM :: Fun (Int, Int) Int -> V -> Property+prop_imapM (Fn2 f) v =+    fmap elemsU (NEV.imapM (\i a -> logged i (f i a)) v)+      === (is, List.zipWith f is (elemsU v))+  where+    is = [0 .. NEV.length v - 1]++prop_mapM_ :: V -> Property+prop_mapM_ v = NEV.mapM_ (\a -> logged a a) v === (elemsU v, ())++prop_imapM_ :: V -> Property+prop_imapM_ v =+    NEV.imapM_ (\i a -> logged (i, a) a) v+      === (List.zip [0 ..] (elemsU v), ())++prop_forM :: Fun Int Int -> V -> Property+prop_forM (Fn f) v =+    fmap elemsU (NEV.forM v (\a -> logged a (f a)))+      === (elemsU v, List.map f (elemsU v))++prop_forM_ :: V -> Property+prop_forM_ v = NEV.forM_ v (\a -> logged a a) === (elemsU v, ())++-- ---------------------------------------------------------------------- --+-- Zipping+--+-- The higher arities collect their arguments in order, so the models+-- detect both truncation to the shortest input and argument order.++prop_zipWith :: Fun (Int, Int) Int -> V -> V -> Property+prop_zipWith (Fn2 f) a b =+    elemsU (NEV.zipWith f a b) === List.zipWith f (elemsU a) (elemsU b)++prop_zipWith3 :: Fun (Int, Int, Int) Int -> V -> V -> V -> Property+prop_zipWith3 (Fn3 f) a b c =+    elemsU (NEV.zipWith3 f a b c)+      === List.zipWith3 f (elemsU a) (elemsU b) (elemsU c)++{-+prop_zipWith4 :: V -> V -> V -> V -> Property+prop_zipWith4 a b c d =+    elemsU (NEV.zipWith4 k a b c d)+      === List.zipWith4 k (elemsU a) (elemsU b) (elemsU c) (elemsU d)+  where+    k p q r s = [p, q, r, s]++prop_zipWith5 :: V -> V -> V -> V -> V -> Property+prop_zipWith5 a b c d e =+    elemsU (NEV.zipWith5 k a b c d e)+      === List.zipWith5 k (elemsU a) (elemsU b) (elemsU c) (elemsU d) (elemsU e)+  where+    k p q r s t = [p, q, r, s, t]++prop_zipWith6 :: V -> V -> V -> V -> V -> V -> Property+prop_zipWith6 a b c d e f =+    elemsU (NEV.zipWith6 k a b c d e f)+      === List.zipWith6 k+            (elemsU a) (elemsU b) (elemsU c) (elemsU d) (elemsU e) (elemsU f)+  where+    k p q r s t u = [p, q, r, s, t, u]++prop_izipWith :: V -> V -> Property+prop_izipWith a b =+    elemsU (NEV.izipWith k a b) === List.zipWith3 k [0 ..] (elemsU a) (elemsU b)+  where+    k i p q = [i, p, q]++prop_izipWith3 :: V -> V -> V -> Property+prop_izipWith3 a b c =+    elemsU (NEV.izipWith3 k a b c)+      === List.zipWith4 k [0 ..] (elemsU a) (elemsU b) (elemsU c)+  where+    k i p q r = [i, p, q, r]++prop_izipWith4 :: V -> V -> V -> V -> Property+prop_izipWith4 a b c d =+    elemsU (NEV.izipWith4 k a b c d)+      === List.zipWith5 k [0 ..] (elemsU a) (elemsU b) (elemsU c) (elemsU d)+  where+    k i p q r s = [i, p, q, r, s]++prop_izipWith5 :: V -> V -> V -> V -> V -> Property+prop_izipWith5 a b c d e =+    elemsU (NEV.izipWith5 k a b c d e)+      === List.zipWith6 k [0 ..]+            (elemsU a) (elemsU b) (elemsU c) (elemsU d) (elemsU e)+  where+    k i p q r s t = [i, p, q, r, s, t]++prop_izipWith6 :: V -> V -> V -> V -> V -> V -> Property+prop_izipWith6 a b c d e f =+    elemsU (NEV.izipWith6 k a b c d e f)+      === List.zipWith7 k [0 ..]+            (elemsU a) (elemsU b) (elemsU c) (elemsU d) (elemsU e) (elemsU f)+  where+    k i p q r s t u = [i, p, q, r, s, t, u]+-}++prop_zip :: V -> V -> Property+prop_zip a b = elemsU (NEV.zip a b) === List.zip (elemsU a) (elemsU b)++prop_zip3 :: V -> V -> V -> Property+prop_zip3 a b c =+    elemsU (NEV.zip3 a b c) === List.zip3 (elemsU a) (elemsU b) (elemsU c)++prop_zip4 :: V -> V -> V -> V -> Property+prop_zip4 a b c d =+    elemsU (NEV.zip4 a b c d)+      === List.zip4 (elemsU a) (elemsU b) (elemsU c) (elemsU d)++prop_zip5 :: V -> V -> V -> V -> V -> Property+prop_zip5 a b c d e =+    elemsU (NEV.zip5 a b c d e)+      === List.zip5 (elemsU a) (elemsU b) (elemsU c) (elemsU d) (elemsU e)++prop_zip6 :: V -> V -> V -> V -> V -> V -> Property+prop_zip6 a b c d e f =+    elemsU (NEV.zip6 a b c d e f)+      === List.zip6 (elemsU a) (elemsU b) (elemsU c) (elemsU d) (elemsU e) (elemsU f)++-- ---------------------------------------------------------------------- --+-- Monadic zipping++prop_zipWithM :: Fun (Int, Int) Int -> V -> V -> Property+prop_zipWithM (Fn2 f) a b =+    fmap elemsU (NEV.zipWithM (\p q -> logged (p, q) (f p q)) a b)+      === (ps, List.map (uncurry f) ps)+  where+    ps = List.zip (elemsU a) (elemsU b)++prop_zipWithM_ :: V -> V -> Property+prop_zipWithM_ a b =+    NEV.zipWithM_ (\p q -> logged (p, q) p) a b+      === (List.zip (elemsU a) (elemsU b), ())++prop_izipWithM :: Fun (Int, Int, Int) Int -> V -> V -> Property+prop_izipWithM (Fn3 f) a b =+    fmap elemsU (NEV.izipWithM (\i p q -> logged i (f i p q)) a b)+      === (List.map fst ips, List.map (\(i, (p, q)) -> f i p q) ips)+  where+    ips = List.zip [0 ..] (List.zip (elemsU a) (elemsU b))++prop_izipWithM_ :: V -> V -> Property+prop_izipWithM_ a b =+    NEV.izipWithM_ (\i p q -> logged (i, p, q) p) a b+      === (List.zip3 [0 ..] (elemsU a) (elemsU b), ())++-- ---------------------------------------------------------------------- --+-- Unzipping++prop_unzip :: NonEmptyUVector (Int, Int) -> Property+prop_unzip v = (elemsU a, elemsU b) === List.unzip (elemsU v)+  where+    (a, b) = NEV.unzip v++prop_unzip3 :: NonEmptyUVector (Int, Int, Int) -> Property+prop_unzip3 v = (elemsU a, elemsU b, elemsU c) === List.unzip3 (elemsU v)+  where+    (a, b, c) = NEV.unzip3 v++prop_unzip4 :: NonEmptyUVector (Int, Int, Int, Int) -> Property+prop_unzip4 v =+    (elemsU a, elemsU b, elemsU c, elemsU d) === List.unzip4 (elemsU v)+  where+    (a, b, c, d) = NEV.unzip4 v++prop_unzip5 :: NonEmptyUVector (Int, Int, Int, Int, Int) -> Property+prop_unzip5 v =+    (elemsU a, elemsU b, elemsU c, elemsU d, elemsU e) === List.unzip5 (elemsU v)+  where+    (a, b, c, d, e) = NEV.unzip5 v++prop_unzip6 :: NonEmptyUVector (Int, Int, Int, Int, Int, Int) -> Property+prop_unzip6 v =+    (elemsU a, elemsU b, elemsU c, elemsU d, elemsU e, elemsU f)+      === List.unzip6 (elemsU v)+  where+    (a, b, c, d, e, f) = NEV.unzip6 v
+ test/Test/Data/Vector/NonEmpty/FoldsU.hs view
@@ -0,0 +1,285 @@+-- |+-- Module      : Test.Data.Vector.NonEmpty.FoldsU+-- Copyright   : (c) 2019-2026 Emily Pillmore, Koz Ross+-- License     : BSD-style+--+-- Maintainer  : Emily Pillmore <emilypi@cohomolo.gy>+-- Stability   : experimental+-- Portability : non-portable+--+-- Properties for folds, specialized folds, monadic folds, and sequencing.+--+-- Fold functions are arbitrary, hence neither associative nor commutative,+-- so the models pin down fold direction and argument order. Monadic folds+-- run in a writer-style @([w], -)@ monad to expose effect order.+--+module Test.Data.Vector.NonEmpty.FoldsU+( tests+) where+++import qualified Control.Monad as Monad+import qualified Data.List as List+import Data.List.NonEmpty (NonEmpty(..))+import Data.Ord (comparing)+import Data.Vector.NonEmpty.Unboxed (NonEmptyUVector)+import qualified Data.Vector.NonEmpty.Unboxed as NEV++import Test.Data.Vector.NonEmpty.Util+import Test.QuickCheck+import Test.Tasty+import Test.Tasty.QuickCheck+++tests :: TestTree+tests = testGroup "Folds (unboxed)"+    [ testGroup "Folding"+      [ testProperty "prop_foldl" prop_foldl+      , testProperty "prop_foldl1" prop_foldl1+      , testProperty "prop_foldl'" prop_foldl'+      , testProperty "prop_foldl1'" prop_foldl1'+      , testProperty "prop_foldr" prop_foldr+      , testProperty "prop_foldr1" prop_foldr1+      , testProperty "prop_foldr'" prop_foldr'+      , testProperty "prop_foldr1'" prop_foldr1'+      , testProperty "prop_ifoldl" prop_ifoldl+      , testProperty "prop_ifoldl'" prop_ifoldl'+      , testProperty "prop_ifoldr" prop_ifoldr+      , testProperty "prop_ifoldr'" prop_ifoldr'+      ]+    , testGroup "Specialized folds"+      [ testProperty "prop_all" prop_all+      , testProperty "prop_any" prop_any+      , testProperty "prop_and" prop_and+      , testProperty "prop_or" prop_or+      , testProperty "prop_sum" prop_sum+      , testProperty "prop_product" prop_product+      , testProperty "prop_maximum" prop_maximum+      , testProperty "prop_maximumBy" prop_maximumBy+      , testProperty "prop_minimum" prop_minimum+      , testProperty "prop_minimumBy" prop_minimumBy+      , testProperty "prop_maxIndex" prop_maxIndex+      , testProperty "prop_maxIndexBy" prop_maxIndexBy+      , testProperty "prop_minIndex" prop_minIndex+      , testProperty "prop_minIndexBy" prop_minIndexBy+      ]+    , testGroup "Monadic folds"+      [ testProperty "prop_foldM" prop_foldM+      , testProperty "prop_foldM'" prop_foldM'+      , testProperty "prop_fold1M" prop_fold1M+      , testProperty "prop_fold1M'" prop_fold1M'+      , testProperty "prop_foldM_" prop_foldM_+      , testProperty "prop_foldM'_" prop_foldM'_+      , testProperty "prop_fold1M_" prop_fold1M_+      , testProperty "prop_fold1M'_" prop_fold1M'_+      , testProperty "prop_ifoldM" prop_ifoldM+      , testProperty "prop_ifoldM'" prop_ifoldM'+      , testProperty "prop_ifoldM_" prop_ifoldM_+      , testProperty "prop_ifoldM'_" prop_ifoldM'_+      ]+    ]++type V = NonEmptyUVector Int++-- ---------------------------------------------------------------------- --+-- Models++indexedList :: V -> [(Int, Int)]+indexedList = List.zip [0 ..] . elemsU++-- | Ties resolve to the first occurrence, matching @vector@.+--+firstBy :: (a -> a -> Bool) -> [(Int, a)] -> (Int, a)+firstBy better = List.foldl1 (\x y -> if better (snd y) (snd x) then y else x)++-- | A comparison with many ties, so that tie-breaking is exercised.+--+coarse :: Int -> Int -> Ordering+coarse = comparing (`mod` 3)++-- | A writer-style step that logs the accumulator and element it consumes,+-- exposing how the accumulator is threaded even when the result is+-- discarded.+--+step :: (Int -> Int -> Int) -> Int -> Int -> ([(Int, Int)], Int)+step f acc a = logged (acc, a) (f acc a)++-- | A writer-style indexed step that logs the accumulator and index it+-- consumes.+--+istep+    :: (Int -> Int -> Int -> Int)+    -> Int+    -> Int+    -> Int+    -> ([(Int, Int)], Int)+istep f acc i a = logged (acc, i) (f acc i a)++-- ---------------------------------------------------------------------- --+-- Folding++prop_foldl :: Fun (Int, Int) Int -> Int -> V -> Property+prop_foldl (Fn2 f) z v = NEV.foldl f z v === List.foldl f z (elemsU v)++prop_foldl1 :: Fun (Int, Int) Int -> V -> Property+prop_foldl1 (Fn2 f) v = NEV.foldl1 f v === foldl1 f (elems1U v)++prop_foldl' :: Fun (Int, Int) Int -> Int -> V -> Property+prop_foldl' (Fn2 f) z v = NEV.foldl' f z v === List.foldl f z (elemsU v)++prop_foldl1' :: Fun (Int, Int) Int -> V -> Property+prop_foldl1' (Fn2 f) v = NEV.foldl1' f v === foldl1 f (elems1U v)++prop_foldr :: Fun (Int, Int) Int -> Int -> V -> Property+prop_foldr (Fn2 f) z v = NEV.foldr f z v === List.foldr f z (elemsU v)++prop_foldr1 :: Fun (Int, Int) Int -> V -> Property+prop_foldr1 (Fn2 f) v = NEV.foldr1 f v === foldr1 f (elems1U v)++prop_foldr' :: Fun (Int, Int) Int -> Int -> V -> Property+prop_foldr' (Fn2 f) z v = NEV.foldr' f z v === List.foldr f z (elemsU v)++prop_foldr1' :: Fun (Int, Int) Int -> V -> Property+prop_foldr1' (Fn2 f) v = NEV.foldr1' f v === foldr1 f (elems1U v)++prop_ifoldl :: Fun (Int, Int, Int) Int -> Int -> V -> Property+prop_ifoldl (Fn3 f) z v =+    NEV.ifoldl f z v+      === List.foldl (\acc (i, a) -> f acc i a) z (indexedList v)++prop_ifoldl' :: Fun (Int, Int, Int) Int -> Int -> V -> Property+prop_ifoldl' (Fn3 f) z v =+    NEV.ifoldl' f z v+      === List.foldl (\acc (i, a) -> f acc i a) z (indexedList v)++prop_ifoldr :: Fun (Int, Int, Int) Int -> Int -> V -> Property+prop_ifoldr (Fn3 f) z v =+    NEV.ifoldr f z v+      === List.foldr (\(i, a) acc -> f i a acc) z (indexedList v)++prop_ifoldr' :: Fun (Int, Int, Int) Int -> Int -> V -> Property+prop_ifoldr' (Fn3 f) z v =+    NEV.ifoldr' f z v+      === List.foldr (\(i, a) acc -> f i a acc) z (indexedList v)++-- ---------------------------------------------------------------------- --+-- Specialized folds++prop_all :: Fun Int Bool -> V -> Property+prop_all (Fn p) v = NEV.all p v === List.all p (elemsU v)++prop_any :: Fun Int Bool -> V -> Property+prop_any (Fn p) v = NEV.any p v === List.any p (elemsU v)++prop_and :: NonEmptyUVector Bool -> Property+prop_and v = NEV.and v === List.and (elemsU v)++prop_or :: NonEmptyUVector Bool -> Property+prop_or v = NEV.or v === List.or (elemsU v)++prop_sum :: V -> Property+prop_sum v = NEV.sum v === List.sum (elemsU v)++prop_product :: V -> Property+prop_product v = NEV.product v === List.product (elemsU v)++prop_maximum :: V -> Property+prop_maximum v = NEV.maximum v === maximum (elems1U v)++prop_maximumBy :: V -> Property+prop_maximumBy v =+    NEV.maximumBy coarse v+      === snd (firstBy (\a b -> coarse a b == GT) (indexedList v))++prop_minimum :: V -> Property+prop_minimum v = NEV.minimum v === minimum (elems1U v)++prop_minimumBy :: V -> Property+prop_minimumBy v =+    NEV.minimumBy coarse v+      === snd (firstBy (\a b -> coarse a b == LT) (indexedList v))++prop_maxIndex :: V -> Property+prop_maxIndex v =+    NEV.maxIndex w === fst (firstBy (>) (indexedList w))+  where+    w = vecU (List.map (`mod` 4) (elemsU v))++prop_maxIndexBy :: V -> Property+prop_maxIndexBy v =+    NEV.maxIndexBy coarse v+      === fst (firstBy (\a b -> coarse a b == GT) (indexedList v))++prop_minIndex :: V -> Property+prop_minIndex v =+    NEV.minIndex w === fst (firstBy (<) (indexedList w))+  where+    w = vecU (List.map (`mod` 4) (elemsU v))++prop_minIndexBy :: V -> Property+prop_minIndexBy v =+    NEV.minIndexBy coarse v+      === fst (firstBy (\a b -> coarse a b == LT) (indexedList v))++-- ---------------------------------------------------------------------- --+-- Monadic folds++prop_foldM :: Fun (Int, Int) Int -> Int -> V -> Property+prop_foldM (Fn2 f) z v =+    NEV.foldM (step f) z v === Monad.foldM (step f) z (elemsU v)++prop_foldM' :: Fun (Int, Int) Int -> Int -> V -> Property+prop_foldM' (Fn2 f) z v =+    NEV.foldM' (step f) z v === Monad.foldM (step f) z (elemsU v)++prop_fold1M :: Fun (Int, Int) Int -> V -> Property+prop_fold1M (Fn2 f) v =+    NEV.fold1M (step f) v === Monad.foldM (step f) a as+  where+    a :| as = elems1U v++prop_fold1M' :: Fun (Int, Int) Int -> V -> Property+prop_fold1M' (Fn2 f) v =+    NEV.fold1M' (step f) v === Monad.foldM (step f) a as+  where+    a :| as = elems1U v++prop_foldM_ :: Fun (Int, Int) Int -> Int -> V -> Property+prop_foldM_ (Fn2 f) z v =+    NEV.foldM_ (step f) z v === Monad.foldM_ (step f) z (elemsU v)++prop_foldM'_ :: Fun (Int, Int) Int -> Int -> V -> Property+prop_foldM'_ (Fn2 f) z v =+    NEV.foldM'_ (step f) z v === Monad.foldM_ (step f) z (elemsU v)++prop_fold1M_ :: Fun (Int, Int) Int -> V -> Property+prop_fold1M_ (Fn2 f) v =+    NEV.fold1M_ (step f) v === Monad.foldM_ (step f) a as+  where+    a :| as = elems1U v++prop_fold1M'_ :: Fun (Int, Int) Int -> V -> Property+prop_fold1M'_ (Fn2 f) v =+    NEV.fold1M'_ (step f) v === Monad.foldM_ (step f) a as+  where+    a :| as = elems1U v++prop_ifoldM :: Fun (Int, Int, Int) Int -> Int -> V -> Property+prop_ifoldM (Fn3 f) z v =+    NEV.ifoldM (istep f) z v+      === Monad.foldM (\acc (i, a) -> istep f acc i a) z (indexedList v)++prop_ifoldM' :: Fun (Int, Int, Int) Int -> Int -> V -> Property+prop_ifoldM' (Fn3 f) z v =+    NEV.ifoldM' (istep f) z v+      === Monad.foldM (\acc (i, a) -> istep f acc i a) z (indexedList v)++prop_ifoldM_ :: Fun (Int, Int, Int) Int -> Int -> V -> Property+prop_ifoldM_ (Fn3 f) z v =+    NEV.ifoldM_ (istep f) z v+      === Monad.foldM_ (\acc (i, a) -> istep f acc i a) z (indexedList v)++prop_ifoldM'_ :: Fun (Int, Int, Int) Int -> Int -> V -> Property+prop_ifoldM'_ (Fn3 f) z v =+    NEV.ifoldM'_ (istep f) z v+      === Monad.foldM_ (\acc (i, a) -> istep f acc i a) z (indexedList v)
+ test/Test/Data/Vector/NonEmpty/GroupingU.hs view
@@ -0,0 +1,107 @@+module Test.Data.Vector.NonEmpty.GroupingU+( tests+) where+++import qualified Data.List as List+import qualified Data.List.NonEmpty as NonEmpty+import Data.Vector.NonEmpty.Unboxed (NonEmptyUVector)+import Data.Vector.Unboxed (Unbox)+import qualified Data.Vector.NonEmpty.Unboxed as NEV++import Test.Data.Vector.NonEmpty.Util+import Test.QuickCheck+import Test.Tasty+import Test.Tasty.QuickCheck+++tests :: TestTree+tests = testGroup "Grouping (unboxed)"+    [ testGroup "group"+      [ testProperty "prop_group" prop_group+      , testProperty "prop_group_singleton" prop_group_singleton+      , testProperty "prop_group_all_equal" prop_group_all_equal+      , testProperty "prop_group_distinct" prop_group_distinct+      , testProperty "prop_group_runs" prop_group_runs+      ]+    , testGroup "groupBy"+      [ testProperty "prop_groupBy" prop_groupBy+      , testProperty "prop_groupBy_singleton" prop_groupBy_singleton+      , testProperty "prop_groupBy_all_true" prop_groupBy_all_true+      , testProperty "prop_groupBy_all_false" prop_groupBy_all_false+      , testProperty "prop_groupBy_equivalence" prop_groupBy_equivalence+      , testProperty "prop_groupBy_nontransitive" prop_groupBy_nontransitive+      , testProperty "prop_groupBy_asymmetric" prop_groupBy_asymmetric+      ]+    ]++groupElems :: Unbox element => NonEmpty.NonEmpty (NonEmptyUVector element) -> [[element]]+groupElems = List.map elemsU . NonEmpty.toList++prop_group :: NonEmptyUVector Int -> Property+prop_group input =+    groupElems (NEV.group (vecU values)) === List.group values+  where+    values = List.map (`mod` 4) (elemsU input)++prop_group_singleton :: Int -> Property+prop_group_singleton value =+    groupElems (NEV.group (vecU [value])) === [[value]]++prop_group_all_equal :: Int -> Positive Int -> Property+prop_group_all_equal value (Positive count) =+    groupElems (NEV.group (vecU values)) === [values]+  where+    values = List.replicate count value++prop_group_distinct :: NonEmptyUVector Int -> Property+prop_group_distinct input =+    groupElems (NEV.group (vecU values)) === List.map (: []) values+  where+    values = List.nub (elemsU input)++prop_group_runs :: Property+prop_group_runs = once $+    groupElems (NEV.group (vecU "Mississippi"))+      === ["M", "i", "ss", "i", "ss", "i", "pp", "i"]++prop_groupBy :: Fun (Int, Int) Bool -> NonEmptyUVector Int -> Property+prop_groupBy (Fn2 predicate) input =+    groupElems (NEV.groupBy predicate (vecU values))+      === List.groupBy predicate values+  where+    values = List.map (`mod` 4) (elemsU input)++prop_groupBy_singleton :: Int -> Property+prop_groupBy_singleton value =+    groupElems (NEV.groupBy predicate (vecU [value])) === [[value]]+  where+    predicate _ _ = error "groupBy evaluated its predicate on a singleton"++prop_groupBy_all_true :: NonEmptyUVector Int -> Property+prop_groupBy_all_true input =+    groupElems (NEV.groupBy (\_ _ -> True) input) === [elemsU input]++prop_groupBy_all_false :: NonEmptyUVector Int -> Property+prop_groupBy_all_false input =+    groupElems (NEV.groupBy (\_ _ -> False) input)+      === List.map (: []) (elemsU input)++prop_groupBy_equivalence :: NonEmptyUVector Int -> Property+prop_groupBy_equivalence input =+    groupElems (NEV.groupBy sameParity input)+      === List.groupBy sameParity (elemsU input)+  where+    sameParity first second = even first == even second++prop_groupBy_nontransitive :: Property+prop_groupBy_nontransitive = once $+    groupElems (NEV.groupBy nearby (vecU [1, 2, 3, 4] :: NonEmptyUVector Int))+      === [[1, 2], [3, 4]]+  where+    nearby first second = abs (first - second) <= 1++prop_groupBy_asymmetric :: Property+prop_groupBy_asymmetric = once $+    groupElems (NEV.groupBy (<) (vecU [1, 2, 1, 3, 0, 4] :: NonEmptyUVector Int))+      === [[1, 2], [1, 3], [0, 4]]
+ test/Test/Data/Vector/NonEmpty/InstancesU.hs view
@@ -0,0 +1,142 @@+-- |+-- Module      : Test.Data.Vector.NonEmpty.InstancesU+-- Copyright   : (c) 2019-2026 Emily Pillmore, Koz Ross+-- License     : BSD-style+--+-- Maintainer  : Emily Pillmore <emilypi@cohomolo.gy>+-- Stability   : experimental+-- Portability : non-portable+--+-- Laws and list models for the type class instances of t'NonEmptyUVector'.+--+module Test.Data.Vector.NonEmpty.InstancesU+( tests+) where+++import Control.DeepSeq (rnf)+import Control.Exception (evaluate)++import Data.Data (gmapM, gmapQ, gmapT, showConstr, toConstr)+import qualified Data.List as List+import Data.List.NonEmpty (NonEmpty(..))+import Data.Semigroup (sconcat, stimes)+import Data.Vector.NonEmpty.Unboxed (NonEmptyUVector)+import qualified Data.Vector.NonEmpty.Unboxed as NEV++import Test.Data.Vector.NonEmpty.Util+import Test.QuickCheck+import Test.Tasty+import Test.Tasty.QuickCheck++import Text.Read (readMaybe)+++tests :: TestTree+tests = testGroup "Instances (unboxed)"+    [ testGroup "Eq"+      [ testProperty "prop_eq" prop_eq+      ]+    , testGroup "Ord"+      [ testProperty "prop_compare" prop_compare+      ]+    , testGroup "Show"+      [ testProperty "prop_show" prop_show+      , testProperty "prop_showsPrec" prop_showsPrec+      ]+    , testGroup "Read"+      [ testProperty "prop_read_show" prop_read_show+      , testProperty "prop_read_list" prop_read_list+      ]+    , testGroup "Semigroup"+      [ testProperty "prop_append" prop_append+      , testProperty "prop_semigroup_associativity" prop_semigroup_associativity+      , testProperty "prop_sconcat" prop_sconcat+      , testProperty "prop_stimes" prop_stimes+      , testProperty "prop_stimes_non_positive" prop_stimes_non_positive+      ]+    , testGroup "NFData"+      [ testProperty "prop_rnf" prop_rnf+      , testProperty "prop_rnf_forces_elements" prop_rnf_forces_elements+      ]+    , testGroup "Data"+      [ testProperty "prop_data" prop_data+      ]+    ]++type V = NonEmptyUVector Int++-- | Either the same vector or an unrelated one, so that equal pairs are+-- generated often.+--+genNear :: V -> Gen V+genNear v = oneof [pure v, arbitrary]++-- ---------------------------------------------------------------------- --+-- Eq and Ord++prop_eq :: V -> Property+prop_eq v = forAll (genNear v) $ \w -> (v == w) === (elemsU v == elemsU w)++prop_compare :: V -> Property+prop_compare v = forAll (genNear v) $ \w ->+    compare v w === compare (elemsU v) (elemsU w)++-- ---------------------------------------------------------------------- --+-- Show and Read++prop_show :: V -> Property+prop_show v = show v === show (elemsU v)++prop_showsPrec :: Int -> V -> String -> Property+prop_showsPrec d v s = showsPrec d v s === show (elemsU v) ++ s++prop_read_show :: V -> Property+prop_read_show v = read (show v) === v++-- The empty list must not parse.+prop_read_list :: [Int] -> Property+prop_read_list as =+    fmap elemsU (readMaybe (show as) :: Maybe V) === whenNonEmpty as++-- ---------------------------------------------------------------------- --+-- Semigroup++prop_append :: V -> V -> Property+prop_append v w = elemsU (v <> w) === elemsU v ++ elemsU w++prop_semigroup_associativity :: V -> V -> V -> Property+prop_semigroup_associativity u v w = ((u <> v) <> w) === (u <> (v <> w))++prop_sconcat :: V -> [V] -> Property+prop_sconcat v vs = elemsU (sconcat (v :| vs)) === List.concatMap elemsU (v : vs)++prop_stimes :: V -> Property+prop_stimes v = forAll (choose (1, 5)) $ \n ->+    elemsU (stimes (n :: Int) v) === List.concat (List.replicate n (elemsU v))++-- A non-positive multiplier would produce an empty vector, so it must throw.+prop_stimes_non_positive :: V -> Property+prop_stimes_non_positive v = forAll (choose (-5, 0)) $ \n ->+    throws (stimes (n :: Int) v)++-- ---------------------------------------------------------------------- --+-- NFData++prop_rnf :: V -> Property+prop_rnf v = rnf v === ()++prop_rnf_forces_elements :: Property+prop_rnf_forces_elements = once $+    throwsIO (evaluate (rnf (NEV.singleton (error "unforced element" :: Int))))++-- ---------------------------------------------------------------------- --+-- Data++-- The representation is a single constructor wrapping a single field.+prop_data :: V -> Property+prop_data v =+    gmapT id v === v+      .&&. gmapM Just v === Just v+      .&&. gmapQ (const ()) v === [()]+      .&&. showConstr (toConstr v) === "NonEmptyUVector"
+ test/Test/Data/Vector/NonEmpty/ModificationU.hs view
@@ -0,0 +1,184 @@+-- |+-- Module      : Test.Data.Vector.NonEmpty.ModificationU+-- Copyright   : (c) 2019-2026 Emily Pillmore, Koz Ross+-- License     : BSD-style+--+-- Maintainer  : Emily Pillmore <emilypi@cohomolo.gy>+-- Stability   : experimental+-- Portability : non-portable+--+-- Properties for bulk updates, accumulations, permutations, and safe+-- destructive updates.+--+module Test.Data.Vector.NonEmpty.ModificationU+( tests+) where+++import qualified Data.List as List+import Data.Maybe (mapMaybe)+import qualified Data.Vector.Unboxed as V+import qualified Data.Vector.Unboxed.Mutable as MV+import Data.Vector.NonEmpty.Unboxed (NonEmptyUVector)+import qualified Data.Vector.NonEmpty.Unboxed as NEV++import Test.Data.Vector.NonEmpty.Util+import Test.QuickCheck+import Test.Tasty+import Test.Tasty.QuickCheck+++tests :: TestTree+tests = testGroup "Modification (unboxed)"+    [ testGroup "Bulk updates"+      [ testProperty "prop_bulk_update" prop_bulk_update+      , testProperty "prop_bulk_update_out_of_bounds" prop_bulk_update_out_of_bounds+      , testProperty "prop_update" prop_update+      , testProperty "prop_update_" prop_update_+      , testProperty "prop_unsafeUpd" prop_unsafeUpd+      , testProperty "prop_unsafeUpdate" prop_unsafeUpdate+      , testProperty "prop_unsafeUpdate_" prop_unsafeUpdate_+      ]+    , testGroup "Accumulations"+      [ testProperty "prop_accum" prop_accum+      , testProperty "prop_accum_out_of_bounds" prop_accum_out_of_bounds+      , testProperty "prop_accumulate" prop_accumulate+      , testProperty "prop_accumulate_" prop_accumulate_+      , testProperty "prop_unsafeAccum" prop_unsafeAccum+      , testProperty "prop_unsafeAccumulate" prop_unsafeAccumulate+      , testProperty "prop_unsafeAccumulate_" prop_unsafeAccumulate_+      ]+    , testGroup "Permutations"+      [ testProperty "prop_reverse" prop_reverse+      , testProperty "prop_reverse_involutive" prop_reverse_involutive+      , testProperty "prop_backpermute" prop_backpermute+      , testProperty "prop_backpermute_out_of_bounds" prop_backpermute_out_of_bounds+      , testProperty "prop_unsafeBackpermute" prop_unsafeBackpermute+      ]+    , testGroup "Safe destructive updates"+      [ testProperty "prop_modify" prop_modify+      , testProperty "prop_modify_preserves_input" prop_modify_preserves_input+      ]+    ]++-- ---------------------------------------------------------------------- --+-- Models++-- | Later updates to the same index win.+--+updateList :: [(Int, a)] -> [a] -> [a]+updateList us as = List.foldl' (\acc (i, a) -> adjustAt i (const a) acc) as us++accumList :: (a -> b -> a) -> [(Int, b)] -> [a] -> [a]+accumList f us as = List.foldl' (\acc (i, b) -> adjustAt i (`f` b) acc) as us++-- ---------------------------------------------------------------------- --+-- Bulk updates++prop_bulk_update :: NonEmptyUVector Int -> Property+prop_bulk_update v = forAll (genUpdatesU v) $ \us ->+    elemsU (v NEV.// us) === updateList us (elemsU v)++prop_bulk_update_out_of_bounds :: NonEmptyUVector Int -> Int -> Property+prop_bulk_update_out_of_bounds v a = forAll (genOutOfBoundsU v) $ \i ->+    throws (v NEV.// [(i, a)])++prop_update :: NonEmptyUVector Int -> Property+prop_update v = forAll (genUpdatesU v) $ \us ->+    elemsU (NEV.update v (V.fromList us)) === updateList us (elemsU v)++-- Surplus values beyond the index vector are ignored.+prop_update_ :: NonEmptyUVector Int -> [Int] -> Property+prop_update_ v surplus = forAll (genUpdatesU v) $ \us ->+    let (is, as) = List.unzip us+    in elemsU (NEV.update_ v (V.fromList is) (V.fromList (as ++ surplus)))+         === updateList us (elemsU v)++prop_unsafeUpd :: NonEmptyUVector Int -> Property+prop_unsafeUpd v = forAll (genUpdatesU v) $ \us ->+    elemsU (NEV.unsafeUpd v us) === updateList us (elemsU v)++prop_unsafeUpdate :: NonEmptyUVector Int -> Property+prop_unsafeUpdate v = forAll (genUpdatesU v) $ \us ->+    elemsU (NEV.unsafeUpdate v (V.fromList us)) === updateList us (elemsU v)++prop_unsafeUpdate_ :: NonEmptyUVector Int -> Property+prop_unsafeUpdate_ v = forAll (genUpdatesU v) $ \us ->+    let (is, as) = List.unzip us+    in elemsU (NEV.unsafeUpdate_ v (V.fromList is) (V.fromList as))+         === updateList us (elemsU v)++-- ---------------------------------------------------------------------- --+-- Accumulations++prop_accum :: Fun (Int, Int) Int -> NonEmptyUVector Int -> Property+prop_accum (Fn2 f) v = forAll (genUpdatesU v) $ \us ->+    elemsU (NEV.accum f v us) === accumList f us (elemsU v)++prop_accum_out_of_bounds :: NonEmptyUVector Int -> Int -> Property+prop_accum_out_of_bounds v b = forAll (genOutOfBoundsU v) $ \i ->+    throws (NEV.accum (+) v [(i, b)])++prop_accumulate :: Fun (Int, Int) Int -> NonEmptyUVector Int -> Property+prop_accumulate (Fn2 f) v = forAll (genUpdatesU v) $ \us ->+    elemsU (NEV.accumulate f v (V.fromList us)) === accumList f us (elemsU v)++prop_accumulate_ :: Fun (Int, Int) Int -> NonEmptyUVector Int -> Property+prop_accumulate_ (Fn2 f) v = forAll (genUpdatesU v) $ \us ->+    let (is, bs) = List.unzip us+    in elemsU (NEV.accumulate_ f v (V.fromList is) (V.fromList bs))+         === accumList f us (elemsU v)++prop_unsafeAccum :: Fun (Int, Int) Int -> NonEmptyUVector Int -> Property+prop_unsafeAccum (Fn2 f) v = forAll (genUpdatesU v) $ \us ->+    elemsU (NEV.unsafeAccum f v us) === accumList f us (elemsU v)++prop_unsafeAccumulate :: Fun (Int, Int) Int -> NonEmptyUVector Int -> Property+prop_unsafeAccumulate (Fn2 f) v = forAll (genUpdatesU v) $ \us ->+    elemsU (NEV.unsafeAccumulate f v (V.fromList us))+      === accumList f us (elemsU v)++prop_unsafeAccumulate_ :: Fun (Int, Int) Int -> NonEmptyUVector Int -> Property+prop_unsafeAccumulate_ (Fn2 f) v = forAll (genUpdatesU v) $ \us ->+    let (is, bs) = List.unzip us+    in elemsU (NEV.unsafeAccumulate_ f v (V.fromList is) (V.fromList bs))+         === accumList f us (elemsU v)++-- ---------------------------------------------------------------------- --+-- Permutations++prop_reverse :: NonEmptyUVector Int -> Property+prop_reverse v = elemsU (NEV.reverse v) === List.reverse (elemsU v)++prop_reverse_involutive :: NonEmptyUVector Int -> Property+prop_reverse_involutive v = NEV.reverse (NEV.reverse v) === v++prop_backpermute :: NonEmptyUVector Int -> Property+prop_backpermute v = forAll (genIndicesU v) $ \is ->+    elemsU (NEV.backpermute v is)+      === mapMaybe (`lookupList` elemsU v) (elemsU is)++prop_backpermute_out_of_bounds :: NonEmptyUVector Int -> Property+prop_backpermute_out_of_bounds v = forAll (genOutOfBoundsU v) $ \i ->+    throws (NEV.backpermute v (NEV.singleton i))++prop_unsafeBackpermute :: NonEmptyUVector Int -> Property+prop_unsafeBackpermute v = forAll (genIndicesU v) $ \is ->+    elemsU (NEV.unsafeBackpermute v is)+      === mapMaybe (`lookupList` elemsU v) (elemsU is)++-- ---------------------------------------------------------------------- --+-- Safe destructive updates++prop_modify :: NonEmptyUVector Int -> Int -> Property+prop_modify v a = forAll ((,) <$> genIndexU v <*> genIndexU v) $ \(i, j) ->+    elemsU (NEV.modify (\mv -> MV.write mv i a >> MV.swap mv i j) v)+      === swapAt i j (adjustAt i (const a) (elemsU v))++-- The input vector is copied, never mutated in place.+prop_modify_preserves_input :: NonEmptyList Int -> Int -> Property+prop_modify_preserves_input (NonEmpty as) a =+    (elemsU w, elemsU v) === (List.map (const a) as, as)+  where+    v = vecU as+    w = NEV.modify (`MV.set` a) v
+ test/Test/Data/Vector/NonEmpty/MutableU.hs view
@@ -0,0 +1,440 @@+{-# LANGUAGE BangPatterns #-}+{-# LANGUAGE RankNTypes #-}+{-# LANGUAGE TypeApplications #-}+-- |+-- Module      : Test.Data.Vector.NonEmpty.MutableU+-- Copyright   : (c) 2019-2026 Emily Pillmore, Koz Ross+-- License     : BSD-style+--+-- Maintainer  : Emily Pillmore <emilypi@cohomolo.gy>+-- Stability   : experimental+-- Portability : non-portable+--+-- Properties for non-empty mutable vectors, observed by freezing them+-- into lists.+--+module Test.Data.Vector.NonEmpty.MutableU+( tests+) where+++import Control.Monad.ST (ST, runST)++import qualified Data.List as List+import qualified Data.List.NonEmpty as NonEmpty+import Data.STRef (modifySTRef', newSTRef, readSTRef)+import qualified Data.Vector.Unboxed as V+import Data.Vector.Unboxed.Mutable (MVector)+import qualified Data.Vector.Unboxed.Mutable as MV+import Data.Vector.NonEmpty.Unboxed.Internal+    ( NonEmptyMUVector(..)+    , NonEmptyUVector(..)+    , NonEmptyIOUVector+    , NonEmptySTUVector+    )+import qualified Data.Vector.NonEmpty.Unboxed.Mutable as NEMV++import Test.Data.Vector.NonEmpty.Util+import Test.QuickCheck+import Test.Tasty+import Test.Tasty.QuickCheck+++tests :: TestTree+tests = testGroup "Mutable (unboxed)"+    [ testGroup "Length information"+      [ testProperty "prop_length" prop_length+      ]+    , testGroup "Extracting subvectors"+      [ testProperty "prop_slice" prop_slice+      , testProperty "prop_slice_shares" prop_slice_shares+      , testProperty "prop_init" prop_init+      , testProperty "prop_tail" prop_tail+      , testProperty "prop_take" prop_take+      , testProperty "prop_drop" prop_drop+      , testProperty "prop_splitAt" prop_splitAt+      , testProperty "prop_unsafeSlice" prop_unsafeSlice+      , testProperty "prop_unsafeTake" prop_unsafeTake+      , testProperty "prop_unsafeDrop" prop_unsafeDrop+      ]+    , testGroup "Overlapping"+      [ testProperty "prop_overlaps_self" prop_overlaps_self+      , testProperty "prop_overlaps_distinct" prop_overlaps_distinct+      , testProperty "prop_overlaps_slices" prop_overlaps_slices+      ]+    , testGroup "Conversions"+      [ testProperty "prop_fromMVector" prop_fromMVector+      , testProperty "prop_toMVector" prop_toMVector+      , testProperty "prop_unsafeFromMVector" prop_unsafeFromMVector+      ]+    , testGroup "Initialisation"+      [ testProperty "prop_new" prop_new+      , testProperty "prop_new1" prop_new1+      , testProperty "prop_unsafeNew" prop_unsafeNew+      , testProperty "prop_replicate" prop_replicate+      , testProperty "prop_replicate1" prop_replicate1+      , testProperty "prop_replicateM" prop_replicateM+      , testProperty "prop_replicate1M" prop_replicate1M+      , testProperty "prop_clone" prop_clone+      ]+    , testGroup "Growing"+      [ testProperty "prop_grow" prop_grow+      , testProperty "prop_grow_negative" prop_grow_negative+      , testProperty "prop_unsafeGrow" prop_unsafeGrow+      ]+    , testGroup "Accessing individual elements"+      [ testProperty "prop_read" prop_read+      , testProperty "prop_read_out_of_bounds" prop_read_out_of_bounds+      , testProperty "prop_write" prop_write+      , testProperty "prop_write_out_of_bounds" prop_write_out_of_bounds+      , testProperty "prop_modify" prop_modify+      , testProperty "prop_swap" prop_swap+      , testProperty "prop_unsafeRead" prop_unsafeRead+      , testProperty "prop_unsafeWrite" prop_unsafeWrite+      , testProperty "prop_unsafeModify" prop_unsafeModify+      , testProperty "prop_unsafeSwap" prop_unsafeSwap+      ]+    , testGroup "Modifying vectors"+      [ testProperty "prop_nextPermutation" prop_nextPermutation+      , testProperty "prop_nextPermutation_last" prop_nextPermutation_last+      ]+    , testGroup "Filling and copying"+      [ testProperty "prop_set" prop_set+      , testProperty "prop_copy" prop_copy+      , testProperty "prop_copy_length_mismatch" prop_copy_length_mismatch+      , testProperty "prop_unsafeCopy" prop_unsafeCopy+      , testProperty "prop_move" prop_move+      , testProperty "prop_unsafeMove" prop_unsafeMove+      ]+    ]++type V = NonEmptyUVector Int++-- ---------------------------------------------------------------------- --+-- Running mutable vectors++thaw :: V.Unbox a => NonEmptyUVector a -> ST s (NonEmptySTUVector s a)+thaw = fmap NonEmptyMUVector . V.thaw . _neUvec++thawIO :: V.Unbox a => NonEmptyUVector a -> IO (NonEmptyIOUVector a)+thawIO = fmap NonEmptyMUVector . V.thaw . _neUvec++-- | Run a computation against a fresh mutable copy of the vector.+--+withThawed :: V.Unbox a => NonEmptyUVector a -> (forall s. NonEmptySTUVector s a -> ST s b) -> b+withThawed v k = runST (thaw v >>= k)++freezeList :: V.Unbox a => MVector s a -> ST s [a]+freezeList = fmap V.toList . V.freeze++freeze :: V.Unbox a => NonEmptySTUVector s a -> ST s [a]+freeze = freezeList . _nemUvec++-- | A mutable operation's effect on the vector's contents.+--+mutated :: V -> (forall s. NonEmptySTUVector s Int -> ST s ()) -> [Int]+mutated v k = withThawed v (\mv -> k mv >> freeze mv)++-- ---------------------------------------------------------------------- --+-- Length information++prop_length :: V -> Property+prop_length v = withThawed v (pure . NEMV.length) === List.length (elemsU v)++-- ---------------------------------------------------------------------- --+-- Extracting subvectors++prop_slice :: V -> Property+prop_slice v = forAll (genSliceU v) $ \(i, m) ->+    withThawed v (freezeList . NEMV.slice i m)+      === List.take m (List.drop i (elemsU v))++-- Subvectors are views: writes through them reach the parent vector.+prop_slice_shares :: V -> Int -> Property+prop_slice_shares v a = forAll (genIndexU v) $ \i ->+    mutated v (\mv -> MV.write (NEMV.drop i mv) 0 a)+      === adjustAt i (const a) (elemsU v)++prop_init :: V -> Property+prop_init v =+    withThawed v (freezeList . NEMV.init)+      === List.take (List.length (elemsU v) - 1) (elemsU v)++prop_tail :: V -> Property+prop_tail v = withThawed v (freezeList . NEMV.tail) === List.drop 1 (elemsU v)++prop_take :: Int -> V -> Property+prop_take n v =+    withThawed v (freezeList . NEMV.take n) === List.take n (elemsU v)++prop_drop :: Int -> V -> Property+prop_drop n v =+    withThawed v (freezeList . NEMV.drop n) === List.drop n (elemsU v)++prop_splitAt :: Int -> V -> Property+prop_splitAt n v =+    withThawed v (\mv -> let (as, bs) = NEMV.splitAt n mv+                         in (,) <$> freezeList as <*> freezeList bs)+      === List.splitAt n (elemsU v)++prop_unsafeSlice :: V -> Property+prop_unsafeSlice v = forAll (genSliceU v) $ \(i, m) ->+    withThawed v (freezeList . NEMV.unsafeSlice i m)+      === List.take m (List.drop i (elemsU v))++prop_unsafeTake :: V -> Property+prop_unsafeTake v = forAll (choose (0, List.length (elemsU v))) $ \n ->+    withThawed v (freezeList . NEMV.unsafeTake n) === List.take n (elemsU v)++prop_unsafeDrop :: V -> Property+prop_unsafeDrop v = forAll (choose (0, List.length (elemsU v))) $ \n ->+    withThawed v (freezeList . NEMV.unsafeDrop n) === List.drop n (elemsU v)++-- ---------------------------------------------------------------------- --+-- Overlapping++prop_overlaps_self :: V -> Property+prop_overlaps_self v = withThawed v (\mv -> pure (NEMV.overlaps mv mv)) === True++prop_overlaps_distinct :: V -> V -> Property+prop_overlaps_distinct v w = runST (NEMV.overlaps <$> thaw v <*> thaw w) === False++-- Adjacent slices are disjoint; extending one by an element overlaps them.+prop_overlaps_slices :: V -> Property+prop_overlaps_slices v = n >= 2 ==> forAll (choose (1, n - 1)) $ \k ->+    withThawed v (\(NonEmptyMUVector mv) ->+      let front m = NonEmptyMUVector (MV.take m mv)+          back = NonEmptyMUVector (MV.drop k mv)+      in pure (NEMV.overlaps (front k) back, NEMV.overlaps (front (k + 1)) back))+      === (False, True)+  where+    n = List.length (elemsU v)++-- ---------------------------------------------------------------------- --+-- Conversions++prop_fromMVector :: [Int] -> Property+prop_fromMVector as =+    runST (V.thaw (V.fromList as) >>= traverse freeze . NEMV.fromMVector)+      === whenNonEmpty as++prop_toMVector :: V -> Property+prop_toMVector v = withThawed v (freezeList . NEMV.toMVector) === elemsU v++prop_unsafeFromMVector :: V -> Property+prop_unsafeFromMVector v =+    runST (V.thaw (_neUvec v) >>= freeze . NEMV.unsafeFromMVector) === elemsU v++-- ---------------------------------------------------------------------- --+-- Initialisation++prop_new :: NonNegative Int -> Property+prop_new (NonNegative n) =+    runST (fmap NEMV.length <$> NEMV.new @_ @Int n)+      === if n > 0 then Just n else Nothing++prop_new1 :: Int -> Property+prop_new1 n = runST (NEMV.length <$> NEMV.new1 @_ @Int n) === max n 1++prop_unsafeNew :: NonNegative Int -> Property+prop_unsafeNew (NonNegative n) =+    runST (fmap NEMV.length <$> NEMV.unsafeNew @_ @Int n)+      === if n > 0 then Just n else Nothing++prop_replicate :: Int -> Int -> Property+prop_replicate n a =+    runST (NEMV.replicate n a >>= traverse freeze)+      === whenNonEmpty (List.replicate n a)++prop_replicate1 :: Int -> Int -> Property+prop_replicate1 n a =+    runST (NEMV.replicate1 n a >>= freeze) === List.replicate (max n 1) a++-- The action runs once per element, in order.+prop_replicateM :: Int -> Property+prop_replicateM n =+    runST (counter >>= NEMV.replicateM n >>= traverse freeze)+      === whenNonEmpty [1 .. n]++prop_replicate1M :: Int -> Property+prop_replicate1M n =+    runST (counter >>= NEMV.replicate1M n >>= traverse freeze)+      === Just [1 .. max n 1]++-- | An action yielding 1, 2, 3, ... on successive runs.+--+counter :: ST s (ST s Int)+counter = do+    ref <- newSTRef 0+    pure (modifySTRef' ref (+ 1) >> readSTRef ref)++-- A clone has the same contents but no longer aliases the original.+prop_clone :: V -> Int -> Property+prop_clone v a =+    withThawed v (\mv -> do+      c <- NEMV.clone mv+      MV.set (_nemUvec c) a+      (,) <$> freeze mv <*> freeze c)+      === (elemsU v, List.map (const a) (elemsU v))++-- ---------------------------------------------------------------------- --+-- Growing++prop_grow :: V -> NonNegative Int -> Property+prop_grow v (NonNegative n) =+    withThawed v (\mv -> do+      g <- NEMV.grow mv n+      as <- freezeList (MV.take (NEMV.length mv) (_nemUvec g))+      pure (NEMV.length g, as))+      === (List.length (elemsU v) + n, elemsU v)++prop_grow_negative :: V -> Positive Int -> Property+prop_grow_negative v (Positive n) =+    throwsIO (thawIO v >>= \mv -> NEMV.grow mv (negate n))++prop_unsafeGrow :: V -> NonNegative Int -> Property+prop_unsafeGrow v (NonNegative n) =+    withThawed v (\mv -> do+      g <- NEMV.unsafeGrow mv n+      as <- freezeList (MV.take (NEMV.length mv) (_nemUvec g))+      pure (NEMV.length g, as))+      === (List.length (elemsU v) + n, elemsU v)++-- ---------------------------------------------------------------------- --+-- Accessing individual elements++prop_read :: V -> Property+prop_read v = forAll (genIndexU v) $ \i ->+    Just (withThawed v (`NEMV.read` i)) === lookupList i (elemsU v)++prop_read_out_of_bounds :: V -> Property+prop_read_out_of_bounds v = forAll (genOutOfBoundsU v) $ \i ->+    throwsIO (thawIO v >>= (`NEMV.read` i))++prop_write :: V -> Int -> Property+prop_write v a = forAll (genIndexU v) $ \i ->+    mutated v (\mv -> NEMV.write mv i a) === adjustAt i (const a) (elemsU v)++prop_write_out_of_bounds :: V -> Int -> Property+prop_write_out_of_bounds v a = forAll (genOutOfBoundsU v) $ \i ->+    throwsIO (thawIO v >>= \mv -> NEMV.write mv i a)++prop_modify :: Fun Int Int -> V -> Property+prop_modify (Fn f) v = forAll (genIndexU v) $ \i ->+    mutated v (\mv -> NEMV.modify mv f i) === adjustAt i f (elemsU v)++prop_swap :: V -> Property+prop_swap v = forAll ((,) <$> genIndexU v <*> genIndexU v) $ \(i, j) ->+    mutated v (\mv -> NEMV.swap mv i j) === swapAt i j (elemsU v)++prop_unsafeRead :: V -> Property+prop_unsafeRead v = forAll (genIndexU v) $ \i ->+    Just (withThawed v (`NEMV.unsafeRead` i)) === lookupList i (elemsU v)++prop_unsafeWrite :: V -> Int -> Property+prop_unsafeWrite v a = forAll (genIndexU v) $ \i ->+    mutated v (\mv -> NEMV.unsafeWrite mv i a) === adjustAt i (const a) (elemsU v)++prop_unsafeModify :: Fun Int Int -> V -> Property+prop_unsafeModify (Fn f) v = forAll (genIndexU v) $ \i ->+    mutated v (\mv -> NEMV.unsafeModify mv f i) === adjustAt i f (elemsU v)++prop_unsafeSwap :: V -> Property+prop_unsafeSwap v = forAll ((,) <$> genIndexU v <*> genIndexU v) $ \(i, j) ->+    mutated v (\mv -> NEMV.unsafeSwap mv i j) === swapAt i j (elemsU v)++-- ---------------------------------------------------------------------- --+-- Modifying vectors++-- Starting from sorted order, successive permutations enumerate every+-- distinct permutation in lexicographic order.+prop_nextPermutation :: Property+prop_nextPermutation =+    forAll (choose (1, 5)) $ \n ->+    forAll (vectorOf n (choose (0, 3))) $ \as ->+      let sorted = List.sort (as :: [Int])+      in withThawed (vecU sorted) enumerate+           === List.map NonEmpty.head+                 (NonEmpty.group (List.sort (List.permutations sorted)))+  where+    enumerate :: NonEmptySTUVector s Int -> ST s [[Int]]+    enumerate mv = do+      as <- freeze mv+      more <- NEMV.nextPermutation mv+      if more then (as :) <$> enumerate mv else pure [as]++-- The last permutation has no successor and is left unchanged.+prop_nextPermutation_last :: V -> Property+prop_nextPermutation_last v =+    withThawed (vecU descending) (\mv -> (,) <$> NEMV.nextPermutation mv <*> freeze mv)+      === (False, descending)+  where+    descending = List.sortBy (flip compare) (elemsU v)++-- ---------------------------------------------------------------------- --+-- Filling and copying++prop_set :: V -> Int -> Property+prop_set v a =+    mutated v (`NEMV.set` a) === List.map (const a) (elemsU v)++-- | Copy @v@ over a vector of the same length, returning the target and+-- source contents afterwards.+--+copied+    :: (forall s. NonEmptySTUVector s Int -> NonEmptySTUVector s Int -> ST s ())+    -> V+    -> [Int]+    -> ([Int], [Int])+copied cp v bs = runST $ do+    dst <- thaw (vecU bs)+    src <- thaw v+    cp dst src+    (,) <$> freeze dst <*> freeze src++prop_copy :: V -> Property+prop_copy v = forAll (vectorOf (List.length (elemsU v)) arbitrary) $ \bs ->+    copied NEMV.copy v bs === (elemsU v, elemsU v)++prop_copy_length_mismatch :: V -> Property+prop_copy_length_mismatch v = throwsIO $ do+    dst <- thawIO (vecU (0 : elemsU v))+    src <- thawIO v+    NEMV.copy dst src++prop_unsafeCopy :: V -> Property+prop_unsafeCopy v = forAll (vectorOf (List.length (elemsU v)) arbitrary) $ \bs ->+    copied NEMV.unsafeCopy v bs === (elemsU v, elemsU v)++-- | Move between the overlapping slices @[0, n - 1)@ and @[1, n)@ of one+-- vector, in both directions.+--+moved+    :: (forall s. NonEmptySTUVector s Int -> NonEmptySTUVector s Int -> ST s ())+    -> V+    -> ([Int], [Int])+moved mv v = (shift True, shift False)+  where+    n = List.length (elemsU v)++    shift left = withThawed v $ \(NonEmptyMUVector raw) -> do+      let lo = NonEmptyMUVector (MV.slice 0 (n - 1) raw)+          hi = NonEmptyMUVector (MV.slice 1 (n - 1) raw)+      if left then mv lo hi else mv hi lo+      freezeList raw++prop_move :: V -> Property+prop_move v = List.length as >= 2 ==>+    moved NEMV.move v+      === (List.drop 1 as ++ List.drop (n - 1) as, List.take 1 as ++ List.take (n - 1) as)+  where+    as = elemsU v+    n = List.length as++prop_unsafeMove :: V -> Property+prop_unsafeMove v = List.length as >= 2 ==>+    moved NEMV.unsafeMove v+      === (List.drop 1 as ++ List.drop (n - 1) as, List.take 1 as ++ List.take (n - 1) as)+  where+    as = elemsU v+    n = List.length as
+ test/Test/Data/Vector/NonEmpty/PredicatesU.hs view
@@ -0,0 +1,192 @@+-- |+-- Module      : Test.Data.Vector.NonEmpty.PredicatesU+-- Copyright   : (c) 2019-2026 Emily Pillmore, Koz Ross+-- License     : BSD-style+--+-- Maintainer  : Emily Pillmore <emilypi@cohomolo.gy>+-- Stability   : experimental+-- Portability : non-portable+--+-- Properties for filtering, partitioning, and searching.+--+-- Elements are reduced modulo a small number where duplicates or hits+-- need to be likely.+--+module Test.Data.Vector.NonEmpty.PredicatesU+( tests+) where+++import Data.Either (partitionEithers)+import qualified Data.List as List+import qualified Data.List.NonEmpty as NonEmpty+import qualified Data.Maybe as Maybe+import qualified Data.Vector.Unboxed as V+import Data.Vector.NonEmpty.Unboxed (NonEmptyUVector)+import qualified Data.Vector.NonEmpty.Unboxed as NEV++import Test.Data.Vector.NonEmpty.Util+import Test.QuickCheck+import Test.Tasty+import Test.Tasty.QuickCheck+++tests :: TestTree+tests = testGroup "Predicates (unboxed)"+    [ testGroup "Filtering"+      [ testProperty "prop_uniq" prop_uniq+      , testProperty "prop_mapMaybe" prop_mapMaybe+      , testProperty "prop_imapMaybe" prop_imapMaybe+      , testProperty "prop_filter" prop_filter+      , testProperty "prop_ifilter" prop_ifilter+      , testProperty "prop_filterM" prop_filterM+      , testProperty "prop_ifilterM" prop_ifilterM+      , testProperty "prop_takeWhile" prop_takeWhile+      , testProperty "prop_dropWhile" prop_dropWhile+      ]+    , testGroup "Partitioning"+      [ testProperty "prop_partition" prop_partition+      , testProperty "prop_partitionWith" prop_partitionWith+      , testProperty "prop_unstablePartition" prop_unstablePartition+      , testProperty "prop_span" prop_span+      , testProperty "prop_break" prop_break+      ]+    , testGroup "Searching"+      [ testProperty "prop_elem" prop_elem+      , testProperty "prop_notElem" prop_notElem+      , testProperty "prop_find" prop_find+      , testProperty "prop_findIndex" prop_findIndex+      , testProperty "prop_findIndices" prop_findIndices+      , testProperty "prop_elemIndex" prop_elemIndex+      , testProperty "prop_elemIndices" prop_elemIndices+      ]+    ]++type V = NonEmptyUVector Int++-- | Reduce elements to a small range so that duplicates and matches are+-- common.+--+small :: V -> V+small = vecU . List.map (`mod` 4) . elemsU++-- ---------------------------------------------------------------------- --+-- Filtering++prop_uniq :: V -> Property+prop_uniq v =+    elemsU (NEV.uniq w) === List.map NonEmpty.head (NonEmpty.group (elemsU w))+  where+    w = small v++prop_mapMaybe :: Fun Int (Maybe Int) -> V -> Property+prop_mapMaybe (Fn f) v =+    V.toList (NEV.mapMaybe f v) === Maybe.mapMaybe f (elemsU v)++prop_imapMaybe :: Fun (Int, Int) (Maybe Int) -> V -> Property+prop_imapMaybe (Fn2 f) v =+    V.toList (NEV.imapMaybe f v)+      === Maybe.catMaybes (List.zipWith f [0 ..] (elemsU v))++prop_filter :: Fun Int Bool -> V -> Property+prop_filter (Fn p) v = V.toList (NEV.filter p v) === List.filter p (elemsU v)++prop_ifilter :: Fun (Int, Int) Bool -> V -> Property+prop_ifilter (Fn2 p) v =+    V.toList (NEV.ifilter p v)+      === [ a | (i, a) <- List.zip [0 ..] (elemsU v), p i a ]++prop_filterM :: Fun Int Bool -> V -> Property+prop_filterM (Fn p) v =+    fmap V.toList (NEV.filterM (\a -> logged a (p a)) v)+      === (elemsU v, List.filter p (elemsU v))++prop_ifilterM :: Fun (Int, Int) Bool -> V -> Property+prop_ifilterM (Fn2 p) v =+    fmap V.toList (NEV.ifilterM (\i a -> logged i (p i a)) v)+      === ( List.map fst ias+          , [ a | (i, a) <- ias, p i a ]+          )+  where+    ias = List.zip [0 ..] (elemsU v)++prop_takeWhile :: Fun Int Bool -> V -> Property+prop_takeWhile (Fn p) v =+    V.toList (NEV.takeWhile p v) === List.takeWhile p (elemsU v)++prop_dropWhile :: Fun Int Bool -> V -> Property+prop_dropWhile (Fn p) v =+    V.toList (NEV.dropWhile p v) === List.dropWhile p (elemsU v)++-- ---------------------------------------------------------------------- --+-- Partitioning++prop_partition :: Fun Int Bool -> V -> Property+prop_partition (Fn p) v =+    (V.toList as, V.toList bs) === List.partition p (elemsU v)+  where+    (as, bs) = NEV.partition p v++prop_partitionWith :: Fun Int (Either Int Int) -> V -> Property+prop_partitionWith (Fn f) v =+    (V.toList as, V.toList bs) === partitionEithers (List.map f (elemsU v))+  where+    (as, bs) = NEV.partitionWith f v++-- Only the contents of each side are specified, not their order.+prop_unstablePartition :: Fun Int Bool -> V -> Property+prop_unstablePartition (Fn p) v =+    (List.sort (V.toList as), List.sort (V.toList bs))+      === (List.sort ts, List.sort fs)+  where+    (as, bs) = NEV.unstablePartition p v+    (ts, fs) = List.partition p (elemsU v)++prop_span :: Fun Int Bool -> V -> Property+prop_span (Fn p) v =+    (V.toList as, V.toList bs) === List.span p (elemsU v)+  where+    (as, bs) = NEV.span p v++prop_break :: Fun Int Bool -> V -> Property+prop_break (Fn p) v =+    (V.toList as, V.toList bs) === List.break p (elemsU v)+  where+    (as, bs) = NEV.break p v++-- ---------------------------------------------------------------------- --+-- Searching++prop_elem :: Int -> V -> Property+prop_elem a v = NEV.elem (a `mod` 4) w === List.elem (a `mod` 4) (elemsU w)+  where+    w = small v++prop_notElem :: Int -> V -> Property+prop_notElem a v =+    NEV.notElem (a `mod` 4) w === List.notElem (a `mod` 4) (elemsU w)+  where+    w = small v++prop_find :: Fun Int Bool -> V -> Property+prop_find (Fn p) v = NEV.find p v === List.find p (elemsU v)++prop_findIndex :: Fun Int Bool -> V -> Property+prop_findIndex (Fn p) v = NEV.findIndex p v === List.findIndex p (elemsU v)++prop_findIndices :: Fun Int Bool -> V -> Property+prop_findIndices (Fn p) v =+    V.toList (NEV.findIndices p v) === List.findIndices p (elemsU v)++prop_elemIndex :: Int -> V -> Property+prop_elemIndex a v =+    NEV.elemIndex (a `mod` 4) w === List.elemIndex (a `mod` 4) (elemsU w)+  where+    w = small v++prop_elemIndices :: Int -> V -> Property+prop_elemIndices a v =+    V.toList (NEV.elemIndices (a `mod` 4) w)+      === List.elemIndices (a `mod` 4) (elemsU w)+  where+    w = small v
+ test/Test/Data/Vector/NonEmpty/ScansU.hs view
@@ -0,0 +1,215 @@+-- |+-- Module      : Test.Data.Vector.NonEmpty.ScansU+-- Copyright   : (c) 2019-2026 Emily Pillmore, Koz Ross+-- License     : BSD-style+--+-- Maintainer  : Emily Pillmore <emilypi@cohomolo.gy>+-- Stability   : experimental+-- Portability : non-portable+--+-- Properties for prefix sums (scans) and transformations.+--+-- Scan functions are arbitrary, hence neither associative nor commutative,+-- so the models pin down scan direction and argument order.+--+module Test.Data.Vector.NonEmpty.ScansU+( tests+) where+++import qualified Data.List as List+import qualified Data.Vector.Unboxed as V+import Data.Vector.NonEmpty.Unboxed (NonEmptyUVector)+import qualified Data.Vector.NonEmpty.Unboxed as NEV++import Test.Data.Vector.NonEmpty.Util+import Test.QuickCheck+import Test.Tasty+import Test.Tasty.QuickCheck+++tests :: TestTree+tests = testGroup "Scans (unboxed)"+    [ testGroup "Prefix sums"+      [ testProperty "prop_prescanl" prop_prescanl+      , testProperty "prop_prescanl'" prop_prescanl'+      , testProperty "prop_postscanl" prop_postscanl+      , testProperty "prop_postscanl'" prop_postscanl'+      , testProperty "prop_scanl" prop_scanl+      , testProperty "prop_scanl'" prop_scanl'+      , testProperty "prop_scanl1" prop_scanl1+      , testProperty "prop_scanl1'" prop_scanl1'+      , testProperty "prop_iscanl" prop_iscanl+      , testProperty "prop_iscanl'" prop_iscanl'+      , testProperty "prop_prescanr" prop_prescanr+      , testProperty "prop_prescanr'" prop_prescanr'+      , testProperty "prop_postscanr" prop_postscanr+      , testProperty "prop_postscanr'" prop_postscanr'+      , testProperty "prop_scanr" prop_scanr+      , testProperty "prop_scanr'" prop_scanr'+      , testProperty "prop_scanr1" prop_scanr1+      , testProperty "prop_scanr1'" prop_scanr1'+      , testProperty "prop_iscanr" prop_iscanr+      , testProperty "prop_iscanr'" prop_iscanr'+      ]+    , testGroup "Intersperse tests"+      [ testProperty "prop_intersperse" prop_intersperse+      , testProperty "prop_intersperse_length" prop_intersperse_length+      , testProperty "prop_intersperse_first_last" prop_intersperse_first_last+      , testProperty "prop_intersperse_separator" prop_intersperse_separator+      , testProperty "prop_intersperse_reconstruction" prop_intersperse_reconstruction+      , testProperty "prop_intersperse_singleton" prop_intersperse_singleton+      , testProperty "prop_explicit_examples" prop_explicit_examples+      ]+    ]++type V = NonEmptyUVector Int++-- ---------------------------------------------------------------------- --+-- Models++-- | Left scan over @(index, element)@ pairs.+--+iscanlList :: (Int -> a -> b -> a) -> a -> [b] -> [a]+iscanlList f z = List.scanl (\acc (i, b) -> f i acc b) z . List.zip [0 ..]++-- | Right scan over @(index, element)@ pairs.+--+iscanrList :: (Int -> a -> b -> b) -> b -> [a] -> [b]+iscanrList f z = List.scanr (\(i, a) acc -> f i a acc) z . List.zip [0 ..]++-- ---------------------------------------------------------------------- --+-- Left scans++prop_prescanl :: Fun (Int, Int) Int -> Int -> V -> Property+prop_prescanl (Fn2 f) z v =+    elemsU (NEV.prescanl f z v)+      === List.take (NEV.length v) (List.scanl f z (elemsU v))++prop_prescanl' :: Fun (Int, Int) Int -> Int -> V -> Property+prop_prescanl' (Fn2 f) z v =+    elemsU (NEV.prescanl' f z v)+      === List.take (NEV.length v) (List.scanl f z (elemsU v))++prop_postscanl :: Fun (Int, Int) Int -> Int -> V -> Property+prop_postscanl (Fn2 f) z v =+    elemsU (NEV.postscanl f z v) === List.drop 1 (List.scanl f z (elemsU v))++prop_postscanl' :: Fun (Int, Int) Int -> Int -> V -> Property+prop_postscanl' (Fn2 f) z v =+    elemsU (NEV.postscanl' f z v) === List.drop 1 (List.scanl f z (elemsU v))++prop_scanl :: Fun (Int, Int) Int -> Int -> V -> Property+prop_scanl (Fn2 f) z v = elemsU (NEV.scanl f z v) === List.scanl f z (elemsU v)++prop_scanl' :: Fun (Int, Int) Int -> Int -> V -> Property+prop_scanl' (Fn2 f) z v = elemsU (NEV.scanl' f z v) === List.scanl f z (elemsU v)++prop_scanl1 :: Fun (Int, Int) Int -> V -> Property+prop_scanl1 (Fn2 f) v = elemsU (NEV.scanl1 f v) === List.scanl1 f (elemsU v)++prop_scanl1' :: Fun (Int, Int) Int -> V -> Property+prop_scanl1' (Fn2 f) v = elemsU (NEV.scanl1' f v) === List.scanl1 f (elemsU v)++prop_iscanl :: Fun (Int, Int, Int) Int -> Int -> V -> Property+prop_iscanl (Fn3 f) z v =+    elemsU (NEV.iscanl f z v) === iscanlList f z (elemsU v)++prop_iscanl' :: Fun (Int, Int, Int) Int -> Int -> V -> Property+prop_iscanl' (Fn3 f) z v =+    elemsU (NEV.iscanl' f z v) === iscanlList f z (elemsU v)++-- ---------------------------------------------------------------------- --+-- Right scans++prop_prescanr :: Fun (Int, Int) Int -> Int -> V -> Property+prop_prescanr (Fn2 f) z v =+    elemsU (NEV.prescanr f z v) === List.drop 1 (List.scanr f z (elemsU v))++prop_prescanr' :: Fun (Int, Int) Int -> Int -> V -> Property+prop_prescanr' (Fn2 f) z v =+    elemsU (NEV.prescanr' f z v) === List.drop 1 (List.scanr f z (elemsU v))++prop_postscanr :: Fun (Int, Int) Int -> Int -> V -> Property+prop_postscanr (Fn2 f) z v =+    elemsU (NEV.postscanr f z v)+      === List.take (NEV.length v) (List.scanr f z (elemsU v))++prop_postscanr' :: Fun (Int, Int) Int -> Int -> V -> Property+prop_postscanr' (Fn2 f) z v =+    elemsU (NEV.postscanr' f z v)+      === List.take (NEV.length v) (List.scanr f z (elemsU v))++prop_scanr :: Fun (Int, Int) Int -> Int -> V -> Property+prop_scanr (Fn2 f) z v = elemsU (NEV.scanr f z v) === List.scanr f z (elemsU v)++prop_scanr' :: Fun (Int, Int) Int -> Int -> V -> Property+prop_scanr' (Fn2 f) z v = elemsU (NEV.scanr' f z v) === List.scanr f z (elemsU v)++prop_scanr1 :: Fun (Int, Int) Int -> V -> Property+prop_scanr1 (Fn2 f) v = elemsU (NEV.scanr1 f v) === List.scanr1 f (elemsU v)++prop_scanr1' :: Fun (Int, Int) Int -> V -> Property+prop_scanr1' (Fn2 f) v = elemsU (NEV.scanr1' f v) === List.scanr1 f (elemsU v)++prop_iscanr :: Fun (Int, Int, Int) Int -> Int -> V -> Property+prop_iscanr (Fn3 f) z v =+    elemsU (NEV.iscanr f z v) === iscanrList f z (elemsU v)++prop_iscanr' :: Fun (Int, Int, Int) Int -> Int -> V -> Property+prop_iscanr' (Fn3 f) z v =+    elemsU (NEV.iscanr' f z v) === iscanrList f z (elemsU v)++-- ---------------------------------------------------------------------- --+-- Intersperse properties++prop_intersperse :: Int -> V -> Property+prop_intersperse sep v =+    elemsU (NEV.intersperse sep v) === List.intersperse sep (elemsU v)++-- For vectors with length > 1, interspersing should result in length 2*n - 1+prop_intersperse_length :: Int -> V -> Bool+prop_intersperse_length sep v =+  let result = NEV.intersperse sep v+      originalLen = NEV.length v+  in if originalLen > 1+     then NEV.length result == 2 * originalLen - 1+     else NEV.length result == originalLen++-- The first and last elements of the result should match the original vector+prop_intersperse_first_last :: Int -> V -> Bool+prop_intersperse_first_last sep v =+  let result = NEV.intersperse sep v+  in NEV.head result == NEV.head v && NEV.last result == NEV.last v++-- Every odd-indexed element should be the separator (for vectors with length > 1)+prop_intersperse_separator :: Int -> V -> Bool+prop_intersperse_separator sep v =+  let result = NEV.intersperse sep v+  in NEV.length v <= 1 ||+     all (\i -> result NEV.! (2*i+1) == sep) [0 .. NEV.length v - 2]++-- If we remove the separator, we should get back the original vector+prop_intersperse_reconstruction :: Int -> V -> Bool+prop_intersperse_reconstruction sep v =+  let result = NEV.intersperse sep v+      resultVector = NEV.toVector result+      reconstructed = V.ifilter (\i _ -> i `mod` 2 == 0) resultVector+  in V.toList reconstructed == NEV.toList v++-- For singleton vectors, interspersing should not change the vector+prop_intersperse_singleton :: Int -> Int -> Bool+prop_intersperse_singleton x sep =+  let singleton = NEV.singleton x+      result = NEV.intersperse sep singleton+  in result == singleton++-- Explicit test cases for edge cases and examples combined into one property+prop_explicit_examples :: Property+prop_explicit_examples =+  let normalCase = NEV.intersperse (0 :: Int) (NEV.unsafeFromList [1,2,3 :: Int])+                   === NEV.unsafeFromList [1,0,2,0,3 :: Int]++      singletonCase = NEV.intersperse (0 :: Int) (NEV.singleton (5 :: Int))+                      === NEV.singleton (5 :: Int)+  in normalCase .&&. singletonCase
test/Test/Data/Vector/NonEmpty/Util.hs view
@@ -2,7 +2,7 @@ {-# OPTIONS_GHC -Wno-orphans #-} -- | -- Module      : Test.Data.Vector.NonEmpty.Util--- Copyright   : (c) 2019-2026 Emily Pillmore+-- Copyright   : (c) 2019-2026 Emily Pillmore, Koz Ross -- License     : BSD-style -- -- Maintainer  : Emily Pillmore <emilypi@cohomolo.gy>@@ -19,15 +19,23 @@ module Test.Data.Vector.NonEmpty.Util ( -- * Building and observing vectors   vec+, vecU , elems+, elemsU , elems1+, elems1U , whenNonEmpty   -- * Generators , genIndex+, genIndexU , genIndices+, genIndicesU , genOutOfBounds+, genOutOfBoundsU , genSlice+, genSliceU , genUpdates+, genUpdatesU   -- * Effects , logged , unfoldStep@@ -49,7 +57,9 @@ import Data.List.NonEmpty (NonEmpty(..)) import Data.Maybe (fromMaybe, listToMaybe) import qualified Data.Vector as V+import qualified Data.Vector.Unboxed as VU import Data.Vector.NonEmpty.Internal (NonEmptyVector(..))+import Data.Vector.NonEmpty.Unboxed.Internal (NonEmptyUVector(..))  import Test.QuickCheck @@ -58,6 +68,10 @@     arbitrary = vec . getNonEmpty <$> arbitrary     shrink = fmap (vec . getNonEmpty) . shrink . NonEmpty . elems +instance (Arbitrary a, VU.Unbox a) => Arbitrary (NonEmptyUVector a) where+    arbitrary = vecU . getNonEmpty <$> arbitrary+    shrink = fmap (vecU . getNonEmpty) . shrink . NonEmpty . elemsU+ -- ---------------------------------------------------------------------- -- -- Building and observing vectors @@ -67,17 +81,32 @@ vec :: [a] -> NonEmptyVector a vec = NonEmptyVector . V.fromList +-- | As 'vec', but for unboxed representations.+--+vecU :: VU.Unbox a => [a] -> NonEmptyUVector a+vecU = NonEmptyUVector . VU.fromList+ -- | The elements of a non-empty vector, read from its representation. -- elems :: NonEmptyVector a -> [a] elems = V.toList . _neVec +-- | As 'elems', but for unboxed representations.+--+elemsU :: VU.Unbox a => NonEmptyUVector a -> [a]+elemsU = VU.toList . _neUvec+ -- | The elements of a non-empty vector as a non-empty list, read from its -- representation. -- elems1 :: NonEmptyVector a -> NonEmpty a elems1 (NonEmptyVector v) = V.unsafeHead v :| V.toList (V.unsafeTail v) +-- | As 'elems1', but for unboxed representations.+--+elems1U :: VU.Unbox a => NonEmptyUVector a -> NonEmpty a+elems1U (NonEmptyUVector v) = VU.unsafeHead v :| VU.toList (VU.unsafeTail v)+ -- | Model of the 'Maybe'-valued constructors: 'Nothing' exactly when the -- result would be empty. --@@ -93,11 +122,21 @@ genIndex :: NonEmptyVector a -> Gen Int genIndex (NonEmptyVector v) = choose (0, V.length v - 1) +-- | As 'genIndex', but for unboxed representations.+--+genIndexU :: VU.Unbox a => NonEmptyUVector a -> Gen Int+genIndexU (NonEmptyUVector v) = choose (0, VU.length v - 1)+ -- | A non-empty vector of valid indices into the vector. -- genIndices :: NonEmptyVector a -> Gen (NonEmptyVector Int) genIndices v = vec <$> listOf1 (genIndex v) +-- | As 'genIndices', but for unboxed representations.+--+genIndicesU :: VU.Unbox a => NonEmptyUVector a -> Gen (NonEmptyUVector Int)+genIndicesU v = vecU <$> listOf1 (genIndexU v)+ -- | An index outside the bounds of the vector, on either side. -- genOutOfBounds :: NonEmptyVector a -> Gen Int@@ -108,6 +147,16 @@   where     n = V.length v +-- | As 'genOutOfBounds', but for unboxed representations.+--+genOutOfBoundsU :: VU.Unbox a => NonEmptyUVector a -> Gen Int+genOutOfBoundsU (NonEmptyUVector v) = oneof+    [ choose (-10, -1)+    , choose (n, n + 10)+    ]+  where+    n = VU.length v+ -- | A valid @(offset, length)@ slice of the vector, possibly empty. -- genSlice :: NonEmptyVector a -> Gen (Int, Int)@@ -118,10 +167,24 @@   where     n = V.length v +-- | As 'genSlice', but for unboxed representations.+genSliceU :: VU.Unbox a => NonEmptyUVector a -> Gen (Int, Int)+genSliceU (NonEmptyUVector v) = do+    i <- choose (0, n)+    m <- choose (0, n - i)+    pure (i, m)+  where+    n = VU.length v+ -- | A list of updates at valid indices of the vector. -- genUpdates :: Arbitrary b => NonEmptyVector a -> Gen [(Int, b)] genUpdates v = listOf ((,) <$> genIndex v <*> arbitrary)++-- | As 'genUpdates', but for unboxed representations.+--+genUpdatesU :: (VU.Unbox a, Arbitrary b) => NonEmptyUVector a -> Gen [(Int, b)]+genUpdatesU v = listOf ((,) <$> genIndexU v <*> arbitrary)  -- ---------------------------------------------------------------------- -- -- Effects