Skip to content

Commit 86565dd

Browse files
Tuple2 complete, changed Foldable instances
1 parent 9addc80 commit 86565dd

13 files changed

+477
-156
lines changed

.packages

+1-1
Original file line numberDiff line numberDiff line change
@@ -3,7 +3,7 @@
33
#
44
# For more info see: https://dart.dev/go/dot-packages-deprecation
55
#
6-
# Generated by pub on 2021-06-13 21:30:13.314180.
6+
# Generated by pub on 2021-06-15 19:06:22.469619.
77
_fe_analyzer_shared:file:///C:/Users/Sandro%20Maglione/AppData/Roaming/Pub/Cache/hosted/pub.dartlang.org/_fe_analyzer_shared-22.0.0/lib/
88
analyzer:file:///C:/Users/Sandro%20Maglione/AppData/Roaming/Pub/Cache/hosted/pub.dartlang.org/analyzer-1.7.0/lib/
99
args:file:///C:/Users/Sandro%20Maglione/AppData/Roaming/Pub/Cache/hosted/pub.dartlang.org/args-2.1.0/lib/

CHANGELOG.md

+6-2
Original file line numberDiff line numberDiff line change
@@ -1,9 +1,13 @@
1-
# v0.0.4
1+
# v0.0.4 - 15 June 2021
22

3-
- Renamed `fold` method of `Foldable` to `foldLeft` [**BREAKING CHANGE**]
43
- Completed `Unit` type documentation
54
- Completed `Task` type implementation, documentation, and testing
65
- Completed `TaskEither` type implementation, documentation, and testing
6+
- Completed implementation, documentation, and testing of `Foldable` instance on `Option` and `Either` [**BREAKING CHANGE**]
7+
- Completed `Tuple2` type implementation, documentation, and testing [**BREAKING CHANGE**]
8+
- Renamed `fold` method of `Foldable` to `foldLeft` [**BREAKING CHANGE**]
9+
- Updated methods API (`foldRight`, `foldLeft`, etc.) of `Foldable` instances (`Option`, `Either`, `Tuple`) [**BREAKING CHANGE**]
10+
- `IList` not longer working correctly (waiting for a [better solution for immutable collections](https://github.com/SandroMaglione/fpdart#roadmap)) [**BREAKING CHANGE**]
711

812
# v0.0.3 - 13 June 2021
913

README.md

+7-6
Original file line numberDiff line numberDiff line change
@@ -5,7 +5,7 @@
55
<img src="https://img.shields.io/github/stars/SandroMaglione/fpdart?logo=github" />
66
</a>
77
<img src="https://img.shields.io/github/license/SandroMaglione/fpdart?logo=github" />
8-
<img src="https://img.shields.io/badge/version-0.0.3-blue.svg" />
8+
<img src="https://img.shields.io/badge/version-0.0.4-blue.svg" />
99
<!-- <img src="https://img.shields.io/badge/flutter-v2.0.2-blue.svg" /> -->
1010
<img src="https://img.shields.io/badge/dart-v2.13.1-blue.svg" />
1111
<a href="https://github.com/SandroMaglione">
@@ -54,7 +54,7 @@ Fpdart is inspired by [fp-ts](https://gcanti.github.io/fp-ts/), [cats](https://t
5454
```yaml
5555
# pubspec.yaml
5656
dependencies:
57-
fpdart: ^0.0.3 # Check out the latest version
57+
fpdart: ^0.0.4 # Check out the latest version
5858
```
5959
6060
## Examples
@@ -204,10 +204,10 @@ The roadmap for types development is highlighted below (breaking changes to *'st
204204
- ~~Implementation~~
205205
- ~~Documentation~~
206206
- ~~Testing~~
207-
6. `Tuple`
208-
- Implementation
209-
- Documentation
210-
- Testing
207+
6. ~~`Tuple`~~
208+
- ~~Implementation~~
209+
- ~~Documentation~~
210+
- ~~Testing~~
211211
7. `State`
212212
- Implementation
213213
- Documentation
@@ -263,6 +263,7 @@ In general, any contribution or feedback is welcome (and encouraged!).
263263

264264
## Versioning
265265

266+
- v0.0.4 - 15 June 2021
266267
- v0.0.3 - 13 June 2021
267268
- v0.0.2 - 13 June 2021
268269
- v0.0.1 - 28 May 2021

lib/src/either.dart

+55-2
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,6 @@
11
import 'function.dart';
22
import 'option.dart';
3+
import 'tuple.dart';
34
import 'typeclass/typeclass.export.dart';
45

56
/// Tag the [HKT2] interface for the actual [Either].
@@ -19,6 +20,58 @@ abstract class Either<L, R> extends HKT2<_EitherHKT, L, R>
1920
Extend2<_EitherHKT, L, R> {
2021
const Either();
2122

23+
/// Return the result of `f` called with `b` and the value of [Right].
24+
/// If this [Either] is [Left], return `b`.
25+
@override
26+
C foldRight<C>(C b, C Function(C acc, R b) f);
27+
28+
/// Return the result of `f` called with `b` and the value of [Right].
29+
/// If this [Either] is [Left], return `b`.
30+
@override
31+
C foldLeft<C>(C b, C Function(C acc, R b) f) =>
32+
foldMap<Endo<C>>(dualEndoMonoid(), (b) => (C c) => f(c, b))(b);
33+
34+
/// Use `monoid` to combine the value of [Right] applied to `f`.
35+
@override
36+
C foldMap<C>(Monoid<C> monoid, C Function(R b) f) =>
37+
foldRight(monoid.empty, (c, b) => monoid.combine(f(b), c));
38+
39+
/// Return the result of `f` called with `b` and the value of [Right].
40+
/// If this [Either] is [Left], return `b`.
41+
@override
42+
C foldRightWithIndex<C>(C c, C Function(int i, C acc, R b) f) =>
43+
foldRight<Tuple2<C, int>>(
44+
Tuple2(c, length() - 1),
45+
(t, b) => Tuple2(f(t.second, t.first, b), t.second - 1),
46+
).first;
47+
48+
/// Return the result of `f` called with `b` and the value of [Right].
49+
/// If this [Either] is [Left], return `b`.
50+
@override
51+
C foldLeftWithIndex<C>(C c, C Function(int i, C acc, R b) f) =>
52+
foldLeft<Tuple2<C, int>>(
53+
Tuple2(c, 0),
54+
(t, b) => Tuple2(f(t.second, t.first, b), t.second + 1),
55+
).first;
56+
57+
/// Returns `1` when [Either] is [Right], `0` otherwise.
58+
@override
59+
int length() => foldLeft(0, (b, _) => b + 1);
60+
61+
/// Return the result of `predicate` applied to the value of [Right].
62+
/// If the [Either] is [Left], returns `false`.
63+
@override
64+
bool any(bool Function(R a) predicate) => foldMap(boolOrMonoid(), predicate);
65+
66+
/// Return the result of `predicate` applied to the value of [Right].
67+
/// If the [Either] is [Left], returns `true`.
68+
@override
69+
bool all(bool Function(R a) predicate) => foldMap(boolAndMonoid(), predicate);
70+
71+
/// Use `monoid` to combine the value of [Right].
72+
@override
73+
R concatenate(Monoid<R> monoid) => foldMap(monoid, identity);
74+
2275
/// If the [Either] is [Right], then change its value from type `R` to
2376
/// type `C` using function `f`.
2477
@override
@@ -216,7 +269,7 @@ class Right<L, R> extends Either<L, R> {
216269
Either<C, R> mapLeft<C>(C Function(L a) f) => Right<C, R>(_value);
217270

218271
@override
219-
C foldRight<C>(C b, C Function(R a, C b) f) => f(_value, b);
272+
C foldRight<C>(C b, C Function(C acc, R a) f) => f(b, _value);
220273

221274
@override
222275
C match<C>(C Function(L l) onLeft, C Function(R r) onRight) =>
@@ -292,7 +345,7 @@ class Left<L, R> extends Either<L, R> {
292345
Either<C, R> mapLeft<C>(C Function(L a) f) => Left<C, R>(f(_value));
293346

294347
@override
295-
C foldRight<C>(C b, C Function(R a, C b) f) => b;
348+
C foldRight<C>(C b, C Function(C acc, R a) f) => b;
296349

297350
@override
298351
C match<C>(C Function(L l) onLeft, C Function(R r) onRight) => onLeft(_value);

lib/src/ilist.dart

+3-3
Original file line numberDiff line numberDiff line change
@@ -18,8 +18,8 @@ abstract class IList<T> extends HKT<IListHKT, T>
1818
concatMap((t) => a.map((f) => f(t)));
1919

2020
@override
21-
B foldRight<B>(B b, B Function(T a, B b) f) =>
22-
reverse().foldLeft(b, (b, a) => f(a, b));
21+
B foldRight<B>(B b, B Function(B acc, T a) f) =>
22+
reverse().foldLeft(b, (b, t) => f(b, t));
2323

2424
@override
2525
IList<B> flatMap<B>(covariant IList<B> Function(T a) f);
@@ -52,7 +52,7 @@ abstract class IList<T> extends HKT<IListHKT, T>
5252

5353
/// Append an `IList<T>` to the list
5454
@override
55-
IList<T> plus(covariant IList<T> l) => foldRight(l, (e, p) => Cons(e, p));
55+
IList<T> plus(covariant IList<T> l) => foldRight(l, (e, p) => Cons(p, e));
5656

5757
/// Apply `f` to the elements of this `IList` and `concat` the result.
5858
IList<B> concatMap<B>(IList<B> Function(T t) f) => IList.concat(map(f));

lib/src/option.dart

+66-14
Original file line numberDiff line numberDiff line change
@@ -46,6 +46,70 @@ abstract class Option<A> extends HKT<_OptionHKT, A>
4646
Filterable<_OptionHKT, A> {
4747
const Option();
4848

49+
/// Return the result of `f` called with `b` and the value of [Some].
50+
/// If this [Option] is [None], return `b`.
51+
@override
52+
B foldRight<B>(B b, B Function(B acc, A a) f);
53+
54+
/// Return the result of `f` called with `b` and the value of [Some].
55+
/// If this [Option] is [None], return `b`.
56+
@override
57+
B foldLeft<B>(B b, B Function(B acc, A a) f) =>
58+
foldMap<Endo<B>>(dualEndoMonoid(), (a) => (B b) => f(b, a))(b);
59+
60+
/// Use `monoid` to combine the value of [Some] applied to `f`.
61+
@override
62+
B foldMap<B>(Monoid<B> monoid, B Function(A a) f) =>
63+
foldRight(monoid.empty, (b, a) => monoid.combine(f(a), b));
64+
65+
/// Return the result of `f` called with `b` and the value of [Some].
66+
/// If this [Option] is [None], return `b`.
67+
@override
68+
B foldRightWithIndex<B>(B b, B Function(int i, B acc, A a) f) =>
69+
foldRight<Tuple2<B, int>>(
70+
Tuple2(b, length() - 1),
71+
(t, a) => Tuple2(f(t.second, t.first, a), t.second - 1),
72+
).first;
73+
74+
/// Return the result of `f` called with `b` and the value of [Some].
75+
/// If this [Option] is [None], return `b`.
76+
@override
77+
B foldLeftWithIndex<B>(B b, B Function(int i, B acc, A a) f) =>
78+
foldLeft<Tuple2<B, int>>(
79+
Tuple2(b, 0),
80+
(t, a) => Tuple2(f(t.second, t.first, a), t.second + 1),
81+
).first;
82+
83+
/// Returns `1` when [Option] is [Some], `0` otherwise.
84+
@override
85+
int length() => foldLeft(0, (b, _) => b + 1);
86+
87+
/// Return the result of `predicate` applied to the value of [Some].
88+
/// If the [Option] is [None], returns `false`.
89+
@override
90+
bool any(bool Function(A a) predicate) => foldMap(boolOrMonoid(), predicate);
91+
92+
/// Return the result of `predicate` applied to the value of [Some].
93+
/// If the [Option] is [None], returns `true`.
94+
@override
95+
bool all(bool Function(A a) predicate) => foldMap(boolAndMonoid(), predicate);
96+
97+
/// Use `monoid` to combine the value of [Some].
98+
@override
99+
A concatenate(Monoid<A> monoid) => foldMap(monoid, identity);
100+
101+
/// Return the value of this [Option] if it is [Some], otherwise return `a`.
102+
@override
103+
Option<A> plus(covariant Option<A> a);
104+
105+
/// Return `Some(a)`.
106+
@override
107+
Option<A> prepend(A a) => Some(a);
108+
109+
/// If this [Option] is [None], return `Some(a)`. Otherwise return this [Some].
110+
@override
111+
Option<A> append(A a);
112+
49113
/// Change the value of type `A` to a value of type `B` using function `f`.
50114
/// ```dart
51115
/// /// Change type `String` (`A`) to type `int` (`B`)
@@ -162,18 +226,6 @@ abstract class Option<A> extends HKT<_OptionHKT, A>
162226
E Function(A a, C c, D d) f) =>
163227
flatMap((a) => mc.flatMap((c) => md.map((d) => f(a, c, d))));
164228

165-
/// Return the value of this [Option] if it is [Some], otherwise return `a`.
166-
@override
167-
Option<A> plus(covariant Option<A> a);
168-
169-
/// Return `Some(a)`.
170-
@override
171-
Option<A> prepend(A a) => Some(a);
172-
173-
/// If this [Option] is [None], return `Some(a)`. Otherwise return this [Some].
174-
@override
175-
Option<A> append(A a);
176-
177229
/// Execute `onSome` when value is [Some], otherwise execute `onNone`.
178230
B match<B>(B Function(A a) onSome, B Function() onNone);
179231

@@ -323,7 +375,7 @@ class Some<A> extends Option<A> {
323375
Option<B> map<B>(B Function(A a) f) => Some(f(_value));
324376

325377
@override
326-
B foldRight<B>(B b, B Function(A a, B b) f) => f(_value, b);
378+
B foldRight<B>(B b, B Function(B acc, A a) f) => f(b, _value);
327379

328380
@override
329381
Option<B> flatMap<B>(covariant Option<B> Function(A a) f) => f(_value);
@@ -394,7 +446,7 @@ class None<A> extends Option<A> {
394446
Option<B> map<B>(B Function(A a) f) => Option.none();
395447

396448
@override
397-
B foldRight<B>(B b, B Function(A a, B b) f) => b;
449+
B foldRight<B>(B b, B Function(B acc, A a) f) => b;
398450

399451
@override
400452
Option<B> flatMap<B>(covariant Option<B> Function(A a) f) => Option.none();

lib/src/tuple.dart

+17-12
Original file line numberDiff line numberDiff line change
@@ -58,12 +58,12 @@ class Tuple2<T1, T2> extends HKT2<_Tuple2HKT, T1, T2>
5858
///
5959
/// Same as `foldLeft`.
6060
@override
61-
C foldRight<C>(C b, C Function(T2 a, C b) f) => f(_value2, b);
61+
C foldRight<C>(C b, C Function(C acc, T2 a) f) => f(b, _value2);
6262

6363
/// Return value of type `C` by calling `f` with `b` and the first value of the [Tuple2].
6464
///
6565
/// Same as `foldLeftFirst`.
66-
C foldRightFirst<C>(C b, C Function(T1 a, C b) f) => f(_value1, b);
66+
C foldRightFirst<C>(C b, C Function(C acc, T1 a) f) => f(b, _value1);
6767

6868
/// Return value of type `C` by calling `f` with `b` and the second value of the [Tuple2].
6969
///
@@ -81,40 +81,40 @@ class Tuple2<T1, T2> extends HKT2<_Tuple2HKT, T1, T2>
8181
/// Return value of type `C` by applying `f` on `monoid`.
8282
@override
8383
C foldMap<C>(Monoid<C> monoid, C Function(T2 a) f) =>
84-
foldRight(monoid.empty, (a, b) => monoid.combine(f(a), b));
84+
foldRight(monoid.empty, (c, b) => monoid.combine(c, f(b)));
8585

8686
/// Return value of type `C` by applying `f` on `monoid`.
8787
C foldMapFirst<C>(Monoid<C> monoid, C Function(T1 a) f) =>
88-
foldRightFirst(monoid.empty, (a, b) => monoid.combine(f(a), b));
88+
foldRightFirst(monoid.empty, (c, t) => monoid.combine(f(t), c));
8989

9090
/// Return value of type `C` by calling `f` with `b` and the second value of the [Tuple2].
9191
@override
92-
C foldRightWithIndex<C>(C c, C Function(int i, T2 b, C c) f) =>
92+
C foldRightWithIndex<C>(C c, C Function(int i, C acc, T2 b) f) =>
9393
foldRight<Tuple2<C, int>>(
9494
Tuple2(c, length() - 1),
95-
(a, t) => Tuple2(f(t.second, a, t.first), t.second - 1),
95+
(t, a) => Tuple2(f(t.second, t.first, a), t.second - 1),
9696
).first;
9797

9898
/// Return value of type `C` by calling `f` with `b` and the first value of the [Tuple2].
99-
C foldRightFirstWithIndex<C>(C c, C Function(int i, T1 b, C c) f) =>
99+
C foldRightFirstWithIndex<C>(C c, C Function(int i, C c, T1 b) f) =>
100100
foldRightFirst<Tuple2<C, int>>(
101101
Tuple2(c, length() - 1),
102-
(a, t) => Tuple2(f(t.second, a, t.first), t.second - 1),
102+
(t, a) => Tuple2(f(t.second, t.first, a), t.second - 1),
103103
).first;
104104

105105
/// Return value of type `C` by calling `f` with `b` and the second value of the [Tuple2].
106106
@override
107-
C foldLeftWithIndex<C>(C c, C Function(int i, T2 b, C c) f) =>
107+
C foldLeftWithIndex<C>(C c, C Function(int i, C acc, T2 b) f) =>
108108
foldLeft<Tuple2<C, int>>(
109109
Tuple2(c, 0),
110-
(t, a) => Tuple2(f(t.second, a, t.first), t.second + 1),
110+
(t, a) => Tuple2(f(t.second, t.first, a), t.second + 1),
111111
).first;
112112

113113
/// Return value of type `C` by calling `f` with `b` and the first value of the [Tuple2].
114-
C foldLeftFirstWithIndex<C>(C c, C Function(int i, T1 b, C c) f) =>
114+
C foldLeftFirstWithIndex<C>(C c, C Function(int i, C c, T1 b) f) =>
115115
foldLeftFirst<Tuple2<C, int>>(
116116
Tuple2(c, 0),
117-
(t, a) => Tuple2(f(t.second, a, t.first), t.second + 1),
117+
(t, a) => Tuple2(f(t.second, t.first, a), t.second + 1),
118118
).first;
119119

120120
/// Returns `1`.
@@ -131,6 +131,11 @@ class Tuple2<T1, T2> extends HKT2<_Tuple2HKT, T1, T2>
131131
foldMap(boolAndMonoid(), predicate);
132132

133133
/// Combine the second value of [Tuple2] using `monoid`.
134+
/// ```dart
135+
/// const tuple = Tuple2('abc', 10);
136+
/// final ap = tuple.concatenate(Monoid.instance(0, (a1, a2) => a1 + a2));
137+
/// expect(ap, 10);
138+
/// ```
134139
@override
135140
T2 concatenate(Monoid<T2> monoid) => foldMap(monoid, identity);
136141

0 commit comments

Comments
 (0)