Skip to content

Commit 7eb6d33

Browse files
committed
Bifoldable and Bitraversable
1 parent c41075b commit 7eb6d33

File tree

6 files changed

+225
-1
lines changed

6 files changed

+225
-1
lines changed

README.md

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -14,3 +14,8 @@ bower install purescript-foldable-traversable
1414

1515
- [Data.Foldable](docs/Data.Foldable.md)
1616
- [Data.Traversable](docs/Data.Traversable.md)
17+
18+
## Bifunctors
19+
20+
- [Data.Bifoldable](docs/Data.Bifoldable.md)
21+
- [Data.Bitraversable](docs/Data.Bitraversable.md)

docs/Data.Bifoldable.md

Lines changed: 85 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,85 @@
1+
# Module Documentation
2+
3+
## Module Data.Bifoldable
4+
5+
#### `Bifoldable`
6+
7+
``` purescript
8+
class Bifoldable p where
9+
bifoldr :: forall a b c. (a -> c -> c) -> (b -> c -> c) -> c -> p a b -> c
10+
bifoldl :: forall a b c. (c -> a -> c) -> (c -> b -> c) -> c -> p a b -> c
11+
bifoldMap :: forall m a b. (Monoid m) => (a -> m) -> (b -> m) -> p a b -> m
12+
```
13+
14+
`Bifoldable` represents data structures with two type arguments which can be
15+
folded.
16+
17+
A fold for such a structure requires two step functions, one for each type
18+
argument. Type class instances should choose the appropriate step function based
19+
on the type of the element encountered at each point of the fold.
20+
21+
22+
#### `bifoldableTuple`
23+
24+
``` purescript
25+
instance bifoldableTuple :: Bifoldable Tuple
26+
```
27+
28+
29+
#### `bifoldableEither`
30+
31+
``` purescript
32+
instance bifoldableEither :: Bifoldable Either
33+
```
34+
35+
36+
#### `bifold`
37+
38+
``` purescript
39+
bifold :: forall t m. (Bifoldable t, Monoid m) => t m m -> m
40+
```
41+
42+
Fold a data structure, accumulating values in a monoidal type.
43+
44+
#### `bitraverse_`
45+
46+
``` purescript
47+
bitraverse_ :: forall t f a b c d. (Bifoldable t, Applicative f) => (a -> f c) -> (b -> f d) -> t a b -> f Unit
48+
```
49+
50+
Traverse a data structure, accumulating effects using an `Applicative` functor,
51+
ignoring the final result.
52+
53+
#### `bifor_`
54+
55+
``` purescript
56+
bifor_ :: forall t f a b c d. (Bifoldable t, Applicative f) => t a b -> (a -> f c) -> (b -> f d) -> f Unit
57+
```
58+
59+
A version of `bitraverse_` with the data structure as the first argument.
60+
61+
#### `bisequence_`
62+
63+
``` purescript
64+
bisequence_ :: forall t f a b. (Bifoldable t, Applicative f) => t (f a) (f b) -> f Unit
65+
```
66+
67+
Collapse a data structure, collecting effects using an `Applicative` functor,
68+
ignoring the final result.
69+
70+
#### `biany`
71+
72+
``` purescript
73+
biany :: forall t a b c. (Bifoldable t, BoundedLattice c) => (a -> c) -> (b -> c) -> t a b -> c
74+
```
75+
76+
Test whether a predicate holds at any position in a data structure.
77+
78+
#### `biall`
79+
80+
``` purescript
81+
biall :: forall t a b c. (Bifoldable t, BoundedLattice c) => (a -> c) -> (b -> c) -> t a b -> c
82+
```
83+
84+
85+

docs/Data.Bitraversable.md

Lines changed: 44 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,44 @@
1+
# Module Documentation
2+
3+
## Module Data.Bitraversable
4+
5+
#### `Bitraversable`
6+
7+
``` purescript
8+
class (Bifunctor t, Bifoldable t) <= Bitraversable t where
9+
bitraverse :: forall f a b c d. (Applicative f) => (a -> f c) -> (b -> f d) -> t a b -> f (t c d)
10+
bisequence :: forall f a b. (Applicative f) => t (f a) (f b) -> f (t a b)
11+
```
12+
13+
`Bitraversable` represents data structures with two type arguments which can be
14+
traversed.
15+
16+
A traversal for such a structure requires two functions, one for each type
17+
argument. Type class instances should choose the appropriate function based
18+
on the type of the element encountered at each point of the traversal.
19+
20+
21+
#### `bitraversableTuple`
22+
23+
``` purescript
24+
instance bitraversableTuple :: Bitraversable Tuple
25+
```
26+
27+
28+
#### `bitraversableEither`
29+
30+
``` purescript
31+
instance bitraversableEither :: Bitraversable Either
32+
```
33+
34+
35+
#### `bifor`
36+
37+
``` purescript
38+
bifor :: forall t f a b c d. (Bitraversable t, Applicative f) => t a b -> (a -> f c) -> (b -> f d) -> f (t c d)
39+
```
40+
41+
Traverse a data structure, accumulating effects and results using an `Applicative` functor.
42+
43+
44+

gulpfile.js

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -37,7 +37,7 @@ var docTask = function(name) {
3737
docTasks.push(taskName);
3838
};
3939

40-
["Data.Foldable", "Data.Traversable"].forEach(docTask);
40+
["Data.Foldable", "Data.Traversable", "Data.Bifoldable", "Data.Bitraversable"].forEach(docTask);
4141

4242
gulp.task("docs", docTasks);
4343

src/Data/Bifoldable.purs

Lines changed: 59 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,59 @@
1+
module Data.Bifoldable where
2+
3+
import Control.Apply ((*>))
4+
import Data.Either (Either(..))
5+
import Data.Monoid (Monoid)
6+
import Data.Monoid.Inf (Inf(..), runInf)
7+
import Data.Monoid.Sup (Sup(..), runSup)
8+
import Data.Tuple (Tuple(..))
9+
10+
-- | `Bifoldable` represents data structures with two type arguments which can be
11+
-- | folded.
12+
-- |
13+
-- | A fold for such a structure requires two step functions, one for each type
14+
-- | argument. Type class instances should choose the appropriate step function based
15+
-- | on the type of the element encountered at each point of the fold.
16+
-- |
17+
class Bifoldable p where
18+
bifoldr :: forall a b c. (a -> c -> c) -> (b -> c -> c) -> c -> p a b -> c
19+
bifoldl :: forall a b c. (c -> a -> c) -> (c -> b -> c) -> c -> p a b -> c
20+
bifoldMap :: forall m a b. (Monoid m) => (a -> m) -> (b -> m) -> p a b -> m
21+
22+
instance bifoldableTuple :: Bifoldable Tuple where
23+
bifoldMap f g (Tuple a b) = f a <> g b
24+
bifoldr f g z (Tuple a b) = f a (g b z)
25+
bifoldl f g z (Tuple a b) = g (f z a) b
26+
27+
instance bifoldableEither :: Bifoldable Either where
28+
bifoldMap f _ (Left a) = f a
29+
bifoldMap _ g (Right b) = g b
30+
bifoldr f _ z (Left a) = f a z
31+
bifoldr _ g z (Right b) = g b z
32+
bifoldl f _ z (Left a) = f z a
33+
bifoldl _ g z (Right b) = g z b
34+
35+
-- | Fold a data structure, accumulating values in a monoidal type.
36+
bifold :: forall t m. (Bifoldable t, Monoid m) => t m m -> m
37+
bifold = bifoldMap id id
38+
39+
-- | Traverse a data structure, accumulating effects using an `Applicative` functor,
40+
-- | ignoring the final result.
41+
bitraverse_ :: forall t f a b c d. (Bifoldable t, Applicative f) => (a -> f c) -> (b -> f d) -> t a b -> f Unit
42+
bitraverse_ f g = bifoldr ((*>) <<< f) ((*>) <<< g) (pure unit)
43+
44+
-- | A version of `bitraverse_` with the data structure as the first argument.
45+
bifor_ :: forall t f a b c d. (Bifoldable t, Applicative f) => t a b -> (a -> f c) -> (b -> f d) -> f Unit
46+
bifor_ t f g = bitraverse_ f g t
47+
48+
-- | Collapse a data structure, collecting effects using an `Applicative` functor,
49+
-- | ignoring the final result.
50+
bisequence_ :: forall t f a b. (Bifoldable t, Applicative f) => t (f a) (f b) -> f Unit
51+
bisequence_ = bitraverse_ id id
52+
53+
-- | Test whether a predicate holds at any position in a data structure.
54+
biany :: forall t a b c. (Bifoldable t, BoundedLattice c) => (a -> c) -> (b -> c) -> t a b -> c
55+
biany p q = runSup <<< bifoldMap (Sup <<< p) (Sup <<< q)
56+
57+
-- -- | Test whether a predicate holds at all positions in a data structure.
58+
biall :: forall t a b c. (Bifoldable t, BoundedLattice c) => (a -> c) -> (b -> c) -> t a b -> c
59+
biall p q = runInf <<< bifoldMap (Inf <<< p) (Inf <<< q)

src/Data/Bitraversable.purs

Lines changed: 31 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,31 @@
1+
module Data.Bitraversable where
2+
3+
import Data.Bifoldable
4+
import Data.Bifunctor (Bifunctor)
5+
import Data.Either (Either(..))
6+
import Data.Tuple (Tuple(..))
7+
8+
-- | `Bitraversable` represents data structures with two type arguments which can be
9+
-- | traversed.
10+
-- |
11+
-- | A traversal for such a structure requires two functions, one for each type
12+
-- | argument. Type class instances should choose the appropriate function based
13+
-- | on the type of the element encountered at each point of the traversal.
14+
-- |
15+
class (Bifunctor t, Bifoldable t) <= Bitraversable t where
16+
bitraverse :: forall f a b c d. (Applicative f) => (a -> f c) -> (b -> f d) -> t a b -> f (t c d)
17+
bisequence :: forall f a b. (Applicative f) => t (f a) (f b) -> f (t a b)
18+
19+
instance bitraversableTuple :: Bitraversable Tuple where
20+
bitraverse f g (Tuple a b) = Tuple <$> f a <*> g b
21+
bisequence (Tuple a b) = Tuple <$> a <*> b
22+
23+
instance bitraversableEither :: Bitraversable Either where
24+
bitraverse f _ (Left a) = Left <$> f a
25+
bitraverse _ g (Right b) = Right <$> g b
26+
bisequence (Left a) = Left <$> a
27+
bisequence (Right b) = Right <$> b
28+
29+
-- | Traverse a data structure, accumulating effects and results using an `Applicative` functor.
30+
bifor :: forall t f a b c d. (Bitraversable t, Applicative f) => t a b -> (a -> f c) -> (b -> f d) -> f (t c d)
31+
bifor t f g = bitraverse f g t

0 commit comments

Comments
 (0)