Skip to content

Commit

Permalink
Tuple2 complete, changed Foldable instances
Browse files Browse the repository at this point in the history
  • Loading branch information
SandroMaglione committed Jun 15, 2021
1 parent 9addc80 commit 86565dd
Show file tree
Hide file tree
Showing 13 changed files with 477 additions and 156 deletions.
2 changes: 1 addition & 1 deletion .packages
Original file line number Diff line number Diff line change
Expand Up @@ -3,7 +3,7 @@
#
# For more info see: https://dart.dev/go/dot-packages-deprecation
#
# Generated by pub on 2021-06-13 21:30:13.314180.
# Generated by pub on 2021-06-15 19:06:22.469619.
_fe_analyzer_shared:file:///C:/Users/Sandro%20Maglione/AppData/Roaming/Pub/Cache/hosted/pub.dartlang.org/_fe_analyzer_shared-22.0.0/lib/
analyzer:file:///C:/Users/Sandro%20Maglione/AppData/Roaming/Pub/Cache/hosted/pub.dartlang.org/analyzer-1.7.0/lib/
args:file:///C:/Users/Sandro%20Maglione/AppData/Roaming/Pub/Cache/hosted/pub.dartlang.org/args-2.1.0/lib/
Expand Down
8 changes: 6 additions & 2 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
@@ -1,9 +1,13 @@
# v0.0.4
# v0.0.4 - 15 June 2021

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

# v0.0.3 - 13 June 2021

Expand Down
13 changes: 7 additions & 6 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -5,7 +5,7 @@
<img src="https://img.shields.io/github/stars/SandroMaglione/fpdart?logo=github" />
</a>
<img src="https://img.shields.io/github/license/SandroMaglione/fpdart?logo=github" />
<img src="https://img.shields.io/badge/version-0.0.3-blue.svg" />
<img src="https://img.shields.io/badge/version-0.0.4-blue.svg" />
<!-- <img src="https://img.shields.io/badge/flutter-v2.0.2-blue.svg" /> -->
<img src="https://img.shields.io/badge/dart-v2.13.1-blue.svg" />
<a href="https://github.com/SandroMaglione">
Expand Down Expand Up @@ -54,7 +54,7 @@ Fpdart is inspired by [fp-ts](https://gcanti.github.io/fp-ts/), [cats](https://t
```yaml
# pubspec.yaml
dependencies:
fpdart: ^0.0.3 # Check out the latest version
fpdart: ^0.0.4 # Check out the latest version
```
## Examples
Expand Down Expand Up @@ -204,10 +204,10 @@ The roadmap for types development is highlighted below (breaking changes to *'st
- ~~Implementation~~
- ~~Documentation~~
- ~~Testing~~
6. `Tuple`
- Implementation
- Documentation
- Testing
6. ~~`Tuple`~~
- ~~Implementation~~
- ~~Documentation~~
- ~~Testing~~
7. `State`
- Implementation
- Documentation
Expand Down Expand Up @@ -263,6 +263,7 @@ In general, any contribution or feedback is welcome (and encouraged!).

## Versioning

- v0.0.4 - 15 June 2021
- v0.0.3 - 13 June 2021
- v0.0.2 - 13 June 2021
- v0.0.1 - 28 May 2021
Expand Down
57 changes: 55 additions & 2 deletions lib/src/either.dart
Original file line number Diff line number Diff line change
@@ -1,5 +1,6 @@
import 'function.dart';
import 'option.dart';
import 'tuple.dart';
import 'typeclass/typeclass.export.dart';

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

/// Return the result of `f` called with `b` and the value of [Right].
/// If this [Either] is [Left], return `b`.
@override
C foldRight<C>(C b, C Function(C acc, R b) f);

/// Return the result of `f` called with `b` and the value of [Right].
/// If this [Either] is [Left], return `b`.
@override
C foldLeft<C>(C b, C Function(C acc, R b) f) =>
foldMap<Endo<C>>(dualEndoMonoid(), (b) => (C c) => f(c, b))(b);

/// Use `monoid` to combine the value of [Right] applied to `f`.
@override
C foldMap<C>(Monoid<C> monoid, C Function(R b) f) =>
foldRight(monoid.empty, (c, b) => monoid.combine(f(b), c));

/// Return the result of `f` called with `b` and the value of [Right].
/// If this [Either] is [Left], return `b`.
@override
C foldRightWithIndex<C>(C c, C Function(int i, C acc, R b) f) =>
foldRight<Tuple2<C, int>>(
Tuple2(c, length() - 1),
(t, b) => Tuple2(f(t.second, t.first, b), t.second - 1),
).first;

/// Return the result of `f` called with `b` and the value of [Right].
/// If this [Either] is [Left], return `b`.
@override
C foldLeftWithIndex<C>(C c, C Function(int i, C acc, R b) f) =>
foldLeft<Tuple2<C, int>>(
Tuple2(c, 0),
(t, b) => Tuple2(f(t.second, t.first, b), t.second + 1),
).first;

/// Returns `1` when [Either] is [Right], `0` otherwise.
@override
int length() => foldLeft(0, (b, _) => b + 1);

/// Return the result of `predicate` applied to the value of [Right].
/// If the [Either] is [Left], returns `false`.
@override
bool any(bool Function(R a) predicate) => foldMap(boolOrMonoid(), predicate);

/// Return the result of `predicate` applied to the value of [Right].
/// If the [Either] is [Left], returns `true`.
@override
bool all(bool Function(R a) predicate) => foldMap(boolAndMonoid(), predicate);

/// Use `monoid` to combine the value of [Right].
@override
R concatenate(Monoid<R> monoid) => foldMap(monoid, identity);

/// If the [Either] is [Right], then change its value from type `R` to
/// type `C` using function `f`.
@override
Expand Down Expand Up @@ -216,7 +269,7 @@ class Right<L, R> extends Either<L, R> {
Either<C, R> mapLeft<C>(C Function(L a) f) => Right<C, R>(_value);

@override
C foldRight<C>(C b, C Function(R a, C b) f) => f(_value, b);
C foldRight<C>(C b, C Function(C acc, R a) f) => f(b, _value);

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

@override
C foldRight<C>(C b, C Function(R a, C b) f) => b;
C foldRight<C>(C b, C Function(C acc, R a) f) => b;

@override
C match<C>(C Function(L l) onLeft, C Function(R r) onRight) => onLeft(_value);
Expand Down
6 changes: 3 additions & 3 deletions lib/src/ilist.dart
Original file line number Diff line number Diff line change
Expand Up @@ -18,8 +18,8 @@ abstract class IList<T> extends HKT<IListHKT, T>
concatMap((t) => a.map((f) => f(t)));

@override
B foldRight<B>(B b, B Function(T a, B b) f) =>
reverse().foldLeft(b, (b, a) => f(a, b));
B foldRight<B>(B b, B Function(B acc, T a) f) =>
reverse().foldLeft(b, (b, t) => f(b, t));

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

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

/// Apply `f` to the elements of this `IList` and `concat` the result.
IList<B> concatMap<B>(IList<B> Function(T t) f) => IList.concat(map(f));
Expand Down
80 changes: 66 additions & 14 deletions lib/src/option.dart
Original file line number Diff line number Diff line change
Expand Up @@ -46,6 +46,70 @@ abstract class Option<A> extends HKT<_OptionHKT, A>
Filterable<_OptionHKT, A> {
const Option();

/// Return the result of `f` called with `b` and the value of [Some].
/// If this [Option] is [None], return `b`.
@override
B foldRight<B>(B b, B Function(B acc, A a) f);

/// Return the result of `f` called with `b` and the value of [Some].
/// If this [Option] is [None], return `b`.
@override
B foldLeft<B>(B b, B Function(B acc, A a) f) =>
foldMap<Endo<B>>(dualEndoMonoid(), (a) => (B b) => f(b, a))(b);

/// Use `monoid` to combine the value of [Some] applied to `f`.
@override
B foldMap<B>(Monoid<B> monoid, B Function(A a) f) =>
foldRight(monoid.empty, (b, a) => monoid.combine(f(a), b));

/// Return the result of `f` called with `b` and the value of [Some].
/// If this [Option] is [None], return `b`.
@override
B foldRightWithIndex<B>(B b, B Function(int i, B acc, A a) f) =>
foldRight<Tuple2<B, int>>(
Tuple2(b, length() - 1),
(t, a) => Tuple2(f(t.second, t.first, a), t.second - 1),
).first;

/// Return the result of `f` called with `b` and the value of [Some].
/// If this [Option] is [None], return `b`.
@override
B foldLeftWithIndex<B>(B b, B Function(int i, B acc, A a) f) =>
foldLeft<Tuple2<B, int>>(
Tuple2(b, 0),
(t, a) => Tuple2(f(t.second, t.first, a), t.second + 1),
).first;

/// Returns `1` when [Option] is [Some], `0` otherwise.
@override
int length() => foldLeft(0, (b, _) => b + 1);

/// Return the result of `predicate` applied to the value of [Some].
/// If the [Option] is [None], returns `false`.
@override
bool any(bool Function(A a) predicate) => foldMap(boolOrMonoid(), predicate);

/// Return the result of `predicate` applied to the value of [Some].
/// If the [Option] is [None], returns `true`.
@override
bool all(bool Function(A a) predicate) => foldMap(boolAndMonoid(), predicate);

/// Use `monoid` to combine the value of [Some].
@override
A concatenate(Monoid<A> monoid) => foldMap(monoid, identity);

/// Return the value of this [Option] if it is [Some], otherwise return `a`.
@override
Option<A> plus(covariant Option<A> a);

/// Return `Some(a)`.
@override
Option<A> prepend(A a) => Some(a);

/// If this [Option] is [None], return `Some(a)`. Otherwise return this [Some].
@override
Option<A> append(A a);

/// Change the value of type `A` to a value of type `B` using function `f`.
/// ```dart
/// /// Change type `String` (`A`) to type `int` (`B`)
Expand Down Expand Up @@ -162,18 +226,6 @@ abstract class Option<A> extends HKT<_OptionHKT, A>
E Function(A a, C c, D d) f) =>
flatMap((a) => mc.flatMap((c) => md.map((d) => f(a, c, d))));

/// Return the value of this [Option] if it is [Some], otherwise return `a`.
@override
Option<A> plus(covariant Option<A> a);

/// Return `Some(a)`.
@override
Option<A> prepend(A a) => Some(a);

/// If this [Option] is [None], return `Some(a)`. Otherwise return this [Some].
@override
Option<A> append(A a);

/// Execute `onSome` when value is [Some], otherwise execute `onNone`.
B match<B>(B Function(A a) onSome, B Function() onNone);

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

@override
B foldRight<B>(B b, B Function(A a, B b) f) => f(_value, b);
B foldRight<B>(B b, B Function(B acc, A a) f) => f(b, _value);

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

@override
B foldRight<B>(B b, B Function(A a, B b) f) => b;
B foldRight<B>(B b, B Function(B acc, A a) f) => b;

@override
Option<B> flatMap<B>(covariant Option<B> Function(A a) f) => Option.none();
Expand Down
29 changes: 17 additions & 12 deletions lib/src/tuple.dart
Original file line number Diff line number Diff line change
Expand Up @@ -58,12 +58,12 @@ class Tuple2<T1, T2> extends HKT2<_Tuple2HKT, T1, T2>
///
/// Same as `foldLeft`.
@override
C foldRight<C>(C b, C Function(T2 a, C b) f) => f(_value2, b);
C foldRight<C>(C b, C Function(C acc, T2 a) f) => f(b, _value2);

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

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

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

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

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

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

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

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

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

Expand Down
Loading

0 comments on commit 86565dd

Please sign in to comment.