Skip to content

Commit f8cb763

Browse files
committed
Documented defaults and non-termination issue.
* Added to the docs of `Foldable` type class - Mentioned default implementations - Made a note about the non-termination issue * Annotated each default `Foldable` function - Noted which function combinations are unsafe * Added to the docs of `Traversable` type class - Mentioned the defaults to be consistent with `Foldable` * Regenerated docs
1 parent c0af6b6 commit f8cb763

File tree

4 files changed

+56
-0
lines changed

4 files changed

+56
-0
lines changed

docs/Data/Foldable.md

Lines changed: 23 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -15,6 +15,17 @@ class Foldable f where
1515
- `foldl` folds a structure from the left
1616
- `foldMap` folds a structure by accumulating values in a `Monoid`
1717

18+
Default implementations are provided by the following functions:
19+
20+
- `foldrDefault`
21+
- `foldlDefault`
22+
- `foldMapDefaultL`
23+
- `foldMapDefaultR`
24+
25+
Note: that some combinations of the default implementations are unsafe to
26+
use together - causing a non-terminating mutually recursive cycle.
27+
These combinations are documented per function.
28+
1829
##### Instances
1930
``` purescript
2031
instance foldableArray :: Foldable Array
@@ -36,6 +47,9 @@ foldrDefault :: forall f a b. (Foldable f) => (a -> b -> b) -> b -> f a -> b
3647

3748
A default implementation of `foldr` using `foldMap`
3849

50+
Note: when defining a `Foldable` instance, this function is unsafe to use
51+
in combination with `foldMapDefaultR`.
52+
3953
#### `foldlDefault`
4054

4155
``` purescript
@@ -44,6 +58,9 @@ foldlDefault :: forall f a b. (Foldable f) => (b -> a -> b) -> b -> f a -> b
4458

4559
A default implementation of `foldl` using `foldMap`
4660

61+
Note: when defining a `Foldable` instance, this function is unsafe to use
62+
in combination with `foldMapDefaultL`.
63+
4764
#### `foldMapDefaultL`
4865

4966
``` purescript
@@ -52,6 +69,9 @@ foldMapDefaultL :: forall f a m. (Foldable f, Monoid m) => (a -> m) -> f a -> m
5269

5370
A default implementation of `foldMap` using `foldl`
5471

72+
Note: when defining a `Foldable` instance, this function is unsafe to use
73+
in combination with `foldlDefault`.
74+
5575
#### `foldMapDefaultR`
5676

5777
``` purescript
@@ -60,6 +80,9 @@ foldMapDefaultR :: forall f a m. (Foldable f, Monoid m) => (a -> m) -> f a -> m
6080

6181
A default implementation of `foldMap` using `foldr`
6282

83+
Note: when defining a `Foldable` instance, this function is unsafe to use
84+
in combination with `foldrDefault`.
85+
6386
#### `fold`
6487

6588
``` purescript

docs/Data/Traversable.md

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -27,6 +27,11 @@ following sense:
2727

2828
- `foldMap f = runConst <<< traverse (Const <<< f)`
2929

30+
Default implementations are provided by the following functions:
31+
32+
- `traverseDefault`
33+
- `sequenceDefault`
34+
3035
##### Instances
3136
``` purescript
3237
instance traversableArray :: Traversable Array

src/Data/Foldable.purs

Lines changed: 23 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -37,28 +37,51 @@ import Data.Monoid.Multiplicative (Multiplicative(..))
3737
-- | - `foldr` folds a structure from the right
3838
-- | - `foldl` folds a structure from the left
3939
-- | - `foldMap` folds a structure by accumulating values in a `Monoid`
40+
-- |
41+
-- | Default implementations are provided by the following functions:
42+
-- |
43+
-- | - `foldrDefault`
44+
-- | - `foldlDefault`
45+
-- | - `foldMapDefaultL`
46+
-- | - `foldMapDefaultR`
47+
-- |
48+
-- | Note: that some combinations of the default implementations are unsafe to
49+
-- | use together - causing a non-terminating mutually recursive cycle.
50+
-- | These combinations are documented per function.
4051
class Foldable f where
4152
foldr :: forall a b. (a -> b -> b) -> b -> f a -> b
4253
foldl :: forall a b. (b -> a -> b) -> b -> f a -> b
4354
foldMap :: forall a m. (Monoid m) => (a -> m) -> f a -> m
4455

4556

4657
-- | A default implementation of `foldr` using `foldMap`
58+
-- |
59+
-- | Note: when defining a `Foldable` instance, this function is unsafe to use
60+
-- | in combination with `foldMapDefaultR`.
4761
foldrDefault :: forall f a b. (Foldable f) =>
4862
(a -> b -> b) -> b -> f a -> b
4963
foldrDefault c u xs = runEndo (foldMap (Endo <<< c) xs) u
5064

5165
-- | A default implementation of `foldl` using `foldMap`
66+
-- |
67+
-- | Note: when defining a `Foldable` instance, this function is unsafe to use
68+
-- | in combination with `foldMapDefaultL`.
5269
foldlDefault :: forall f a b. (Foldable f) =>
5370
(b -> a -> b) -> b -> f a -> b
5471
foldlDefault c u xs = runEndo (runDual (foldMap (Dual <<< Endo <<< flip c) xs)) u
5572

5673
-- | A default implementation of `foldMap` using `foldl`
74+
-- |
75+
-- | Note: when defining a `Foldable` instance, this function is unsafe to use
76+
-- | in combination with `foldlDefault`.
5777
foldMapDefaultL :: forall f a m. (Foldable f, Monoid m) =>
5878
(a -> m) -> f a -> m
5979
foldMapDefaultL f xs = foldl (\acc x -> f x <> acc) mempty xs
6080

6181
-- | A default implementation of `foldMap` using `foldr`
82+
-- |
83+
-- | Note: when defining a `Foldable` instance, this function is unsafe to use
84+
-- | in combination with `foldrDefault`.
6285
foldMapDefaultR :: forall f a m. (Foldable f, Monoid m) =>
6386
(a -> m) -> f a -> m
6487
foldMapDefaultR f xs = foldr (\x acc -> f x <> acc) mempty xs

src/Data/Traversable.purs

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -39,6 +39,11 @@ import Data.Monoid.Conj (Conj(..), runConj)
3939
-- | `Foldable` instances, in the following sense:
4040
-- |
4141
-- | - `foldMap f = runConst <<< traverse (Const <<< f)`
42+
-- |
43+
-- | Default implementations are provided by the following functions:
44+
-- |
45+
-- | - `traverseDefault`
46+
-- | - `sequenceDefault`
4247
class (Functor t, Foldable t) <= Traversable t where
4348
traverse :: forall a b m. (Applicative m) => (a -> m b) -> t a -> m (t b)
4449
sequence :: forall a m. (Applicative m) => t (m a) -> m (t a)

0 commit comments

Comments
 (0)