@@ -2,11 +2,17 @@ module Data.Semigroup.Foldable
2
2
( class Foldable1
3
3
, foldMap1
4
4
, fold1
5
+ , foldr1
6
+ , foldl1
5
7
, traverse1_
6
8
, for1_
7
9
, sequence1_
8
10
, foldMap1Default
9
11
, fold1Default
12
+ , fold1DefaultR
13
+ , fold1DefaultL
14
+ , foldr1Default
15
+ , foldl1Default
10
16
, intercalate
11
17
, intercalateMap
12
18
, maximum
@@ -18,42 +24,70 @@ import Prelude
18
24
import Data.Foldable (class Foldable )
19
25
import Data.Monoid.Dual (Dual (..))
20
26
import Data.Monoid.Multiplicative (Multiplicative (..))
21
- import Data.Newtype (ala )
27
+ import Data.Newtype (ala , alaF )
22
28
import Data.Ord.Max (Max (..))
23
29
import Data.Ord.Min (Min (..))
24
30
25
31
-- | `Foldable1` represents data structures with a minimum of one element that can be _folded_.
26
32
-- |
27
33
-- | - `fold1` folds a structure using a `Semigroup` instance
28
34
-- | - `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
29
37
-- |
30
38
-- | Default implementations are provided by the following functions:
31
39
-- |
32
40
-- | - `fold1Default`
41
+ -- | - `fold1DefaultR`
42
+ -- | - `fold1DefaultL`
33
43
-- | - `foldMap1Default`
44
+ -- | - `foldr1Default`
45
+ -- | - `foldl1Default`
34
46
-- |
35
47
-- | Note: some combinations of the default implementations are unsafe to
36
48
-- | use together - causing a non-terminating mutually recursive cycle.
37
49
-- | These combinations are documented per function.
38
50
class Foldable t <= Foldable1 t where
39
51
foldMap1 :: forall a m . Semigroup m => (a -> m ) -> t a -> m
40
52
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
41
55
42
56
-- | A default implementation of `fold1` using `foldMap1`.
43
57
fold1Default :: forall t m . Foldable1 t => Semigroup m => t m -> m
44
58
fold1Default = foldMap1 identity
45
59
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
+
46
68
-- | A default implementation of `foldMap1` using `fold1`.
47
69
foldMap1Default :: forall t m a . Foldable1 t => Functor t => Semigroup m => (a -> m ) -> t a -> m
48
70
foldMap1Default f = (map f) >>> fold1
49
71
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
+
50
80
instance foldableDual :: Foldable1 Dual where
51
81
foldMap1 f (Dual x) = f x
52
82
fold1 = fold1Default
83
+ foldr1 _ (Dual x) = x
84
+ foldl1 _ (Dual x) = x
53
85
54
86
instance foldableMultiplicative :: Foldable1 Multiplicative where
55
87
foldMap1 f (Multiplicative x) = f x
56
88
fold1 = fold1Default
89
+ foldr1 _ (Multiplicative x) = x
90
+ foldl1 _ (Multiplicative x) = x
57
91
58
92
newtype Act :: forall k . (k -> Type ) -> k -> Type
59
93
newtype Act f a = Act (f a )
@@ -110,3 +144,15 @@ intercalateMap
110
144
=> m -> (a -> m ) -> f a -> m
111
145
intercalateMap j f foldable =
112
146
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