diff --git a/Data/Vector.hs b/Data/Vector.hs index 711e1a4f..34568234 100644 --- a/Data/Vector.hs +++ b/Data/Vector.hs @@ -1318,7 +1318,16 @@ ifilter :: (Int -> a -> Bool) -> Vector a -> Vector a {-# INLINE ifilter #-} ifilter = G.ifilter --- | /O(n)/ Drop repeated adjacent elements. +-- | /O(n)/ Drop repeated adjacent elements. First element in group is returned. +-- +-- ==== __Examples__ +-- +-- >>> import qualified Data.Vector as V +-- >>> V.uniq $ V.fromList [1.0,3.0,3.0,200.0,3.0] +-- [1.0,3.0,200.0,3.0] +-- >>> import Data.Semigroup +-- >>> V.uniq $ V.fromList [ Arg 1 'a', Arg 1 'b', Arg (1 :: Int) 'c'] +-- [Arg 1 'a'] uniq :: (Eq a) => Vector a -> Vector a {-# INLINE uniq #-} uniq = G.uniq @@ -1633,13 +1642,35 @@ product :: Num a => Vector a -> a product = G.product -- | /O(n)/ Yield the maximum element of the vector. The vector may not be --- empty. +-- empty. In a case of a tie the first occurrence wins. +-- +-- ==== __Examples__ +-- +-- >>> import qualified Data.Vector as V +-- >>> V.maximum $ V.fromList [2.0, 1.0] +-- 2.0 +-- >>> import Data.Semigroup +-- >>> V.maximum $ V.fromList [Arg 1.0 'a', Arg 2.0 'b'] +-- Arg 2.0 'b' +-- >>> V.maximum $ V.fromList [Arg 1.0 'a', Arg 1.0 'b'] +-- Arg 1.0 'a' maximum :: Ord a => Vector a -> a {-# INLINE maximum #-} maximum = G.maximum --- | /O(n)/ Yield the maximum element of the vector according to the given --- comparison function. The vector may not be empty. +-- | /O(n)/ Yield the maximum element of the vector according to the +-- given comparison function. The vector may not be empty. In case of +-- a tie the first occurrence wins. This behavior is different from +-- 'Data.List.maximumBy' which returns the last tie. +-- +-- ==== __Examples__ +-- +-- >>> import Data.Ord +-- >>> import qualified Data.Vector as V +-- >>> V.maximumBy (comparing fst) $ V.fromList [(2.0,'a'), (1.0,'b')] +-- (2.0,'a') +-- >>> V.maximumBy (comparing fst) $ V.fromList [(1.0,'a'), (1.0,'b')] +-- (1.0,'a') maximumBy :: (a -> a -> Ordering) -> Vector a -> a {-# INLINE maximumBy #-} maximumBy = G.maximumBy @@ -1647,18 +1678,47 @@ maximumBy = G.maximumBy -- | /O(n)/ Yield the maximum element of the vector by comparing the results -- of a key function on each element. In case of a tie, the first occurrence -- wins. The vector may not be empty. +-- +-- ==== __Examples__ +-- +-- >>> import qualified Data.Vector as V +-- >>> V.maximumOn fst $ V.fromList [(2.0,'a'), (1.0,'b')] +-- (2.0,'a') +-- >>> V.maximumOn fst $ V.fromList [(1.0,'a'), (1.0,'b')] +-- (1.0,'a') maximumOn :: Ord b => (a -> b) -> Vector a -> a {-# INLINE maximumOn #-} maximumOn = G.maximumOn -- | /O(n)/ Yield the minimum element of the vector. The vector may not be --- empty. +-- empty. In a case of a tie the first occurrence wins. +-- +-- ==== __Examples__ +-- +-- >>> import qualified Data.Vector as V +-- >>> V.minimum $ V.fromList [2.0, 1.0] +-- 1.0 +-- >>> import Data.Semigroup +-- >>> V.minimum $ V.fromList [Arg 2.0 'a', Arg 1.0 'b'] +-- Arg 1.0 'b' +-- >>> V.minimum $ V.fromList [Arg 1.0 'a', Arg 1.0 'b'] +-- Arg 1.0 'a' minimum :: Ord a => Vector a -> a {-# INLINE minimum #-} minimum = G.minimum --- | /O(n)/ Yield the minimum element of the vector according to the given --- comparison function. The vector may not be empty. +-- | /O(n)/ Yield the minimum element of the vector according to the +-- given comparison function. The vector may not be empty. In case of +-- a tie, the first occurrence wins. +-- +-- ==== __Examples__ +-- +-- >>> import Data.Ord +-- >>> import qualified Data.Vector as V +-- >>> V.minimumBy (comparing fst) $ V.fromList [(2.0,'a'), (1.0,'b')] +-- (1.0,'b') +-- >>> V.minimumBy (comparing fst) $ V.fromList [(1.0,'a'), (1.0,'b')] +-- (1.0,'a') minimumBy :: (a -> a -> Ordering) -> Vector a -> a {-# INLINE minimumBy #-} minimumBy = G.minimumBy @@ -1666,6 +1726,14 @@ minimumBy = G.minimumBy -- | /O(n)/ Yield the minimum element of the vector by comparing the results -- of a key function on each element. In case of a tie, the first occurrence -- wins. The vector may not be empty. +-- +-- ==== __Examples__ +-- +-- >>> import qualified Data.Vector as V +-- >>> V.minimumOn fst $ V.fromList [(2.0,'a'), (1.0,'b')] +-- (1.0,'b') +-- >>> V.minimumOn fst $ V.fromList [(1.0,'a'), (1.0,'b')] +-- (1.0,'a') minimumOn :: Ord b => (a -> b) -> Vector a -> a {-# INLINE minimumOn #-} minimumOn = G.minimumOn @@ -1676,8 +1744,18 @@ maxIndex :: Ord a => Vector a -> Int {-# INLINE maxIndex #-} maxIndex = G.maxIndex --- | /O(n)/ Yield the index of the maximum element of the vector according to --- the given comparison function. The vector may not be empty. +-- | /O(n)/ Yield the index of the maximum element of the vector +-- according to the given comparison function. The vector may not be +-- empty. In case of a tie, the first occurrence wins. +-- +-- ==== __Examples__ +-- +-- >>> import Data.Ord +-- >>> import qualified Data.Vector as V +-- >>> V.maxIndexBy (comparing fst) $ V.fromList [(2.0,'a'), (1.0,'b')] +-- 0 +-- >>> V.maxIndexBy (comparing fst) $ V.fromList [(1.0,'a'), (1.0,'b')] +-- 0 maxIndexBy :: (a -> a -> Ordering) -> Vector a -> Int {-# INLINE maxIndexBy #-} maxIndexBy = G.maxIndexBy @@ -1690,6 +1768,15 @@ minIndex = G.minIndex -- | /O(n)/ Yield the index of the minimum element of the vector according to -- the given comparison function. The vector may not be empty. +-- +-- ==== __Examples__ +-- +-- >>> import Data.Ord +-- >>> import qualified Data.Vector as V +-- >>> V.minIndexBy (comparing fst) $ V.fromList [(2.0,'a'), (1.0,'b')] +-- 1 +-- >>> V.minIndexBy (comparing fst) $ V.fromList [(1.0,'a'), (1.0,'b')] +-- 0 minIndexBy :: (a -> a -> Ordering) -> Vector a -> Int {-# INLINE minIndexBy #-} minIndexBy = G.minIndexBy diff --git a/Data/Vector/Generic.hs b/Data/Vector/Generic.hs index ca8f5bae..286f2d96 100644 --- a/Data/Vector/Generic.hs +++ b/Data/Vector/Generic.hs @@ -1385,7 +1385,16 @@ ifilter f = unstream . inplace (S.map snd . S.filter (uncurry f) . S.indexed) toMax . stream --- | /O(n)/ Drop repeated adjacent elements. +-- | /O(n)/ Drop repeated adjacent elements. First element in group is returned. +-- +-- ==== __Examples__ +-- +-- >>> import qualified Data.Vector as V +-- >>> V.uniq $ V.fromList [1.0,3.0,3.0,200.0,3.0] +-- [1.0,3.0,200.0,3.0] +-- >>> import Data.Semigroup +-- >>> V.uniq $ V.fromList [ Arg 1 'a', Arg 1 'b', Arg (1 :: Int) 'c'] +-- [Arg 1 'a'] uniq :: (Vector v a, Eq a) => v a -> v a {-# INLINE uniq #-} uniq = unstream . inplace S.uniq toMax . stream @@ -1778,42 +1787,93 @@ product :: (Vector v a, Num a) => v a -> a product = Bundle.foldl' (*) 1 . stream -- | /O(n)/ Yield the maximum element of the vector. The vector may not be --- empty. +-- empty. In a case of a tie the first occurrence wins. +-- +-- ==== __Examples__ +-- +-- >>> import qualified Data.Vector as V +-- >>> V.maximum $ V.fromList [2.0, 1.0] +-- 2.0 +-- >>> import Data.Semigroup +-- >>> V.maximum $ V.fromList [Arg 1.0 'a', Arg 2.0 'b'] +-- Arg 2.0 'b' +-- >>> V.maximum $ V.fromList [Arg 1.0 'a', Arg 1.0 'b'] +-- Arg 1.0 'a' maximum :: (Vector v a, Ord a) => v a -> a {-# INLINE maximum #-} maximum = Bundle.foldl1' max . stream --- | /O(n)/ Yield the maximum element of the vector according to the given --- comparison function. The vector may not be empty. +-- | /O(n)/ Yield the maximum element of the vector according to the +-- given comparison function. The vector may not be empty. In case of +-- a tie the first occurrence wins. This behavior is different from +-- 'Data.List.maximumBy' which returns the last tie. +-- +-- ==== __Examples__ +-- +-- >>> import Data.Ord +-- >>> import qualified Data.Vector as V +-- >>> V.maximumBy (comparing fst) $ V.fromList [(2.0,'a'), (1.0,'b')] +-- (2.0,'a') +-- >>> V.maximumBy (comparing fst) $ V.fromList [(1.0,'a'), (1.0,'b')] +-- (1.0,'a') maximumBy :: Vector v a => (a -> a -> Ordering) -> v a -> a {-# INLINE maximumBy #-} maximumBy cmpr = Bundle.foldl1' maxBy . stream where {-# INLINE maxBy #-} maxBy x y = case cmpr x y of - GT -> x - _ -> y + LT -> y + _ -> x -- | /O(n)/ Yield the maximum element of the vector by comparing the results -- of a key function on each element. In case of a tie, the first occurrence -- wins. The vector may not be empty. +-- +-- ==== __Examples__ +-- +-- >>> import qualified Data.Vector as V +-- >>> V.maximumOn fst $ V.fromList [(2.0,'a'), (1.0,'b')] +-- (2.0,'a') +-- >>> V.maximumOn fst $ V.fromList [(1.0,'a'), (1.0,'b')] +-- (1.0,'a') maximumOn :: (Ord b, Vector v a) => (a -> b) -> v a -> a {-# INLINE maximumOn #-} maximumOn f = fst . Bundle.foldl1' maxBy . Bundle.map (\a -> (a, f a)) . stream where {-# INLINE maxBy #-} maxBy x y = case compare (snd x) (snd y) of - GT -> x - _ -> y + LT -> y + _ -> x -- | /O(n)/ Yield the minimum element of the vector. The vector may not be --- empty. +-- empty. In a case of a tie the first occurrence wins. +-- +-- ==== __Examples__ +-- +-- >>> import qualified Data.Vector as V +-- >>> V.minimum $ V.fromList [2.0, 1.0] +-- 1.0 +-- >>> import Data.Semigroup +-- >>> V.minimum $ V.fromList [Arg 2.0 'a', Arg 1.0 'b'] +-- Arg 1.0 'b' +-- >>> V.minimum $ V.fromList [Arg 1.0 'a', Arg 1.0 'b'] +-- Arg 1.0 'a' minimum :: (Vector v a, Ord a) => v a -> a {-# INLINE minimum #-} minimum = Bundle.foldl1' min . stream --- | /O(n)/ Yield the minimum element of the vector according to the given --- comparison function. The vector may not be empty. +-- | /O(n)/ Yield the minimum element of the vector according to the +-- given comparison function. The vector may not be empty. In case of +-- a tie, the first occurrence wins. +-- +-- ==== __Examples__ +-- +-- >>> import Data.Ord +-- >>> import qualified Data.Vector as V +-- >>> V.minimumBy (comparing fst) $ V.fromList [(2.0,'a'), (1.0,'b')] +-- (1.0,'b') +-- >>> V.minimumBy (comparing fst) $ V.fromList [(1.0,'a'), (1.0,'b')] +-- (1.0,'a') minimumBy :: Vector v a => (a -> a -> Ordering) -> v a -> a {-# INLINE minimumBy #-} minimumBy cmpr = Bundle.foldl1' minBy . stream @@ -1826,6 +1886,14 @@ minimumBy cmpr = Bundle.foldl1' minBy . stream -- | /O(n)/ Yield the minimum element of the vector by comparing the results -- of a key function on each element. In case of a tie, the first occurrence -- wins. The vector may not be empty. +-- +-- ==== __Examples__ +-- +-- >>> import qualified Data.Vector as V +-- >>> V.minimumOn fst $ V.fromList [(2.0,'a'), (1.0,'b')] +-- (1.0,'b') +-- >>> V.minimumOn fst $ V.fromList [(1.0,'a'), (1.0,'b')] +-- (1.0,'a') minimumOn :: (Ord b, Vector v a) => (a -> b) -> v a -> a {-# INLINE minimumOn #-} minimumOn f = fst . Bundle.foldl1' minBy . Bundle.map (\a -> (a, f a)) . stream @@ -1841,16 +1909,26 @@ maxIndex :: (Vector v a, Ord a) => v a -> Int {-# INLINE maxIndex #-} maxIndex = maxIndexBy compare --- | /O(n)/ Yield the index of the maximum element of the vector according to --- the given comparison function. The vector may not be empty. +-- | /O(n)/ Yield the index of the maximum element of the vector +-- according to the given comparison function. The vector may not be +-- empty. In case of a tie, the first occurrence wins. +-- +-- ==== __Examples__ +-- +-- >>> import Data.Ord +-- >>> import qualified Data.Vector as V +-- >>> V.maxIndexBy (comparing fst) $ V.fromList [(2.0,'a'), (1.0,'b')] +-- 0 +-- >>> V.maxIndexBy (comparing fst) $ V.fromList [(1.0,'a'), (1.0,'b')] +-- 0 maxIndexBy :: Vector v a => (a -> a -> Ordering) -> v a -> Int {-# INLINE maxIndexBy #-} maxIndexBy cmpr = fst . Bundle.foldl1' imax . Bundle.indexed . stream where imax (i,x) (j,y) = i `seq` j `seq` case cmpr x y of - GT -> (i,x) - _ -> (j,y) + LT -> (j,y) + _ -> (i,x) -- | /O(n)/ Yield the index of the minimum element of the vector. The vector -- may not be empty. @@ -1860,6 +1938,15 @@ minIndex = minIndexBy compare -- | /O(n)/ Yield the index of the minimum element of the vector according to -- the given comparison function. The vector may not be empty. +-- +-- ==== __Examples__ +-- +-- >>> import Data.Ord +-- >>> import qualified Data.Vector as V +-- >>> V.minIndexBy (comparing fst) $ V.fromList [(2.0,'a'), (1.0,'b')] +-- 1 +-- >>> V.minIndexBy (comparing fst) $ V.fromList [(1.0,'a'), (1.0,'b')] +-- 0 minIndexBy :: Vector v a => (a -> a -> Ordering) -> v a -> Int {-# INLINE minIndexBy #-} minIndexBy cmpr = fst . Bundle.foldl1' imin . Bundle.indexed . stream diff --git a/Data/Vector/Primitive.hs b/Data/Vector/Primitive.hs index 636f95f3..d9c5b16a 100644 --- a/Data/Vector/Primitive.hs +++ b/Data/Vector/Primitive.hs @@ -1069,7 +1069,13 @@ ifilter :: Prim a => (Int -> a -> Bool) -> Vector a -> Vector a {-# INLINE ifilter #-} ifilter = G.ifilter --- | /O(n)/ Drop repeated adjacent elements. +-- | /O(n)/ Drop repeated adjacent elements. First element in group is returned. +-- +-- ==== __Examples__ +-- +-- >>> import qualified Data.Vector.Primitive as VP +-- >>> VP.uniq $ VP.fromList [1.0,3.0,3.0,200.0,3.0] +-- [1.0,3.0,200.0,3.0] uniq :: (Prim a, Eq a) => Vector a -> Vector a {-# INLINE uniq #-} uniq = G.uniq @@ -1354,13 +1360,21 @@ product :: (Prim a, Num a) => Vector a -> a product = G.product -- | /O(n)/ Yield the maximum element of the vector. The vector may not be --- empty. +-- empty. In a case of a tie the first occurrence wins. +-- +-- ==== __Examples__ +-- +-- >>> import qualified Data.Vector.Primitive as VP +-- >>> VP.maximum $ VP.fromList [2.0, 1.0] +-- 2.0 maximum :: (Prim a, Ord a) => Vector a -> a {-# INLINE maximum #-} maximum = G.maximum --- | /O(n)/ Yield the maximum element of the vector according to the given --- comparison function. The vector may not be empty. +-- | /O(n)/ Yield the maximum element of the vector according to the +-- given comparison function. The vector may not be empty. In case of +-- a tie the first occurrence wins. This behavior is different from +-- 'Data.List.maximumBy' which returns the last tie. maximumBy :: Prim a => (a -> a -> Ordering) -> Vector a -> a {-# INLINE maximumBy #-} maximumBy = G.maximumBy @@ -1373,13 +1387,20 @@ maximumOn :: (Ord b, Prim a) => (a -> b) -> Vector a -> a maximumOn = G.maximumOn -- | /O(n)/ Yield the minimum element of the vector. The vector may not be --- empty. +-- empty. In a case of a tie the first occurrence wins. +-- +-- ==== __Examples__ +-- +-- >>> import qualified Data.Vector.Primitive as VP +-- >>> VP.minimum $ VP.fromList [2.0, 1.0] +-- 1.0 minimum :: (Prim a, Ord a) => Vector a -> a {-# INLINE minimum #-} minimum = G.minimum --- | /O(n)/ Yield the minimum element of the vector according to the given --- comparison function. The vector may not be empty. +-- | /O(n)/ Yield the minimum element of the vector according to the +-- given comparison function. The vector may not be empty. In case of +-- a tie, the first occurrence wins. minimumBy :: Prim a => (a -> a -> Ordering) -> Vector a -> a {-# INLINE minimumBy #-} minimumBy = G.minimumBy @@ -1397,8 +1418,9 @@ maxIndex :: (Prim a, Ord a) => Vector a -> Int {-# INLINE maxIndex #-} maxIndex = G.maxIndex --- | /O(n)/ Yield the index of the maximum element of the vector according to --- the given comparison function. The vector may not be empty. +-- | /O(n)/ Yield the index of the maximum element of the vector +-- according to the given comparison function. The vector may not be +-- empty. In case of a tie, the first occurrence wins. maxIndexBy :: Prim a => (a -> a -> Ordering) -> Vector a -> Int {-# INLINE maxIndexBy #-} maxIndexBy = G.maxIndexBy diff --git a/Data/Vector/Storable.hs b/Data/Vector/Storable.hs index 871e8454..3a525942 100644 --- a/Data/Vector/Storable.hs +++ b/Data/Vector/Storable.hs @@ -1090,7 +1090,13 @@ ifilter :: Storable a => (Int -> a -> Bool) -> Vector a -> Vector a {-# INLINE ifilter #-} ifilter = G.ifilter --- | /O(n)/ Drop repeated adjacent elements. +-- | /O(n)/ Drop repeated adjacent elements. First element in group is returned. +-- +-- ==== __Examples__ +-- +-- >>> import qualified Data.Vector.Storable as VS +-- >>> VS.uniq $ VS.fromList [1.0,3.0,3.0,200.0,3.0] +-- [1.0,3.0,200.0,3.0] uniq :: (Storable a, Eq a) => Vector a -> Vector a {-# INLINE uniq #-} uniq = G.uniq @@ -1401,13 +1407,21 @@ product :: (Storable a, Num a) => Vector a -> a product = G.product -- | /O(n)/ Yield the maximum element of the vector. The vector may not be --- empty. +-- empty. In a case of a tie the first occurrence wins. +-- +-- ==== __Examples__ +-- +-- >>> import qualified Data.Vector.Storable as VS +-- >>> VS.maximum $ VS.fromList [2.0, 1.0] +-- 2.0 maximum :: (Storable a, Ord a) => Vector a -> a {-# INLINE maximum #-} maximum = G.maximum --- | /O(n)/ Yield the maximum element of the vector according to the given --- comparison function. The vector may not be empty. +-- | /O(n)/ Yield the maximum element of the vector according to the +-- given comparison function. The vector may not be empty. In case of +-- a tie the first occurrence wins. This behavior is different from +-- 'Data.List.maximumBy' which returns the last tie. maximumBy :: Storable a => (a -> a -> Ordering) -> Vector a -> a {-# INLINE maximumBy #-} maximumBy = G.maximumBy @@ -1420,13 +1434,20 @@ maximumOn :: (Ord b, Storable a) => (a -> b) -> Vector a -> a maximumOn = G.maximumOn -- | /O(n)/ Yield the minimum element of the vector. The vector may not be --- empty. +-- empty. In a case of a tie the first occurrence wins. +-- +-- ==== __Examples__ +-- +-- >>> import qualified Data.Vector.Storable as VS +-- >>> VS.minimum $ VS.fromList [2.0, 1.0] +-- 1.0 minimum :: (Storable a, Ord a) => Vector a -> a {-# INLINE minimum #-} minimum = G.minimum --- | /O(n)/ Yield the minimum element of the vector according to the given --- comparison function. The vector may not be empty. +-- | /O(n)/ Yield the minimum element of the vector according to the +-- given comparison function. The vector may not be empty. In case of +-- a tie, the first occurrence wins. minimumBy :: Storable a => (a -> a -> Ordering) -> Vector a -> a {-# INLINE minimumBy #-} minimumBy = G.minimumBy @@ -1444,8 +1465,9 @@ maxIndex :: (Storable a, Ord a) => Vector a -> Int {-# INLINE maxIndex #-} maxIndex = G.maxIndex --- | /O(n)/ Yield the index of the maximum element of the vector according to --- the given comparison function. The vector may not be empty. +-- | /O(n)/ Yield the index of the maximum element of the vector +-- according to the given comparison function. The vector may not be +-- empty. In case of a tie, the first occurrence wins. maxIndexBy :: Storable a => (a -> a -> Ordering) -> Vector a -> Int {-# INLINE maxIndexBy #-} maxIndexBy = G.maxIndexBy diff --git a/Data/Vector/Unboxed.hs b/Data/Vector/Unboxed.hs index ea7c0989..707117c4 100644 --- a/Data/Vector/Unboxed.hs +++ b/Data/Vector/Unboxed.hs @@ -1079,7 +1079,16 @@ filter :: Unbox a => (a -> Bool) -> Vector a -> Vector a {-# INLINE filter #-} filter = G.filter --- | /O(n)/ Drop repeated adjacent elements. +-- | /O(n)/ Drop repeated adjacent elements. First element in group is returned. +-- +-- ==== __Examples__ +-- +-- >>> import qualified Data.Vector.Unboxed as VU +-- >>> VU.uniq $ VU.fromList [1.0,3.0,3.0,200.0,3.0] +-- [1.0,3.0,200.0,3.0] +-- >>> import Data.Semigroup +-- >>> VU.uniq $ VU.fromList [ Arg 1 'a', Arg 1 'b', Arg (1 :: Int) 'c'] +-- [Arg 1 'a'] uniq :: (Unbox a, Eq a) => Vector a -> Vector a {-# INLINE uniq #-} uniq = G.uniq @@ -1392,13 +1401,35 @@ product :: (Unbox a, Num a) => Vector a -> a product = G.product -- | /O(n)/ Yield the maximum element of the vector. The vector may not be --- empty. +-- empty. In a case of a tie the first occurrence wins. +-- +-- ==== __Examples__ +-- +-- >>> import qualified Data.Vector.Unboxed as VU +-- >>> VU.maximum $ VU.fromList [2.0, 1.0] +-- 2.0 +-- >>> import Data.Semigroup +-- >>> VU.maximum $ VU.fromList [Arg 1.0 'a', Arg 2.0 'b'] +-- Arg 2.0 'b' +-- >>> VU.maximum $ VU.fromList [Arg 1.0 'a', Arg 1.0 'b'] +-- Arg 1.0 'a' maximum :: (Unbox a, Ord a) => Vector a -> a {-# INLINE maximum #-} maximum = G.maximum --- | /O(n)/ Yield the maximum element of the vector according to the given --- comparison function. The vector may not be empty. +-- | /O(n)/ Yield the maximum element of the vector according to the +-- given comparison function. The vector may not be empty. In case of +-- a tie the first occurrence wins. This behavior is different from +-- 'Data.List.maximumBy' which returns the last tie. +-- +-- ==== __Examples__ +-- +-- >>> import Data.Ord +-- >>> import qualified Data.Vector.Unboxed as VU +-- >>> VU.maximumBy (comparing fst) $ VU.fromList [(2.0,'a'), (1.0,'b')] +-- (2.0,'a') +-- >>> VU.maximumBy (comparing fst) $ VU.fromList [(1.0,'a'), (1.0,'b')] +-- (1.0,'a') maximumBy :: Unbox a => (a -> a -> Ordering) -> Vector a -> a {-# INLINE maximumBy #-} maximumBy = G.maximumBy @@ -1406,15 +1437,46 @@ maximumBy = G.maximumBy -- | /O(n)/ Yield the maximum element of the vector by comparing the results -- of a key function on each element. In case of a tie, the first occurrence -- wins. The vector may not be empty. +-- +-- ==== __Examples__ +-- +-- >>> import qualified Data.Vector.Unboxed as VU +-- >>> VU.maximumOn fst $ VU.fromList [(2.0,'a'), (1.0,'b')] +-- (2.0,'a') +-- >>> VU.maximumOn fst $ VU.fromList [(1.0,'a'), (1.0,'b')] +-- (1.0,'a') maximumOn :: (Ord b, Unbox a) => (a -> b) -> Vector a -> a {-# INLINE maximumOn #-} maximumOn = G.maximumOn -- | /O(n)/ Yield the minimum element of the vector. The vector may not be --- empty. +-- empty. In a case of a tie the first occurrence wins. +-- +-- ==== __Examples__ +-- +-- >>> import qualified Data.Vector.Unboxed as VU +-- >>> VU.minimum $ VU.fromList [2.0, 1.0] +-- 1.0 +-- >>> import Data.Semigroup +-- >>> VU.minimum $ VU.fromList [Arg 2.0 'a', Arg 1.0 'b'] +-- Arg 1.0 'b' +-- >>> VU.minimum $ VU.fromList [Arg 1.0 'a', Arg 1.0 'b'] +-- Arg 1.0 'a' minimum :: (Unbox a, Ord a) => Vector a -> a {-# INLINE minimum #-} minimum = G.minimum +-- | /O(n)/ Yield the minimum element of the vector according to the +-- given comparison function. The vector may not be empty. In case of +-- a tie, the first occurrence wins. +-- +-- ==== __Examples__ +-- +-- >>> import Data.Ord +-- >>> import qualified Data.Vector.Unboxed as VU +-- >>> VU.minimumBy (comparing fst) $ VU.fromList [(2.0,'a'), (1.0,'b')] +-- (1.0,'b') +-- >>> VU.minimumBy (comparing fst) $ VU.fromList [(1.0,'a'), (1.0,'b')] +-- (1.0,'a') minimumBy :: Unbox a => (a -> a -> Ordering) -> Vector a -> a -- | /O(n)/ Yield the minimum element of the vector according to the given @@ -1425,6 +1487,14 @@ minimumBy = G.minimumBy -- | /O(n)/ Yield the minimum element of the vector by comparing the results -- of a key function on each element. In case of a tie, the first occurrence -- wins. The vector may not be empty. +-- +-- ==== __Examples__ +-- +-- >>> import qualified Data.Vector.Unboxed as VU +-- >>> VU.minimumOn fst $ VU.fromList [(2.0,'a'), (1.0,'b')] +-- (1.0,'b') +-- >>> VU.minimumOn fst $ VU.fromList [(1.0,'a'), (1.0,'b')] +-- (1.0,'a') minimumOn :: (Ord b, Unbox a) => (a -> b) -> Vector a -> a {-# INLINE minimumOn #-} minimumOn = G.minimumOn @@ -1435,8 +1505,18 @@ maxIndex :: (Unbox a, Ord a) => Vector a -> Int {-# INLINE maxIndex #-} maxIndex = G.maxIndex --- | /O(n)/ Yield the index of the maximum element of the vector according to --- the given comparison function. The vector may not be empty. +-- | /O(n)/ Yield the index of the maximum element of the vector +-- according to the given comparison function. The vector may not be +-- empty. In case of a tie, the first occurrence wins. +-- +-- ==== __Examples__ +-- +-- >>> import Data.Ord +-- >>> import qualified Data.Vector.Unboxed as VU +-- >>> VU.maxIndexBy (comparing fst) $ VU.fromList [(2.0,'a'), (1.0,'b')] +-- 0 +-- >>> VU.maxIndexBy (comparing fst) $ VU.fromList [(1.0,'a'), (1.0,'b')] +-- 0 maxIndexBy :: Unbox a => (a -> a -> Ordering) -> Vector a -> Int {-# INLINE maxIndexBy #-} maxIndexBy = G.maxIndexBy @@ -1449,6 +1529,15 @@ minIndex = G.minIndex -- | /O(n)/ Yield the index of the minimum element of the vector according to -- the given comparison function. The vector may not be empty. +-- +-- ==== __Examples__ +-- +-- >>> import Data.Ord +-- >>> import qualified Data.Vector.Unboxed as VU +-- >>> VU.minIndexBy (comparing fst) $ VU.fromList [(2.0,'a'), (1.0,'b')] +-- 1 +-- >>> VU.minIndexBy (comparing fst) $ VU.fromList [(1.0,'a'), (1.0,'b')] +-- 0 minIndexBy :: Unbox a => (a -> a -> Ordering) -> Vector a -> Int {-# INLINE minIndexBy #-} minIndexBy = G.minIndexBy diff --git a/changelog.md b/changelog.md index 4fc33f64..6ebc10e3 100644 --- a/changelog.md +++ b/changelog.md @@ -7,12 +7,6 @@ compiler fine with new definitions. * `mkType` from `Data.Vector.Generic` is deprecated in favor of `Data.Data.mkNoRepType` - * `maximumBy` now behaves like its counterpart in `Data.List` in that if - `maximumBy` has to choose between several elements which could be - considered the maximum, it will now choose the last element (previously, - it would choose the first element). Similarly, `maxIndexBy` will also - now pick the last element if several elements could be considered the - maximum. * The role signatures on several `Vector` types were too permissive, so they have been tightened up: * The role signature for `Data.Vector.Mutable.MVector` is now diff --git a/tests/Tests/Vector/Property.hs b/tests/Tests/Vector/Property.hs index f2e8bde7..dd28e193 100644 --- a/tests/Tests/Vector/Property.hs +++ b/tests/Tests/Vector/Property.hs @@ -512,7 +512,7 @@ testOrdFunctions _ = $(testProperties 'prop_maximumBy, 'prop_minimumBy, 'prop_maximumOn, 'prop_minimumOn, 'prop_maxIndexBy, 'prop_minIndexBy, - 'prop_ListLastMaxIndexWins, 'prop_FalseListFirstMaxIndexWins ]) + 'prop_ListFirstMaxIndexWins, 'prop_FalseListFirstMaxIndexWins ]) where prop_compare :: P (v a -> v a -> Ordering) = compare `eq` compare prop_maximum :: P (v a -> a) = not . V.null ===> V.maximum `eq` maximum @@ -529,8 +529,8 @@ testOrdFunctions _ = $(testProperties not . V.null ===> V.minimumOn id `eq` minimum prop_maxIndexBy :: P (v a -> Int) = not . V.null ===> V.maxIndexBy compare `eq` maxIndex - prop_ListLastMaxIndexWins :: P (v a -> Int) = - not . V.null ===> ( maxIndex . V.toList) `eq` listMaxIndexLMW + prop_ListFirstMaxIndexWins :: P (v a -> Int) = + not . V.null ===> ( maxIndex . V.toList) `eq` listMaxIndexFMW prop_FalseListFirstMaxIndexWinsDesc :: P (v a -> Int) = (\x -> not $ V.null x && (V.uniq x /= x ) )===> ( maxIndex . V.toList) `eq` listMaxIndexFMW prop_FalseListFirstMaxIndexWins :: Property @@ -541,9 +541,6 @@ testOrdFunctions _ = $(testProperties listMaxIndexFMW :: Ord a => [a] -> Int listMaxIndexFMW = ( fst . extractFMW . sconcat . DLE.fromList . fmap FMW . zip [0 :: Int ..]) -listMaxIndexLMW :: Ord a => [a] -> Int -listMaxIndexLMW = ( fst . extractLMW . sconcat . DLE.fromList . fmap LMW . zip [0 :: Int ..]) - newtype LastMaxWith a i = LMW {extractLMW:: (i,a)} deriving(Eq,Show,Read) instance (Ord a) => Semigroup (LastMaxWith a i) where diff --git a/tests/Utilities.hs b/tests/Utilities.hs index 0f4f7f00..dce2321e 100644 --- a/tests/Utilities.hs +++ b/tests/Utilities.hs @@ -336,7 +336,7 @@ minIndex = fst . foldr1 imin . zip [0..] maxIndex :: Ord a => [a] -> Int maxIndex = fst . foldr1 imax . zip [0..] where - imax (i,x) (j,y) | x > y = (i,x) + imax (i,x) (j,y) | x >= y = (i,x) | otherwise = (j,y) iterateNM :: Monad m => Int -> (a -> m a) -> a -> m [a]