From 86d30f5dbbc8506ab6fe1951b48784c4e20e6d6f Mon Sep 17 00:00:00 2001 From: Peter Murphy <26548438+ptrfrncsmrph@users.noreply.github.com> Date: Sat, 26 Dec 2020 11:20:25 -0500 Subject: [PATCH 1/9] Add simple stability test for sortWith --- test/Test/Data/Array.purs | 7 ++++++- 1 file changed, 6 insertions(+), 1 deletion(-) diff --git a/test/Test/Data/Array.purs b/test/Test/Data/Array.purs index 02295089..16038a30 100644 --- a/test/Test/Data/Array.purs +++ b/test/Test/Data/Array.purs @@ -9,7 +9,7 @@ import Data.Const (Const(..)) import Data.Foldable (for_, foldMapDefaultR, class Foldable, all, traverse_) import Data.Traversable (scanl, scanr) import Data.Maybe (Maybe(..), isNothing, fromJust) -import Data.Tuple (Tuple(..)) +import Data.Tuple (Tuple(..), fst) import Data.Unfoldable (replicateA) import Effect (Effect) import Effect.Console (log) @@ -290,6 +290,11 @@ testArray = do log "sortWith should reorder a list into ascending order based on the result of compare over a projection" assert $ A.sortWith identity [1, 3, 2, 5, 6, 4] == [1, 2, 3, 4, 5, 6] + log "sortWith should be stable" + assert $ A.sortWith fst + [Tuple "a" 1, Tuple "a" 2, Tuple "a" 3, Tuple "a" 4] == + [Tuple "a" 1, Tuple "a" 2, Tuple "a" 3, Tuple "a" 4] + log "take should keep the specified number of items from the front of an array, discarding the rest" assert $ (A.take 1 [1, 2, 3]) == [1] assert $ (A.take 2 [1, 2, 3]) == [1, 2] From 63cc78b28010a56201cafa143494b216f4312bfa Mon Sep 17 00:00:00 2001 From: Peter Murphy <26548438+ptrfrncsmrph@users.noreply.github.com> Date: Sat, 26 Dec 2020 11:57:08 -0500 Subject: [PATCH 2/9] Use larger input array for sortWith stability test --- test/Test/Data/Array.purs | 11 +++++++---- 1 file changed, 7 insertions(+), 4 deletions(-) diff --git a/test/Test/Data/Array.purs b/test/Test/Data/Array.purs index 16038a30..cbd59ea3 100644 --- a/test/Test/Data/Array.purs +++ b/test/Test/Data/Array.purs @@ -287,13 +287,16 @@ testArray = do log "sortBy should reorder a list into ascending order based on the result of a comparison function" assert $ A.sortBy (flip compare) [1, 3, 2, 5, 6, 4] == [6, 5, 4, 3, 2, 1] + log "sortBy should not reorder elements that are equal according to a comparison function" + let s1 = map (Tuple "a") (A.range 1 100) + assert $ A.sortBy (comparing fst) s1 == s1 + log "sortWith should reorder a list into ascending order based on the result of compare over a projection" assert $ A.sortWith identity [1, 3, 2, 5, 6, 4] == [1, 2, 3, 4, 5, 6] - log "sortWith should be stable" - assert $ A.sortWith fst - [Tuple "a" 1, Tuple "a" 2, Tuple "a" 3, Tuple "a" 4] == - [Tuple "a" 1, Tuple "a" 2, Tuple "a" 3, Tuple "a" 4] + log "sortWith should not reorder elements that are equal according to a projection" + let s2 = map (Tuple "a") (A.range 1 100) + assert $ A.sortWith fst s2 == s2 log "take should keep the specified number of items from the front of an array, discarding the rest" assert $ (A.take 1 [1, 2, 3]) == [1] From da62e39b5a2ac5e54579a9f9ddedee4cc617715c Mon Sep 17 00:00:00 2001 From: Peter Murphy Date: Sun, 27 Dec 2020 19:45:05 -0500 Subject: [PATCH 3/9] Stabilize mergesort --- src/Data/Array.js | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/Data/Array.js b/src/Data/Array.js index b6bc7571..54881814 100644 --- a/src/Data/Array.js +++ b/src/Data/Array.js @@ -290,7 +290,7 @@ exports.sortByImpl = (function () { while (i < mid && j < to) { x = xs2[i]; y = xs2[j]; - c = fromOrdering(compare(x)(y)); + c = fromOrdering(compare(x)(y)) || i - j; if (c > 0) { xs1[k++] = y; ++j; From 5524a9fa3d0194523e87e25cf385adbfd3b63a26 Mon Sep 17 00:00:00 2001 From: Peter Murphy Date: Mon, 28 Dec 2020 08:07:19 -0500 Subject: [PATCH 4/9] Add ST tests, simplify sortByImpl fix --- src/Data/Array.js | 8 +------- src/Data/Array/ST.js | 6 ------ test/Test/Data/Array/ST.purs | 14 ++++++++++++++ 3 files changed, 15 insertions(+), 13 deletions(-) diff --git a/src/Data/Array.js b/src/Data/Array.js index 54881814..a31c6f90 100644 --- a/src/Data/Array.js +++ b/src/Data/Array.js @@ -290,17 +290,11 @@ exports.sortByImpl = (function () { while (i < mid && j < to) { x = xs2[i]; y = xs2[j]; - c = fromOrdering(compare(x)(y)) || i - j; + c = fromOrdering(compare(x)(y)); if (c > 0) { xs1[k++] = y; ++j; } - else if (c === 0) { - xs1[k++] = x; - xs1[k++] = y; - ++i; - ++j; - } else { xs1[k++] = x; ++i; diff --git a/src/Data/Array/ST.js b/src/Data/Array/ST.js index 26fa9166..701010c5 100644 --- a/src/Data/Array/ST.js +++ b/src/Data/Array/ST.js @@ -123,12 +123,6 @@ exports.sortByImpl = (function () { xs1[k++] = y; ++j; } - else if (c === 0) { - xs1[k++] = x; - xs1[k++] = y; - ++i; - ++j; - } else { xs1[k++] = x; ++i; diff --git a/test/Test/Data/Array/ST.purs b/test/Test/Data/Array/ST.purs index 49fab239..8a83cd99 100644 --- a/test/Test/Data/Array/ST.purs +++ b/test/Test/Data/Array/ST.purs @@ -3,10 +3,12 @@ module Test.Data.Array.ST (testArrayST) where import Prelude import Control.Monad.ST as ST +import Data.Array (range) import Data.Array.ST (withArray) import Data.Array.ST as STA import Data.Foldable (all) import Data.Maybe (Maybe(..), isNothing) +import Data.Tuple (Tuple(..), fst) import Effect (Effect) import Effect.Console (log) import Test.Assert (assert) @@ -234,11 +236,23 @@ testArrayST = do STA.sortBy (flip compare) =<< STA.unsafeThaw [1, 3, 2, 5, 6, 4] ) == [6, 5, 4, 3, 2, 1] + log "sortBy should not reorder elements that are equal according to a comparison function" + let s1 = map (Tuple "a") (range 1 100) + assert $ STA.run ( + STA.sortBy (comparing fst) =<< STA.unsafeThaw s1 + ) == s1 + log "sortWith should reorder a list into ascending order based on the result of compare over a projection" assert $ STA.run ( STA.sortWith identity =<< STA.unsafeThaw [1, 3, 2, 5, 6, 4] ) == [1, 2, 3, 4, 5, 6] + log "sortWith should not reorder elements that are equal according to a projection" + let s2 = map (Tuple "a") (range 1 100) + assert $ STA.run ( + STA.sortWith fst =<< STA.unsafeThaw s2 + ) == s2 + log "splice should be able to delete multiple items at a specified index" assert $ STA.run (do From 23ab0fae37d67eaf152b93e2714d150c2e1343ee Mon Sep 17 00:00:00 2001 From: Peter Murphy Date: Mon, 28 Dec 2020 08:20:10 -0500 Subject: [PATCH 5/9] Add note about stability to documentation --- src/Data/Array.purs | 6 +++++- src/Data/Array/ST.purs | 10 +++++++--- 2 files changed, 12 insertions(+), 4 deletions(-) diff --git a/src/Data/Array.purs b/src/Data/Array.purs index 17e5e804..c0c68b9a 100644 --- a/src/Data/Array.purs +++ b/src/Data/Array.purs @@ -790,6 +790,7 @@ foreign import scanr :: forall a b. (a -> b -> b) -> b -> Array a -> Array b -------------------------------------------------------------------------------- -- | Sort the elements of an array in increasing order, creating a new array. +-- | Sorting is stable: the order of equal elements is preserved. -- | -- | ```purescript -- | sort [2, -3, 1] = [-3, 1, 2] @@ -800,6 +801,8 @@ sort xs = sortBy compare xs -- | Sort the elements of an array in increasing order, where elements are -- | compared using the specified partial ordering, creating a new array. +-- | Sorting is stable: the order of elements is preserved if they are equal +-- | according to the specified partial ordering. -- | -- | ```purescript -- | compareLength a b = compare (length a) (length b) @@ -813,7 +816,8 @@ sortBy comp = sortByImpl comp case _ of LT -> -1 -- | Sort the elements of an array in increasing order, where elements are --- | sorted based on a projection +-- | sorted based on a projection. Sorting is stable: the order of elements is +-- | preserved if they are equal according to the projection. -- | -- | ```purescript -- | sortWith (_.age) [{name: "Alice", age: 42}, {name: "Bob", age: 21}] diff --git a/src/Data/Array/ST.purs b/src/Data/Array/ST.purs index 15bc6909..2726dd24 100644 --- a/src/Data/Array/ST.purs +++ b/src/Data/Array/ST.purs @@ -86,7 +86,8 @@ empty = new -- | Create a mutable copy of an immutable array. foreign import thaw :: forall h a. Array a -> ST h (STArray h a) --- | Sort a mutable array in place. +-- | Sort a mutable array in place. Sorting is stable: the order of equal +-- | elements is preserved. sort :: forall a h. Ord a => STArray h a -> ST h (STArray h a) sort = sortBy compare @@ -101,7 +102,9 @@ foreign import shiftImpl -> STArray h a -> ST h (Maybe a) --- | Sort a mutable array in place using a comparison function. +-- | Sort a mutable array in place using a comparison function. Sorting is +-- | stable: the order of elements is preserved if they are equal according to +-- | the comparison function. sortBy :: forall a h . (a -> a -> Ordering) @@ -119,7 +122,8 @@ foreign import sortByImpl -> STArray h a -> ST h (STArray h a) --- | Sort a mutable array in place based on a projection. +-- | Sort a mutable array in place based on a projection. Sorting is stable: the +-- | order of elements is preserved if they are equal according to the projection. sortWith :: forall a b h . Ord b From cb67fbc2a6f04a70a8143efcb96add0b90988680 Mon Sep 17 00:00:00 2001 From: Jordan Martinez Date: Mon, 28 Dec 2020 09:01:28 -0800 Subject: [PATCH 6/9] Fix compiler warning: replace `STA.empty` with `STA.new` --- src/Data/Array.purs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/Data/Array.purs b/src/Data/Array.purs index c0c68b9a..8e8e9306 100644 --- a/src/Data/Array.purs +++ b/src/Data/Array.purs @@ -611,7 +611,7 @@ intersperse a arr = case length arr of len | len < 2 -> arr | otherwise -> STA.run do let unsafeGetElem idx = unsafePartial (unsafeIndex arr idx) - out <- STA.empty + out <- STA.new _ <- STA.push (unsafeGetElem 0) out ST.for 1 len \idx -> do _ <- STA.push a out From 66486f1130493bbaa870a340cb344f7eeb607247 Mon Sep 17 00:00:00 2001 From: Jordan Martinez Date: Mon, 28 Dec 2020 16:39:43 -0800 Subject: [PATCH 7/9] Merge remote-tracking branch 'upstream/master' into pm/sort-stability-tests --- src/Data/Array.purs | 14 ++++----- src/Data/Array/NonEmpty.purs | 49 ++++++++++++++++++++++++++++++ test/Test/Data/Array.purs | 7 +++-- test/Test/Data/Array/NonEmpty.purs | 22 ++++++++++++++ 4 files changed, 82 insertions(+), 10 deletions(-) diff --git a/src/Data/Array.purs b/src/Data/Array.purs index 8e8e9306..86e8b50d 100644 --- a/src/Data/Array.purs +++ b/src/Data/Array.purs @@ -963,10 +963,10 @@ group xs = groupBy eq xs -- | groupAll [1, 1, 2, 2, 1] == [NonEmptyArray [1, 1, 1], NonEmptyArray [2, 2]] -- | ``` groupAll :: forall a. Ord a => Array a -> Array (NonEmptyArray a) -groupAll = groupAllBy eq +groupAll = groupAllBy compare -- | Deprecated previous name of `groupAll`. -group' :: forall a. Warn (Text "'group\'' is deprecated, use groupAll instead") => Ord a => Array a -> Array (NonEmptyArray a) +group' :: forall a. Warn (Text "'group\'' is deprecated, use 'groupAll' instead") => Ord a => Array a -> Array (NonEmptyArray a) group' = groupAll -- | Group equal, consecutive elements of an array into arrays, using the @@ -991,15 +991,15 @@ groupBy op xs = STA.unsafeFreeze result -- | Group equal elements of an array into arrays, using the specified --- | equivalence relation to determine equality. +-- | comparison function to determine equality. -- | -- | ```purescript --- | groupAllBy (\a b -> odd a && odd b) [1, 3, 2, 4, 3, 3] --- | = [NonEmptyArray [1], NonEmptyArray [2], NonEmptyArray [3, 3, 3], NonEmptyArray [4]] +-- | groupAllBy (comparing Down) [1, 3, 2, 4, 3, 3] +-- | = [NonEmptyArray [4], NonEmptyArray [3, 3, 3], NonEmptyArray [2], NonEmptyArray [1]] -- | ``` -- | -groupAllBy :: forall a. Ord a => (a -> a -> Boolean) -> Array a -> Array (NonEmptyArray a) -groupAllBy p = groupBy p <<< sort +groupAllBy :: forall a. (a -> a -> Ordering) -> Array a -> Array (NonEmptyArray a) +groupAllBy cmp = groupBy (\x y -> cmp x y == EQ) <<< sortBy cmp -- | Remove the duplicates from an array, creating a new array. -- | diff --git a/src/Data/Array/NonEmpty.purs b/src/Data/Array/NonEmpty.purs index be90f846..bbc51af8 100644 --- a/src/Data/Array/NonEmpty.purs +++ b/src/Data/Array/NonEmpty.purs @@ -65,6 +65,11 @@ module Data.Array.NonEmpty , dropEnd , dropWhile , span + , group + , groupAll + , group' + , groupBy + , groupAllBy , nub , nubBy @@ -115,6 +120,7 @@ import Data.Tuple (Tuple(..)) import Data.Unfoldable (class Unfoldable) import Data.Unfoldable1 (class Unfoldable1, unfoldr1) import Partial.Unsafe (unsafePartial) +import Prim.TypeError (class Warn, Text) import Unsafe.Coerce (unsafeCoerce) -- | Internal - adapt an Array transform to NonEmptyArray @@ -347,6 +353,49 @@ span -> { init :: Array a, rest :: Array a } span f = adaptAny $ A.span f +-- | Group equal, consecutive elements of an array into arrays. +-- | +-- | ```purescript +-- | group (NonEmptyArray [1, 1, 2, 2, 1]) == +-- | NonEmptyArray [NonEmptyArray [1, 1], NonEmptyArray [2, 2], NonEmptyArray [1]] +-- | ``` +group :: forall a. Eq a => NonEmptyArray a -> NonEmptyArray (NonEmptyArray a) +group = unsafeAdapt $ A.group + +-- | Group equal elements of an array into arrays. +-- | +-- | ```purescript +-- | groupAll (NonEmptyArray [1, 1, 2, 2, 1]) == +-- | NonEmptyArray [NonEmptyArray [1, 1, 1], NonEmptyArray [2, 2]] +-- | ` +groupAll :: forall a. Ord a => NonEmptyArray a -> NonEmptyArray (NonEmptyArray a) +groupAll = groupAllBy compare + +-- | Deprecated previous name of `groupAll`. +group' :: forall a. Warn (Text "'group\'' is deprecated, use 'groupAll' instead") => Ord a => NonEmptyArray a -> NonEmptyArray (NonEmptyArray a) +group' = unsafeAdapt $ A.groupAll + +-- | Group equal, consecutive elements of an array into arrays, using the +-- | specified equivalence relation to determine equality. +-- | +-- | ```purescript +-- | groupBy (\a b -> odd a && odd b) (NonEmptyArray [1, 3, 2, 4, 3, 3]) +-- | = NonEmptyArray [NonEmptyArray [1, 3], NonEmptyArray [2], NonEmptyArray [4], NonEmptyArray [3, 3]] +-- | ``` +-- | +groupBy :: forall a. (a -> a -> Boolean) -> NonEmptyArray a -> NonEmptyArray (NonEmptyArray a) +groupBy op = unsafeAdapt $ A.groupBy op + +-- | Group equal elements of an array into arrays, using the specified +-- | comparison function to determine equality. +-- | +-- | ```purescript +-- | groupAllBy (comparing Down) (NonEmptyArray [1, 3, 2, 4, 3, 3]) +-- | = NonEmptyArray [NonEmptyArray [4], NonEmptyArray [3, 3, 3], NonEmptyArray [2], NonEmptyArray [1]] +-- | ``` +groupAllBy :: forall a. (a -> a -> Ordering) -> NonEmptyArray a -> NonEmptyArray (NonEmptyArray a) +groupAllBy op = unsafeAdapt $ A.groupAllBy op + nub :: forall a. Ord a => NonEmptyArray a -> NonEmptyArray a nub = unsafeAdapt A.nub diff --git a/test/Test/Data/Array.purs b/test/Test/Data/Array.purs index cbd59ea3..5621ed95 100644 --- a/test/Test/Data/Array.purs +++ b/test/Test/Data/Array.purs @@ -9,6 +9,7 @@ import Data.Const (Const(..)) import Data.Foldable (for_, foldMapDefaultR, class Foldable, all, traverse_) import Data.Traversable (scanl, scanr) import Data.Maybe (Maybe(..), isNothing, fromJust) +import Data.Ord.Down (Down(..)) import Data.Tuple (Tuple(..), fst) import Data.Unfoldable (replicateA) import Effect (Effect) @@ -370,11 +371,11 @@ testArray = do log "groupBy should be stable" assert $ A.groupBy (\_ _ -> true) [1, 2, 3] == [nea [1, 2, 3]] - log "groupAllBy should group equal elements into arrays based on an equivalence relation" - assert $ A.groupAllBy (\x y -> odd x && odd y) [1, 3, 2, 4, 3, 3] == [nea [1], nea [2], nea [3, 3, 3], nea [4]] + log "groupAllBy should group equal elements into arrays based on the result of a comparison function" + assert $ A.groupAllBy (comparing Down) [1, 3, 2, 4, 3, 3] == [nea [4], nea [3, 3, 3], nea [2], nea [1]] log "groupAllBy should be stable" - assert $ A.groupAllBy (\_ _ -> true) [1, 2, 3] == [nea [1, 2, 3]] + assert $ A.groupAllBy (\_ _ -> EQ) [1, 2, 3] == [nea [1, 2, 3]] log "nub should remove duplicate elements from the list, keeping the first occurence" assert $ A.nub [1, 2, 2, 3, 4, 1] == [1, 2, 3, 4] diff --git a/test/Test/Data/Array/NonEmpty.purs b/test/Test/Data/Array/NonEmpty.purs index adacacc7..cb183df1 100644 --- a/test/Test/Data/Array/NonEmpty.purs +++ b/test/Test/Data/Array/NonEmpty.purs @@ -10,6 +10,7 @@ import Data.FunctorWithIndex (mapWithIndex) import Data.Maybe (Maybe(..), fromJust) import Data.Monoid.Additive (Additive(..)) import Data.NonEmpty ((:|)) +import Data.Ord.Down (Down(..)) import Data.Semigroup.Foldable (foldMap1, foldr1, foldl1) import Data.Semigroup.Traversable (traverse1) import Data.Tuple (Tuple(..)) @@ -25,6 +26,9 @@ testNonEmptyArray = do let fromArray :: forall a. Array a -> NEA.NonEmptyArray a fromArray = unsafePartial fromJust <<< NEA.fromArray + nea :: forall a. Array a -> NEA.NonEmptyArray a + nea = fromArray + log "singleton should construct an array with a single value" assert $ NEA.toArray (NEA.singleton 1) == [1] assert $ NEA.toArray (NEA.singleton "foo") == ["foo"] @@ -244,6 +248,24 @@ testNonEmptyArray = do let oneToSeven = fromArray [1, 2, 3, 4, 5, 6, 7] testSpan { p: (_ < 4), input: oneToSeven, init_: [1, 2, 3], rest_: [4, 5, 6, 7] } + log "group should group consecutive equal elements into arrays" + assert $ NEA.group (fromArray [1, 2, 2, 3, 3, 3, 1]) == fromArray [NEA.singleton 1, fromArray [2, 2], fromArray [3, 3, 3], NEA.singleton 1] + + log "groupAll should group equal elements into arrays" + assert $ NEA.groupAll (fromArray [1, 2, 2, 3, 3, 3, 1]) == fromArray [fromArray [1, 1], fromArray [2, 2], fromArray [3, 3, 3]] + + log "groupBy should group consecutive equal elements into arrays based on an equivalence relation" + assert $ NEA.groupBy (\x y -> odd x && odd y) (fromArray [1, 1, 2, 2, 3, 3]) == fromArray [fromArray [1, 1], NEA.singleton 2, NEA.singleton 2, fromArray [3, 3]] + + log "groupBy should be stable" + assert $ NEA.groupBy (\_ _ -> true) (fromArray [1, 2, 3]) == fromArray [fromArray [1, 2, 3]] + + log "groupAllBy should group equal elements into arrays based on the result of a comparison function" + assert $ NEA.groupAllBy (comparing Down) (fromArray [1, 3, 2, 4, 3, 3]) == fromArray [nea [4], nea [3, 3, 3], nea [2], nea [1]] + + log "groupAllBy should be stable" + assert $ NEA.groupAllBy (\_ _ -> EQ) (fromArray [1, 2, 3]) == fromArray [nea [1, 2, 3]] + log "nub should remove duplicate elements from the list, keeping the first occurence" assert $ NEA.nub (fromArray [1, 2, 2, 3, 4, 1]) == fromArray [1, 2, 3, 4] From abacd36cbd5b437eee7fa4b46bed628bca93d9ad Mon Sep 17 00:00:00 2001 From: Jordan Martinez Date: Mon, 28 Dec 2020 19:10:05 -0800 Subject: [PATCH 8/9] Remove fold1 member in NonEmptyArray's Foldable1 instance --- src/Data/Array/NonEmpty/Internal.purs | 1 - 1 file changed, 1 deletion(-) diff --git a/src/Data/Array/NonEmpty/Internal.purs b/src/Data/Array/NonEmpty/Internal.purs index f3286cd4..38f0f59b 100644 --- a/src/Data/Array/NonEmpty/Internal.purs +++ b/src/Data/Array/NonEmpty/Internal.purs @@ -49,7 +49,6 @@ derive newtype instance foldableWithIndexNonEmptyArray :: FoldableWithIndex Int instance foldable1NonEmptyArray :: Foldable1 NonEmptyArray where foldMap1 = foldMap1Default - fold1 = foldl1Impl (<>) foldr1 = foldr1Impl foldl1 = foldl1Impl From f41b2c299a4b46edf16822ea2ab802ef97d9d947 Mon Sep 17 00:00:00 2001 From: Jordan Martinez Date: Mon, 28 Dec 2020 19:10:52 -0800 Subject: [PATCH 9/9] Update foldMap1Default with left version --- src/Data/Array/NonEmpty/Internal.purs | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/src/Data/Array/NonEmpty/Internal.purs b/src/Data/Array/NonEmpty/Internal.purs index 38f0f59b..1dcd1bf1 100644 --- a/src/Data/Array/NonEmpty/Internal.purs +++ b/src/Data/Array/NonEmpty/Internal.purs @@ -15,7 +15,7 @@ import Data.Foldable (class Foldable) import Data.FoldableWithIndex (class FoldableWithIndex) import Data.FunctorWithIndex (class FunctorWithIndex) import Data.Ord (class Ord1) -import Data.Semigroup.Foldable (class Foldable1, foldMap1Default) +import Data.Semigroup.Foldable (class Foldable1, foldMap1DefaultL) import Data.Semigroup.Traversable (class Traversable1, sequence1Default) import Data.Traversable (class Traversable) import Data.TraversableWithIndex (class TraversableWithIndex) @@ -48,7 +48,7 @@ derive newtype instance foldableNonEmptyArray :: Foldable NonEmptyArray derive newtype instance foldableWithIndexNonEmptyArray :: FoldableWithIndex Int NonEmptyArray instance foldable1NonEmptyArray :: Foldable1 NonEmptyArray where - foldMap1 = foldMap1Default + foldMap1 = foldMap1DefaultL foldr1 = foldr1Impl foldl1 = foldl1Impl