@@ -9,6 +9,7 @@ module Data.Semigroup.Foldable
9
9
, sequence1_
10
10
, foldr1Default
11
11
, foldl1Default
12
+ , foldMap1Default
12
13
, intercalate
13
14
, intercalateMap
14
15
, maximum
@@ -36,6 +37,11 @@ import Data.Ord.Min (Min(..))
36
37
-- |
37
38
-- | - `foldr1Default`
38
39
-- | - `foldl1Default`
40
+ -- | - `foldMap1Default`
41
+ -- |
42
+ -- | Note: some combinations of the default implementations are unsafe to
43
+ -- | use together - causing a non-terminating mutually recursive cycle.
44
+ -- | These combinations are documented per function.
39
45
class Foldable t <= Foldable1 t where
40
46
foldr1 :: forall a . (a -> a -> a ) -> t a -> a
41
47
foldl1 :: forall a . (a -> a -> a ) -> t a -> a
@@ -46,9 +52,19 @@ foldr1Default :: forall t a. Foldable1 t => (a -> a -> a) -> t a -> a
46
52
foldr1Default = flip (runFoldRight1 <<< foldMap1 mkFoldRight1)
47
53
48
54
-- | A default implementation of `foldl1` using `foldMap1`.
55
+ -- |
56
+ -- | Note: when defining a `Foldable1` instance, this function is unsafe to use
57
+ -- | in combination with `foldMap1Default`.
49
58
foldl1Default :: forall t a . Foldable1 t => (a -> a -> a ) -> t a -> a
50
59
foldl1Default = flip (runFoldRight1 <<< alaF Dual foldMap1 mkFoldRight1) <<< flip
51
60
61
+ -- | A default implementation of `foldMap1` using `foldl1`.
62
+ -- |
63
+ -- | Note: when defining a `Foldable1` instance, this function is unsafe to use
64
+ -- | in combination with `foldl1Default`.
65
+ foldMap1Default :: forall t m a . Foldable1 t => Functor t => Semigroup m => (a -> m ) -> t a -> m
66
+ foldMap1Default f = map f >>> foldl1 (<>)
67
+
52
68
instance foldableDual :: Foldable1 Dual where
53
69
foldr1 _ (Dual x) = x
54
70
foldl1 _ (Dual x) = x
0 commit comments