From 6bd8e511a434ac7292a56d71e5cfeb5495574dd3 Mon Sep 17 00:00:00 2001 From: Miles Frain Date: Tue, 12 Jan 2021 15:31:10 -0800 Subject: [PATCH 1/5] Revise groupAllBy to just use an Ordering function --- src/Data/List.purs | 41 ++++++++++++++----------------- src/Data/List/NonEmpty.purs | 2 +- test/Test/Data/List.purs | 21 ++++++++++------ test/Test/Data/List/NonEmpty.purs | 13 +++++----- 4 files changed, 39 insertions(+), 38 deletions(-) diff --git a/src/Data/List.purs b/src/Data/List.purs index 360b256..f65b91e 100644 --- a/src/Data/List.purs +++ b/src/Data/List.purs @@ -584,25 +584,23 @@ span _ xs = { init: Nil, rest: xs } -- | Group equal, consecutive elements of a list into lists. -- | --- | For example, --- | -- | ```purescript --- | group (1 : 1 : 2 : 2 : 1 : Nil) == --- | (NonEmptyList (NonEmpty 1 (1 : Nil))) : (NonEmptyList (NonEmpty 2 (2 : Nil))) : (NonEmptyList (NonEmpty 1 Nil)) : Nil +-- | group (3 : 3 : 2 : 2 : 1 : 3 : Nil) == +-- | (3 :|| 3 : Nil) : (2 :|| 2 : Nil) : (1 :|| Nil) : (3 :|| Nil) : Nil -- | ``` -- | -- | Running time: `O(n)` group :: forall a. Eq a => List a -> List (NEL.NonEmptyList a) group = groupBy (==) --- | Group equal elements of a list into lists. --- | --- | For example, +-- | Sort, then group equal elements of a list into lists. -- | -- | ```purescript --- | groupAll (1 : 1 : 2 : 2 : 1 : Nil) == --- | (NonEmptyList (NonEmpty 1 (1 : 1 : Nil))) : (NonEmptyList (NonEmpty 2 (2 : Nil))) : Nil +-- | groupAll (3 : 3 : 2 : 2 : 1 : 3 : Nil) == +-- | (1 :|| Nil) : (2 :|| 2 : Nil) : (3 :|| 3 : 3 : Nil) : Nil -- | ``` +-- | +-- | Running time: `O(n log n)` groupAll :: forall a. Ord a => List a -> List (NEL.NonEmptyList a) groupAll = group <<< sort @@ -610,14 +608,12 @@ groupAll = group <<< sort group' :: forall a. Warn (Text "'group\'' is deprecated, use groupAll instead") => Ord a => List a -> List (NEL.NonEmptyList a) group' = groupAll --- | Group equal, consecutive elements of a list into lists, using the specified --- | equivalence relation to determine equality. --- | --- | For example, +-- | Group equal, consecutive elements of a list into lists, using the provided +-- | equivalence function to determine equality. -- | -- | ```purescript --- | groupBy (\a b -> odd a && odd b) (1 : 3 : 2 : 4 : 3 : 3 : Nil) == --- | (NonEmptyList (NonEmpty 1 (3 : Nil))) : (NonEmptyList (NonEmpty 2 Nil)) : (NonEmptyList (NonEmpty 4 Nil)) : (NonEmptyList (NonEmpty 3 (3 : Nil))) : Nil +-- | groupBy (eq `on` (_ `div` 10)) (32 : 31 : 21 : 22 : 11 : 33 : Nil) == +-- | (32 :|| 31 : Nil) : (21 :|| 22 : Nil) : (11 :|| Nil) : (33 :|| Nil) : Nil -- | ``` -- | -- | Running time: `O(n)` @@ -626,17 +622,16 @@ groupBy _ Nil = Nil groupBy eq (x : xs) = case span (eq x) xs of { init: ys, rest: zs } -> NEL.NonEmptyList (x :| ys) : groupBy eq zs --- | Group equal elements of a list into lists, using the specified --- | equivalence relation to determine equality. --- | --- | For example, +-- | Sort, then group equal elements of a list into lists, using the provided comparison function. -- | -- | ```purescript --- | groupAllBy (\a b -> odd a && odd b) (1 : 3 : 2 : 4 : 3 : 3 : Nil) == --- | (NonEmptyList (NonEmpty 1 Nil)) : (NonEmptyList (NonEmpty 2 Nil)) : (NonEmptyList (NonEmpty 3 (3 : 3 : Nil))) : (NonEmptyList (NonEmpty 4 Nil)) : Nil +-- | groupAllBy (compare `on` (_ `div` 10)) (32 : 31 : 21 : 22 : 11 : 33 : Nil) == +-- | (11 :|| Nil) : (21 :|| 22 : Nil) : (32 :|| 31 : 33) : Nil -- | ``` -groupAllBy :: forall a. Ord a => (a -> a -> Boolean) -> List a -> List (NEL.NonEmptyList a) -groupAllBy p = groupBy p <<< sort +-- | +-- | Running time: `O(n log n)` +groupAllBy :: forall a. (a -> a -> Ordering) -> List a -> List (NEL.NonEmptyList a) +groupAllBy p = groupBy (\x y -> p x y == EQ) <<< sortBy p -- | Returns a lists of elements which do and do not satisfy a predicate. -- | diff --git a/src/Data/List/NonEmpty.purs b/src/Data/List/NonEmpty.purs index 9b71508..9f7d357 100644 --- a/src/Data/List/NonEmpty.purs +++ b/src/Data/List/NonEmpty.purs @@ -272,7 +272,7 @@ group' = groupAll groupBy :: forall a. (a -> a -> Boolean) -> NonEmptyList a -> NonEmptyList (NonEmptyList a) groupBy = wrappedOperation "groupBy" <<< L.groupBy -groupAllBy :: forall a. Ord a => (a -> a -> Boolean) -> NonEmptyList a -> NonEmptyList (NonEmptyList a) +groupAllBy :: forall a. (a -> a -> Ordering) -> NonEmptyList a -> NonEmptyList (NonEmptyList a) groupAllBy = wrappedOperation "groupAllBy" <<< L.groupAllBy partition :: forall a. (a -> Boolean) -> NonEmptyList a -> { yes :: L.List a, no :: L.List a } diff --git a/test/Test/Data/List.purs b/test/Test/Data/List.purs index 02b4355..fd76b6d 100644 --- a/test/Test/Data/List.purs +++ b/test/Test/Data/List.purs @@ -2,8 +2,9 @@ module Test.Data.List (testList) where import Prelude -import Data.Foldable (foldMap, foldl) +import Data.Foldable (class Foldable, foldMap, foldl) import Data.FoldableWithIndex (foldMapWithIndex, foldlWithIndex, foldrWithIndex) +import Data.Function (on) import Data.List (List(..), (..), stripPrefix, Pattern(..), length, range, foldM, unzip, zip, zipWithA, zipWith, intersectBy, intersect, (\\), deleteBy, delete, unionBy, union, nubBy, nub, group, groupAll, groupBy, groupAllBy, partition, span, dropWhile, drop, dropEnd, takeWhile, take, takeEnd, sortBy, sort, catMaybes, mapMaybe, filterM, filter, concat, concatMap, reverse, alterAt, modifyAt, updateAt, deleteAt, insertAt, findLastIndex, findIndex, elemLastIndex, elemIndex, (!!), uncons, unsnoc, init, tail, last, head, insertBy, insert, snoc, null, singleton, fromFoldable, transpose, mapWithIndex, (:)) import Data.List.NonEmpty as NEL import Data.Maybe (Maybe(..), isNothing, fromJust) @@ -21,7 +22,11 @@ import Test.Assert (assert) testList :: Effect Unit testList = do - let l = fromFoldable + let + l = fromFoldable + + nel :: ∀ f a. Foldable f => a -> f a -> NEL.NonEmptyList a + nel x xs = NEL.NonEmptyList $ x :| fromFoldable xs log "strip prefix" assert $ stripPrefix (Pattern (1:Nil)) (1:2:Nil) == Just (2:Nil) @@ -265,16 +270,16 @@ testList = do assert $ spanResult.rest == l [4, 5, 6, 7] log "group should group consecutive equal elements into lists" - assert $ group (l [1, 2, 2, 3, 3, 3, 1]) == l [NEL.singleton 1, NEL.NonEmptyList (2 :| l [2]), NEL.NonEmptyList (3 :| l [3, 3]), NEL.singleton 1] + assert $ group (l [3, 3, 2, 2, 1, 3]) == l [nel 3 [3], nel 2 [2], nel 1 [], nel 3 []] - log "groupAll should group equal elements into lists" - assert $ groupAll (l [1, 2, 2, 3, 3, 3, 1]) == l [NEL.NonEmptyList (1 :| l [1]), NEL.NonEmptyList (2 :| l [2]), NEL.NonEmptyList (3 :| l [3, 3])] + log "groupAll should sort then group equal elements into lists" + assert $ groupAll (l [3, 3, 2, 2, 1, 3]) == l [nel 1 [], nel 2 [2], nel 3 [3, 3]] log "groupBy should group consecutive equal elements into lists based on an equivalence relation" - assert $ groupBy (\x y -> odd x && odd y) (l [1, 1, 2, 2, 3, 3]) == l [NEL.NonEmptyList (1 :| l [1]), NEL.singleton 2, NEL.singleton 2, NEL.NonEmptyList (3 :| l [3])] + assert $ groupBy (eq `on` (_ `div` 10)) (l [32, 31, 21, 22, 11, 33]) == l [nel 32 [31], nel 21 [22], nel 11 [], nel 33 []] - log "groupAllBy should group equal elements into lists based on an equivalence relation" - assert $ groupAllBy (\x y -> odd x && odd y) (l [1, 3, 2, 4, 3, 3]) == l [NEL.singleton 1, NEL.singleton 2, NEL.NonEmptyList (3 :| l [3, 3]), NEL.singleton 4] + log "groupAllBy should sort then group equal elements into lists based on a comparison function" + assert $ groupAllBy (compare `on` (_ `div` 10)) (l [32, 31, 21, 22, 11, 33]) == l [nel 11 [], nel 21 [22], nel 32 [31, 33]] log "partition should separate a list into a tuple of lists that do and do not satisfy a predicate" let partitioned = partition (_ > 2) (l [1, 5, 3, 2, 4]) diff --git a/test/Test/Data/List/NonEmpty.purs b/test/Test/Data/List/NonEmpty.purs index 3316456..2c94642 100644 --- a/test/Test/Data/List/NonEmpty.purs +++ b/test/Test/Data/List/NonEmpty.purs @@ -4,6 +4,7 @@ import Prelude import Data.Foldable (class Foldable, foldM, foldMap, foldl, length) import Data.FoldableWithIndex (foldlWithIndex, foldrWithIndex, foldMapWithIndex) +import Data.Function (on) import Data.List as L import Data.List.NonEmpty as NEL import Data.Maybe (Maybe(..)) @@ -166,16 +167,16 @@ testNonEmptyList = do assert $ spanResult.rest == l [4, 5, 6, 7] log "group should group consecutive equal elements into lists" - assert $ NEL.group (nel 1 [2, 2, 3, 3, 3, 1]) == nel (nel 1 []) [nel 2 [2], nel 3 [3, 3], nel 1 []] + assert $ NEL.group (nel 3 [3, 2, 2, 1, 3]) == nel (nel 3 [3]) [nel 2 [2], nel 1 [], nel 3 []] - log "groupAll should group equal elements into lists" - assert $ NEL.groupAll (nel 1 [2, 2, 3, 3, 3, 1]) == nel (nel 1 [1]) [nel 2 [2], nel 3 [3, 3]] + log "groupAll should sort then group equal elements into lists" + assert $ NEL.groupAll (nel 3 [3, 2, 2, 1, 3]) == nel (nel 1 []) [nel 2 [2], nel 3 [3, 3]] log "groupBy should group consecutive equal elements into lists based on an equivalence relation" - assert $ NEL.groupBy (\x y -> odd x && odd y) (nel 1 [1, 2, 2, 3, 3]) == nel (nel 1 [1]) [nel 2 [], nel 2 [], nel 3 [3]] + assert $ NEL.groupBy (eq `on` (_ `div` 10)) (nel 32 [31, 21, 22, 11, 33]) == nel (nel 32 [31]) [nel 21 [22], nel 11 [], nel 33 []] - log "groupAllBy should group equal elements into lists based on an equivalence relation" - assert $ NEL.groupAllBy (\x y -> odd x && odd y) (nel 1 [3, 2, 4, 3, 3]) == nel (nel 1 []) [nel 2 [], nel 3 [3, 3], nel 4 []] + log "groupAllBy should sort then group equal elements into lists based on a comparison function" + assert $ NEL.groupAllBy (compare `on` (_ `div` 10)) (nel 32 [31, 21, 22, 11, 33]) == nel (nel 11 []) [nel 21 [22], nel 32 [31, 33]] log "partition should separate a list into a tuple of lists that do and do not satisfy a predicate" let partitioned = NEL.partition (_ > 2) (nel 1 [5, 3, 2, 4]) From 1108d57f180ac1197881b895acd5787f8d7d04af Mon Sep 17 00:00:00 2001 From: Miles Frain Date: Tue, 12 Jan 2021 17:32:45 -0800 Subject: [PATCH 2/5] Don't use proposed infix notation yet --- src/Data/List.purs | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/src/Data/List.purs b/src/Data/List.purs index f65b91e..08ffdd3 100644 --- a/src/Data/List.purs +++ b/src/Data/List.purs @@ -586,7 +586,7 @@ span _ xs = { init: Nil, rest: xs } -- | -- | ```purescript -- | group (3 : 3 : 2 : 2 : 1 : 3 : Nil) == --- | (3 :|| 3 : Nil) : (2 :|| 2 : Nil) : (1 :|| Nil) : (3 :|| Nil) : Nil +-- | NonEmptyList (3 :| 3 : Nil) : NonEmptyList (2 :| 2 : Nil) : NonEmptyList (1 :| Nil) : NonEmptyList (3 :| Nil) : Nil -- | ``` -- | -- | Running time: `O(n)` @@ -597,7 +597,7 @@ group = groupBy (==) -- | -- | ```purescript -- | groupAll (3 : 3 : 2 : 2 : 1 : 3 : Nil) == --- | (1 :|| Nil) : (2 :|| 2 : Nil) : (3 :|| 3 : 3 : Nil) : Nil +-- | NonEmptyList (1 :| Nil) : NonEmptyList (2 :| 2 : Nil) : NonEmptyList (3 :| 3 : 3 : Nil) : Nil -- | ``` -- | -- | Running time: `O(n log n)` @@ -613,7 +613,7 @@ group' = groupAll -- | -- | ```purescript -- | groupBy (eq `on` (_ `div` 10)) (32 : 31 : 21 : 22 : 11 : 33 : Nil) == --- | (32 :|| 31 : Nil) : (21 :|| 22 : Nil) : (11 :|| Nil) : (33 :|| Nil) : Nil +-- | NonEmptyList (32 :| 31 : Nil) : NonEmptyList (21 :| 22 : Nil) : NonEmptyList (11 :| Nil) : NonEmptyList (33 :| Nil) : Nil -- | ``` -- | -- | Running time: `O(n)` @@ -626,7 +626,7 @@ groupBy eq (x : xs) = case span (eq x) xs of -- | -- | ```purescript -- | groupAllBy (compare `on` (_ `div` 10)) (32 : 31 : 21 : 22 : 11 : 33 : Nil) == --- | (11 :|| Nil) : (21 :|| 22 : Nil) : (32 :|| 31 : 33) : Nil +-- | NonEmptyList (11 :| Nil) : NonEmptyList (21 :| 22 : Nil) : NonEmptyList (32 :| 31 : 33) : Nil -- | ``` -- | -- | Running time: `O(n log n)` From 5435ce43cdf43d82a09a6de3dc19e2f58823e2d8 Mon Sep 17 00:00:00 2001 From: Miles Frain Date: Wed, 13 Jan 2021 18:41:39 -0800 Subject: [PATCH 3/5] Back-out changes to docs and tests --- src/Data/List.purs | 26 +++++++++++++++----------- test/Test/Data/List.purs | 8 ++++---- test/Test/Data/List/NonEmpty.purs | 8 ++++---- 3 files changed, 23 insertions(+), 19 deletions(-) diff --git a/src/Data/List.purs b/src/Data/List.purs index 08ffdd3..a02bd7e 100644 --- a/src/Data/List.purs +++ b/src/Data/List.purs @@ -584,23 +584,25 @@ span _ xs = { init: Nil, rest: xs } -- | Group equal, consecutive elements of a list into lists. -- | +-- | For example, +-- | -- | ```purescript --- | group (3 : 3 : 2 : 2 : 1 : 3 : Nil) == --- | NonEmptyList (3 :| 3 : Nil) : NonEmptyList (2 :| 2 : Nil) : NonEmptyList (1 :| Nil) : NonEmptyList (3 :| Nil) : Nil +-- | group (1 : 1 : 2 : 2 : 1 : Nil) == +-- | (NonEmptyList (NonEmpty 1 (1 : Nil))) : (NonEmptyList (NonEmpty 2 (2 : Nil))) : (NonEmptyList (NonEmpty 1 Nil)) : Nil -- | ``` -- | -- | Running time: `O(n)` group :: forall a. Eq a => List a -> List (NEL.NonEmptyList a) group = groupBy (==) --- | Sort, then group equal elements of a list into lists. +-- | Group equal elements of a list into lists. +-- | +-- | For example, -- | -- | ```purescript --- | groupAll (3 : 3 : 2 : 2 : 1 : 3 : Nil) == --- | NonEmptyList (1 :| Nil) : NonEmptyList (2 :| 2 : Nil) : NonEmptyList (3 :| 3 : 3 : Nil) : Nil +-- | groupAll (1 : 1 : 2 : 2 : 1 : Nil) == +-- | (NonEmptyList (NonEmpty 1 (1 : 1 : Nil))) : (NonEmptyList (NonEmpty 2 (2 : Nil))) : Nil -- | ``` --- | --- | Running time: `O(n log n)` groupAll :: forall a. Ord a => List a -> List (NEL.NonEmptyList a) groupAll = group <<< sort @@ -608,12 +610,14 @@ groupAll = group <<< sort group' :: forall a. Warn (Text "'group\'' is deprecated, use groupAll instead") => Ord a => List a -> List (NEL.NonEmptyList a) group' = groupAll --- | Group equal, consecutive elements of a list into lists, using the provided --- | equivalence function to determine equality. +-- | Group equal, consecutive elements of a list into lists, using the specified +-- | equivalence relation to determine equality. +-- | +-- | For example, -- | -- | ```purescript --- | groupBy (eq `on` (_ `div` 10)) (32 : 31 : 21 : 22 : 11 : 33 : Nil) == --- | NonEmptyList (32 :| 31 : Nil) : NonEmptyList (21 :| 22 : Nil) : NonEmptyList (11 :| Nil) : NonEmptyList (33 :| Nil) : Nil +-- | groupBy (\a b -> odd a && odd b) (1 : 3 : 2 : 4 : 3 : 3 : Nil) == +-- | (NonEmptyList (NonEmpty 1 (3 : Nil))) : (NonEmptyList (NonEmpty 2 Nil)) : (NonEmptyList (NonEmpty 4 Nil)) : (NonEmptyList (NonEmpty 3 (3 : Nil))) : Nil -- | ``` -- | -- | Running time: `O(n)` diff --git a/test/Test/Data/List.purs b/test/Test/Data/List.purs index fd76b6d..1028d97 100644 --- a/test/Test/Data/List.purs +++ b/test/Test/Data/List.purs @@ -270,13 +270,13 @@ testList = do assert $ spanResult.rest == l [4, 5, 6, 7] log "group should group consecutive equal elements into lists" - assert $ group (l [3, 3, 2, 2, 1, 3]) == l [nel 3 [3], nel 2 [2], nel 1 [], nel 3 []] + assert $ group (l [1, 2, 2, 3, 3, 3, 1]) == l [NEL.singleton 1, NEL.NonEmptyList (2 :| l [2]), NEL.NonEmptyList (3 :| l [3, 3]), NEL.singleton 1] - log "groupAll should sort then group equal elements into lists" - assert $ groupAll (l [3, 3, 2, 2, 1, 3]) == l [nel 1 [], nel 2 [2], nel 3 [3, 3]] + log "groupAll should group equal elements into lists" + assert $ groupAll (l [1, 2, 2, 3, 3, 3, 1]) == l [NEL.NonEmptyList (1 :| l [1]), NEL.NonEmptyList (2 :| l [2]), NEL.NonEmptyList (3 :| l [3, 3])] log "groupBy should group consecutive equal elements into lists based on an equivalence relation" - assert $ groupBy (eq `on` (_ `div` 10)) (l [32, 31, 21, 22, 11, 33]) == l [nel 32 [31], nel 21 [22], nel 11 [], nel 33 []] + assert $ groupBy (\x y -> odd x && odd y) (l [1, 1, 2, 2, 3, 3]) == l [NEL.NonEmptyList (1 :| l [1]), NEL.singleton 2, NEL.singleton 2, NEL.NonEmptyList (3 :| l [3])] log "groupAllBy should sort then group equal elements into lists based on a comparison function" assert $ groupAllBy (compare `on` (_ `div` 10)) (l [32, 31, 21, 22, 11, 33]) == l [nel 11 [], nel 21 [22], nel 32 [31, 33]] diff --git a/test/Test/Data/List/NonEmpty.purs b/test/Test/Data/List/NonEmpty.purs index 2c94642..8585091 100644 --- a/test/Test/Data/List/NonEmpty.purs +++ b/test/Test/Data/List/NonEmpty.purs @@ -167,13 +167,13 @@ testNonEmptyList = do assert $ spanResult.rest == l [4, 5, 6, 7] log "group should group consecutive equal elements into lists" - assert $ NEL.group (nel 3 [3, 2, 2, 1, 3]) == nel (nel 3 [3]) [nel 2 [2], nel 1 [], nel 3 []] + assert $ NEL.group (nel 1 [2, 2, 3, 3, 3, 1]) == nel (nel 1 []) [nel 2 [2], nel 3 [3, 3], nel 1 []] - log "groupAll should sort then group equal elements into lists" - assert $ NEL.groupAll (nel 3 [3, 2, 2, 1, 3]) == nel (nel 1 []) [nel 2 [2], nel 3 [3, 3]] + log "groupAll should group equal elements into lists" + assert $ NEL.groupAll (nel 1 [2, 2, 3, 3, 3, 1]) == nel (nel 1 [1]) [nel 2 [2], nel 3 [3, 3]] log "groupBy should group consecutive equal elements into lists based on an equivalence relation" - assert $ NEL.groupBy (eq `on` (_ `div` 10)) (nel 32 [31, 21, 22, 11, 33]) == nel (nel 32 [31]) [nel 21 [22], nel 11 [], nel 33 []] + assert $ NEL.groupBy (\x y -> odd x && odd y) (nel 1 [1, 2, 2, 3, 3]) == nel (nel 1 [1]) [nel 2 [], nel 2 [], nel 3 [3]] log "groupAllBy should sort then group equal elements into lists based on a comparison function" assert $ NEL.groupAllBy (compare `on` (_ `div` 10)) (nel 32 [31, 21, 22, 11, 33]) == nel (nel 11 []) [nel 21 [22], nel 32 [31, 33]] From dd1ad4472cbffea6416f9b3f7831c6d33ff5ab1a Mon Sep 17 00:00:00 2001 From: Miles Frain Date: Wed, 13 Jan 2021 18:46:12 -0800 Subject: [PATCH 4/5] Revise docs and tests for group* functions --- src/Data/List.purs | 26 +++++++++++--------------- test/Test/Data/List.purs | 8 ++++---- test/Test/Data/List/NonEmpty.purs | 8 ++++---- 3 files changed, 19 insertions(+), 23 deletions(-) diff --git a/src/Data/List.purs b/src/Data/List.purs index a02bd7e..08ffdd3 100644 --- a/src/Data/List.purs +++ b/src/Data/List.purs @@ -584,25 +584,23 @@ span _ xs = { init: Nil, rest: xs } -- | Group equal, consecutive elements of a list into lists. -- | --- | For example, --- | -- | ```purescript --- | group (1 : 1 : 2 : 2 : 1 : Nil) == --- | (NonEmptyList (NonEmpty 1 (1 : Nil))) : (NonEmptyList (NonEmpty 2 (2 : Nil))) : (NonEmptyList (NonEmpty 1 Nil)) : Nil +-- | group (3 : 3 : 2 : 2 : 1 : 3 : Nil) == +-- | NonEmptyList (3 :| 3 : Nil) : NonEmptyList (2 :| 2 : Nil) : NonEmptyList (1 :| Nil) : NonEmptyList (3 :| Nil) : Nil -- | ``` -- | -- | Running time: `O(n)` group :: forall a. Eq a => List a -> List (NEL.NonEmptyList a) group = groupBy (==) --- | Group equal elements of a list into lists. --- | --- | For example, +-- | Sort, then group equal elements of a list into lists. -- | -- | ```purescript --- | groupAll (1 : 1 : 2 : 2 : 1 : Nil) == --- | (NonEmptyList (NonEmpty 1 (1 : 1 : Nil))) : (NonEmptyList (NonEmpty 2 (2 : Nil))) : Nil +-- | groupAll (3 : 3 : 2 : 2 : 1 : 3 : Nil) == +-- | NonEmptyList (1 :| Nil) : NonEmptyList (2 :| 2 : Nil) : NonEmptyList (3 :| 3 : 3 : Nil) : Nil -- | ``` +-- | +-- | Running time: `O(n log n)` groupAll :: forall a. Ord a => List a -> List (NEL.NonEmptyList a) groupAll = group <<< sort @@ -610,14 +608,12 @@ groupAll = group <<< sort group' :: forall a. Warn (Text "'group\'' is deprecated, use groupAll instead") => Ord a => List a -> List (NEL.NonEmptyList a) group' = groupAll --- | Group equal, consecutive elements of a list into lists, using the specified --- | equivalence relation to determine equality. --- | --- | For example, +-- | Group equal, consecutive elements of a list into lists, using the provided +-- | equivalence function to determine equality. -- | -- | ```purescript --- | groupBy (\a b -> odd a && odd b) (1 : 3 : 2 : 4 : 3 : 3 : Nil) == --- | (NonEmptyList (NonEmpty 1 (3 : Nil))) : (NonEmptyList (NonEmpty 2 Nil)) : (NonEmptyList (NonEmpty 4 Nil)) : (NonEmptyList (NonEmpty 3 (3 : Nil))) : Nil +-- | groupBy (eq `on` (_ `div` 10)) (32 : 31 : 21 : 22 : 11 : 33 : Nil) == +-- | NonEmptyList (32 :| 31 : Nil) : NonEmptyList (21 :| 22 : Nil) : NonEmptyList (11 :| Nil) : NonEmptyList (33 :| Nil) : Nil -- | ``` -- | -- | Running time: `O(n)` diff --git a/test/Test/Data/List.purs b/test/Test/Data/List.purs index 1028d97..fd76b6d 100644 --- a/test/Test/Data/List.purs +++ b/test/Test/Data/List.purs @@ -270,13 +270,13 @@ testList = do assert $ spanResult.rest == l [4, 5, 6, 7] log "group should group consecutive equal elements into lists" - assert $ group (l [1, 2, 2, 3, 3, 3, 1]) == l [NEL.singleton 1, NEL.NonEmptyList (2 :| l [2]), NEL.NonEmptyList (3 :| l [3, 3]), NEL.singleton 1] + assert $ group (l [3, 3, 2, 2, 1, 3]) == l [nel 3 [3], nel 2 [2], nel 1 [], nel 3 []] - log "groupAll should group equal elements into lists" - assert $ groupAll (l [1, 2, 2, 3, 3, 3, 1]) == l [NEL.NonEmptyList (1 :| l [1]), NEL.NonEmptyList (2 :| l [2]), NEL.NonEmptyList (3 :| l [3, 3])] + log "groupAll should sort then group equal elements into lists" + assert $ groupAll (l [3, 3, 2, 2, 1, 3]) == l [nel 1 [], nel 2 [2], nel 3 [3, 3]] log "groupBy should group consecutive equal elements into lists based on an equivalence relation" - assert $ groupBy (\x y -> odd x && odd y) (l [1, 1, 2, 2, 3, 3]) == l [NEL.NonEmptyList (1 :| l [1]), NEL.singleton 2, NEL.singleton 2, NEL.NonEmptyList (3 :| l [3])] + assert $ groupBy (eq `on` (_ `div` 10)) (l [32, 31, 21, 22, 11, 33]) == l [nel 32 [31], nel 21 [22], nel 11 [], nel 33 []] log "groupAllBy should sort then group equal elements into lists based on a comparison function" assert $ groupAllBy (compare `on` (_ `div` 10)) (l [32, 31, 21, 22, 11, 33]) == l [nel 11 [], nel 21 [22], nel 32 [31, 33]] diff --git a/test/Test/Data/List/NonEmpty.purs b/test/Test/Data/List/NonEmpty.purs index 8585091..2c94642 100644 --- a/test/Test/Data/List/NonEmpty.purs +++ b/test/Test/Data/List/NonEmpty.purs @@ -167,13 +167,13 @@ testNonEmptyList = do assert $ spanResult.rest == l [4, 5, 6, 7] log "group should group consecutive equal elements into lists" - assert $ NEL.group (nel 1 [2, 2, 3, 3, 3, 1]) == nel (nel 1 []) [nel 2 [2], nel 3 [3, 3], nel 1 []] + assert $ NEL.group (nel 3 [3, 2, 2, 1, 3]) == nel (nel 3 [3]) [nel 2 [2], nel 1 [], nel 3 []] - log "groupAll should group equal elements into lists" - assert $ NEL.groupAll (nel 1 [2, 2, 3, 3, 3, 1]) == nel (nel 1 [1]) [nel 2 [2], nel 3 [3, 3]] + log "groupAll should sort then group equal elements into lists" + assert $ NEL.groupAll (nel 3 [3, 2, 2, 1, 3]) == nel (nel 1 []) [nel 2 [2], nel 3 [3, 3]] log "groupBy should group consecutive equal elements into lists based on an equivalence relation" - assert $ NEL.groupBy (\x y -> odd x && odd y) (nel 1 [1, 2, 2, 3, 3]) == nel (nel 1 [1]) [nel 2 [], nel 2 [], nel 3 [3]] + assert $ NEL.groupBy (eq `on` (_ `div` 10)) (nel 32 [31, 21, 22, 11, 33]) == nel (nel 32 [31]) [nel 21 [22], nel 11 [], nel 33 []] log "groupAllBy should sort then group equal elements into lists based on a comparison function" assert $ NEL.groupAllBy (compare `on` (_ `div` 10)) (nel 32 [31, 21, 22, 11, 33]) == nel (nel 11 []) [nel 21 [22], nel 32 [31, 33]] From 625ad97127a276e38390e8c9ced150c4d4a15c59 Mon Sep 17 00:00:00 2001 From: milesfrain Date: Thu, 14 Jan 2021 23:50:25 -0800 Subject: [PATCH 5/5] Update changelog --- CHANGELOG.md | 1 + 1 file changed, 1 insertion(+) diff --git a/CHANGELOG.md b/CHANGELOG.md index d1b2aed..ed9acda 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -11,6 +11,7 @@ New features: Bugfixes: Other improvements: +- Improve consistency and clarity of docs and tests for `group*` functions (#193) ## [v5.4.1](https://github.com/purescript/purescript-lists/releases/tag/v5.4.1) - 2019-05-06