From 64be83764566a35653ad00bbdf1266a0b327bdba Mon Sep 17 00:00:00 2001 From: Ryan Hendrickson Date: Thu, 22 Oct 2020 01:11:14 -0400 Subject: [PATCH 1/2] Fix `Foldable1 (NonEmpty f)` instance --- src/Data/NonEmpty.purs | 11 +++++------ test/Main.purs | 5 +++-- 2 files changed, 8 insertions(+), 8 deletions(-) diff --git a/src/Data/NonEmpty.purs b/src/Data/NonEmpty.purs index 957b88c..c51cc3e 100644 --- a/src/Data/NonEmpty.purs +++ b/src/Data/NonEmpty.purs @@ -4,11 +4,11 @@ module Data.NonEmpty ( NonEmpty(..) , singleton , (:|) - , foldl1 , fromNonEmpty , oneOf , head , tail + , module Exports ) where import Prelude @@ -20,9 +20,10 @@ import Data.Eq (class Eq1) import Data.Foldable (class Foldable, foldl, foldr, foldMap) import Data.FoldableWithIndex (class FoldableWithIndex, foldMapWithIndex, foldlWithIndex, foldrWithIndex) import Data.FunctorWithIndex (class FunctorWithIndex, mapWithIndex) -import Data.Maybe (Maybe(..)) +import Data.Maybe (Maybe(..), maybe) import Data.Ord (class Ord1) import Data.Semigroup.Foldable (class Foldable1, foldMap1) +import Data.Semigroup.Foldable (foldl1) as Exports import Data.Traversable (class Traversable, traverse, sequence) import Data.TraversableWithIndex (class TraversableWithIndex, traverseWithIndex) import Data.Tuple (uncurry) @@ -46,10 +47,6 @@ infixr 5 NonEmpty as :| singleton :: forall f a. Plus f => a -> NonEmpty f a singleton a = a :| empty --- | Fold a non-empty structure, collecting results using a binary operation. -foldl1 :: forall f a. Foldable f => (a -> a -> a) -> NonEmpty f a -> a -foldl1 f (a :| fa) = foldl f a fa - fromNonEmpty :: forall f a r. (a -> f a -> r) -> NonEmpty f a -> r fromNonEmpty f (a :| fa) = a `f` fa @@ -107,6 +104,8 @@ instance traversableWithIndexNonEmpty instance foldable1NonEmpty :: Foldable f => Foldable1 (NonEmpty f) where fold1 = foldMap1 identity foldMap1 f (a :| fa) = foldl (\s a1 -> s <> f a1) (f a) fa + foldr1 f (a :| fa) = maybe a (f a) $ foldr (\a1 -> Just <<< maybe a1 (f a1)) Nothing fa + foldl1 f (a :| fa) = foldl f a fa instance unfoldable1NonEmpty :: Unfoldable f => Unfoldable1 (NonEmpty f) where unfoldr1 f b = uncurry (:|) $ unfoldr (map f) <$> f b diff --git a/test/Main.purs b/test/Main.purs index b0a7e9a..9e3fcac 100644 --- a/test/Main.purs +++ b/test/Main.purs @@ -5,7 +5,7 @@ import Prelude import Data.Foldable (fold, foldl) import Data.Maybe (Maybe(..)) import Data.NonEmpty (NonEmpty, (:|), foldl1, oneOf, head, tail, singleton) -import Data.Semigroup.Foldable (fold1) +import Data.Semigroup.Foldable (fold1, foldr1) import Data.Unfoldable1 as U1 import Effect (Effect) import Test.Assert (assert) @@ -19,7 +19,8 @@ main :: Effect Unit main = do assert $ singleton 0 == 0 :| [] assert $ 0 :| Nothing /= 0 :| Just 1 - assert $ foldl1 (+) (1 :| [2, 3]) == 6 + assert $ foldl1 (\l r -> "(" <> l <> r <> ")") ("a" :| ["b", "c", "d"]) == "(((ab)c)d)" + assert $ foldr1 (\l r -> "(" <> l <> r <> ")") ("a" :| ["b", "c", "d"]) == "(a(b(cd)))" assert $ foldl (+) 0 (1 :| [2, 3]) == 6 assert $ fold1 ("Hello" :| [" ", "World"]) == "Hello World" assert $ fold ("Hello" :| [" ", "World"]) == "Hello World" From 4e363202e02ab9406933a54a026484ea3fa7b7b7 Mon Sep 17 00:00:00 2001 From: Ryan Hendrickson Date: Thu, 22 Oct 2020 18:46:26 -0400 Subject: [PATCH 2/2] fixup! Fix `Foldable1 (NonEmpty f)` instance --- src/Data/NonEmpty.purs | 9 ++++++--- 1 file changed, 6 insertions(+), 3 deletions(-) diff --git a/src/Data/NonEmpty.purs b/src/Data/NonEmpty.purs index c51cc3e..9e5f75a 100644 --- a/src/Data/NonEmpty.purs +++ b/src/Data/NonEmpty.purs @@ -4,11 +4,11 @@ module Data.NonEmpty ( NonEmpty(..) , singleton , (:|) + , foldl1 , fromNonEmpty , oneOf , head , tail - , module Exports ) where import Prelude @@ -23,7 +23,6 @@ import Data.FunctorWithIndex (class FunctorWithIndex, mapWithIndex) import Data.Maybe (Maybe(..), maybe) import Data.Ord (class Ord1) import Data.Semigroup.Foldable (class Foldable1, foldMap1) -import Data.Semigroup.Foldable (foldl1) as Exports import Data.Traversable (class Traversable, traverse, sequence) import Data.TraversableWithIndex (class TraversableWithIndex, traverseWithIndex) import Data.Tuple (uncurry) @@ -47,6 +46,10 @@ infixr 5 NonEmpty as :| singleton :: forall f a. Plus f => a -> NonEmpty f a singleton a = a :| empty +-- | Fold a non-empty structure, collecting results using a binary operation. +foldl1 :: forall f a. Foldable f => (a -> a -> a) -> NonEmpty f a -> a +foldl1 f (a :| fa) = foldl f a fa + fromNonEmpty :: forall f a r. (a -> f a -> r) -> NonEmpty f a -> r fromNonEmpty f (a :| fa) = a `f` fa @@ -105,7 +108,7 @@ instance foldable1NonEmpty :: Foldable f => Foldable1 (NonEmpty f) where fold1 = foldMap1 identity foldMap1 f (a :| fa) = foldl (\s a1 -> s <> f a1) (f a) fa foldr1 f (a :| fa) = maybe a (f a) $ foldr (\a1 -> Just <<< maybe a1 (f a1)) Nothing fa - foldl1 f (a :| fa) = foldl f a fa + foldl1 = foldl1 instance unfoldable1NonEmpty :: Unfoldable f => Unfoldable1 (NonEmpty f) where unfoldr1 f b = uncurry (:|) $ unfoldr (map f) <$> f b