@@ -2,11 +2,17 @@ module Data.Semigroup.Foldable
22 ( class Foldable1
33 , foldMap1
44 , fold1
5+ , foldr1
6+ , foldl1
57 , traverse1_
68 , for1_
79 , sequence1_
810 , foldMap1Default
911 , fold1Default
12+ , fold1DefaultR
13+ , fold1DefaultL
14+ , foldr1Default
15+ , foldl1Default
1016 , intercalate
1117 , intercalateMap
1218 , maximum
@@ -18,42 +24,70 @@ import Prelude
1824import Data.Foldable (class Foldable )
1925import Data.Monoid.Dual (Dual (..))
2026import Data.Monoid.Multiplicative (Multiplicative (..))
21- import Data.Newtype (ala )
27+ import Data.Newtype (ala , alaF )
2228import Data.Ord.Max (Max (..))
2329import Data.Ord.Min (Min (..))
2430
2531-- | `Foldable1` represents data structures with a minimum of one element that can be _folded_.
2632-- |
2733-- | - `fold1` folds a structure using a `Semigroup` instance
2834-- | - `foldMap1` folds a structure by accumulating values in a `Semigroup`
35+ -- | - `foldr1` folds a structure from the right
36+ -- | - `foldl1` folds a structure from the left
2937-- |
3038-- | Default implementations are provided by the following functions:
3139-- |
3240-- | - `fold1Default`
41+ -- | - `fold1DefaultR`
42+ -- | - `fold1DefaultL`
3343-- | - `foldMap1Default`
44+ -- | - `foldr1Default`
45+ -- | - `foldl1Default`
3446-- |
3547-- | Note: some combinations of the default implementations are unsafe to
3648-- | use together - causing a non-terminating mutually recursive cycle.
3749-- | These combinations are documented per function.
3850class Foldable t <= Foldable1 t where
3951 foldMap1 :: forall a m . Semigroup m => (a -> m ) -> t a -> m
4052 fold1 :: forall m . Semigroup m => t m -> m
53+ foldr1 :: forall a . (a -> a -> a ) -> t a -> a
54+ foldl1 :: forall a . (a -> a -> a ) -> t a -> a
4155
4256-- | A default implementation of `fold1` using `foldMap1`.
4357fold1Default :: forall t m . Foldable1 t => Semigroup m => t m -> m
4458fold1Default = foldMap1 identity
4559
60+ -- | A default implementation of `fold1` using `foldr1`.
61+ fold1DefaultR :: forall t m . Foldable1 t => Semigroup m => t m -> m
62+ fold1DefaultR = foldr1 append
63+
64+ -- | A default implementation of `fold1` using `foldl1`.
65+ fold1DefaultL :: forall t m . Foldable1 t => Semigroup m => t m -> m
66+ fold1DefaultL = foldl1 append
67+
4668-- | A default implementation of `foldMap1` using `fold1`.
4769foldMap1Default :: forall t m a . Foldable1 t => Functor t => Semigroup m => (a -> m ) -> t a -> m
4870foldMap1Default f = (map f) >>> fold1
4971
72+ -- | A default implementation of `foldr1` using `foldMap1`.
73+ foldr1Default :: forall t a . Foldable1 t => (a -> a -> a ) -> t a -> a
74+ foldr1Default = flip (runFoldRight1 <<< foldMap1 mkFoldRight1)
75+
76+ -- | A default implementation of `foldl1` using `foldMap1`.
77+ foldl1Default :: forall t a . Foldable1 t => (a -> a -> a ) -> t a -> a
78+ foldl1Default = flip (runFoldRight1 <<< alaF Dual foldMap1 mkFoldRight1) <<< flip
79+
5080instance foldableDual :: Foldable1 Dual where
5181 foldMap1 f (Dual x) = f x
5282 fold1 = fold1Default
83+ foldr1 _ (Dual x) = x
84+ foldl1 _ (Dual x) = x
5385
5486instance foldableMultiplicative :: Foldable1 Multiplicative where
5587 foldMap1 f (Multiplicative x) = f x
5688 fold1 = fold1Default
89+ foldr1 _ (Multiplicative x) = x
90+ foldl1 _ (Multiplicative x) = x
5791
5892newtype Act :: forall k . (k -> Type ) -> k -> Type
5993newtype Act f a = Act (f a )
@@ -110,3 +144,15 @@ intercalateMap
110144 => m -> (a -> m ) -> f a -> m
111145intercalateMap j f foldable =
112146 joinee (foldMap1 (JoinWith <<< const <<< f) foldable) j
147+
148+ -- | Internal. Used by foldr1Default and foldl1Default.
149+ data FoldRight1 a = FoldRight1 (a -> (a -> a -> a ) -> a ) a
150+
151+ instance foldRight1Semigroup :: Semigroup (FoldRight1 a ) where
152+ append (FoldRight1 lf lr) (FoldRight1 rf rr) = FoldRight1 (\a f -> lf (f lr (rf a f)) f) rr
153+
154+ mkFoldRight1 :: forall a . a -> FoldRight1 a
155+ mkFoldRight1 = FoldRight1 const
156+
157+ runFoldRight1 :: forall a . FoldRight1 a -> (a -> a -> a ) -> a
158+ runFoldRight1 (FoldRight1 f a) = f a
0 commit comments