From af96d93c42efb3d57563ccf02e58251471d7380f Mon Sep 17 00:00:00 2001 From: Juliano Alves Date: Thu, 23 Feb 2023 16:12:04 +0000 Subject: [PATCH] Add tap, tapLeft and tapBoth to Either --- lib/src/either.dart | 22 +++++++++++++ test/either_test.dart | 76 +++++++++++++++++++++++++++++++++++++++++++ 2 files changed, 98 insertions(+) diff --git a/lib/src/either.dart b/lib/src/either.dart index 2ee5b58..fa64b1d 100644 --- a/lib/src/either.dart +++ b/lib/src/either.dart @@ -19,6 +19,28 @@ abstract class Either implements TraversableMonadOps, R Either bimap(LL ifLeft(L l), RR ifRight(R r)) => fold((l) => left(ifLeft(l)), (r) => right(ifRight(r))); + Either tap(void Function(R) f) => + flatMap((r) { + f(r); + return right(r); + }); + + Either tapLeft(void Function(L) f) => + fold((l) { + f(l); + return left(l); + }, (r) => right(r)); + + Either tapBoth(void Function(L) f1, void Function(R) f2) => + fold((l) { + f1(l); + return left(l); + }, (r) { + f2(r); + return right(r); + } + ); + @override Either map(R2 f(R r)) => fold(left, (R r) => right(f(r))); @override Either bind(Function1> f) => fold(left, f); @override Either flatMap(Function1> f) => fold(left, f); diff --git a/test/either_test.dart b/test/either_test.dart index 6461710..a619f32 100644 --- a/test/either_test.dart +++ b/test/either_test.dart @@ -103,4 +103,80 @@ void main() { expect(right.value, 2); }); }); + + group('tap', () { + test('executes function with value if right', () { + final either = right(42); + final results = []; + + final result = either.tap((value) => results.add(value)); + + expect(results, [42]); + expect(result, equals(either)); + }); + + test('does not execute function if left', () { + final either = left('error'); + final results = []; + + final result = either.tap((value) => results.add(value)); + + expect(results, isEmpty); + expect(result, equals(either)); + }); + }); + + group('tapLeft', () { + test('executes function with error if left', () { + final either = left('error'); + final results = []; + + final result = either.tapLeft((error) => results.add(error)); + + expect(results, ['error']); + expect(result, equals(either)); + }); + + test('does not execute function if right', () { + final either = right(42); + final results = []; + + final result = either.tapLeft((error) => results.add(error)); + + expect(results, isEmpty); + expect(result, equals(either)); + }); + }); + + group('tapBoth', () { + test('executes left function if left', () { + final either = left('error'); + final resultsLeft = []; + final resultsRight = []; + + final result = either.tapBoth( + (error) => resultsLeft.add(error), + (value) => resultsRight.add(value), + ); + + expect(resultsLeft, ['error']); + expect(resultsRight, isEmpty); + expect(result, equals(either)); + }); + + test('executes right function if right', () { + final either = right(42); + final resultsLeft = []; + final resultsRight = []; + + final result = either.tapBoth( + (error) => resultsLeft.add(error), + (value) => resultsRight.add(value), + ); + + expect(resultsLeft, isEmpty); + expect(resultsRight, [42]); + expect(result, equals(either)); + }); + }); }