|
1 | 1 | import 'function.dart'; |
2 | 2 | import 'option.dart'; |
| 3 | +import 'task_either.dart'; |
3 | 4 | import 'tuple.dart'; |
4 | 5 | import 'typeclass/typeclass.export.dart'; |
5 | 6 |
|
| 7 | +/// Return a `Right(r)`. |
| 8 | +/// |
| 9 | +/// Shortcut for `Either.of(r)`. |
| 10 | +Either<L, R> right<L, R>(R r) => Right<L, R>(r); |
| 11 | + |
| 12 | +/// Return a `Left(l)`. |
| 13 | +/// |
| 14 | +/// Shortcut for `Either.left(l)`. |
| 15 | +Either<L, R> left<L, R>(L l) => Left<L, R>(l); |
| 16 | + |
6 | 17 | /// Tag the [HKT2] interface for the actual [Either]. |
7 | 18 | abstract class _EitherHKT {} |
8 | 19 |
|
@@ -92,6 +103,8 @@ abstract class Either<L, R> extends HKT2<_EitherHKT, L, R> |
92 | 103 | /// You can extract the value of every [Right] in the chain without |
93 | 104 | /// handling all possible missing cases. |
94 | 105 | /// If any of the functions in the chain returns [Left], the result is [Left]. |
| 106 | + /// |
| 107 | + /// Same as `bind`. |
95 | 108 | @override |
96 | 109 | Either<L, C> flatMap<C>(covariant Either<L, C> Function(R a) f); |
97 | 110 |
|
@@ -135,6 +148,22 @@ abstract class Either<L, R> extends HKT2<_EitherHKT, L, R> |
135 | 148 | Either<L, R> filterOrElse(bool Function(R r) f, L Function(R r) onFalse) => |
136 | 149 | flatMap((r) => f(r) ? Either.of(r) : Either.left(onFalse(r))); |
137 | 150 |
|
| 151 | + /// Used to chain multiple functions that return a [Either]. |
| 152 | + /// |
| 153 | + /// You can extract the value of every [Right] in the chain without |
| 154 | + /// handling all possible missing cases. |
| 155 | + /// If any of the functions in the chain returns [Left], the result is [Left]. |
| 156 | + /// |
| 157 | + /// Same as `flatMap`. |
| 158 | + Either<L, R2> bind<R2>(Either<L, R2> Function(R r) f) => flatMap(f); |
| 159 | + |
| 160 | + /// Used to chain multiple functions that return a `Future<Either>`. |
| 161 | + /// |
| 162 | + /// When this value is [Right], it returns a [TaskEither] that will resolve to |
| 163 | + /// the result of calling `f`. |
| 164 | + /// Otherwise, if this value is [Left], it returns `TaskEither.left()`. |
| 165 | + TaskEither<L, R2> bindFuture<R2>(Future<Either<L, R2>> Function(R r) f); |
| 166 | + |
138 | 167 | /// If the [Either] is [Left], then change its value from type `L` to |
139 | 168 | /// type `C` using function `f`. |
140 | 169 | Either<C, R> mapLeft<C>(C Function(L a) f); |
@@ -176,8 +205,16 @@ abstract class Either<L, R> extends HKT2<_EitherHKT, L, R> |
176 | 205 | R getOrElse(R Function(L l) orElse); |
177 | 206 |
|
178 | 207 | /// Execute `onLeft` when value is [Left], otherwise execute `onRight`. |
| 208 | + /// |
| 209 | + /// Same as `fold`. |
179 | 210 | C match<C>(C Function(L l) onLeft, C Function(R r) onRight); |
180 | 211 |
|
| 212 | + /// Execute `onLeft` when value is [Left], otherwise execute `onRight`. |
| 213 | + /// |
| 214 | + /// Same as `match`. |
| 215 | + C fold<C>(C Function(L l) onLeft, C Function(R r) onRight) => |
| 216 | + match<C>(onLeft, onRight); |
| 217 | + |
181 | 218 | /// Return `true` when value of `r` is equal to the value inside this [Either]. |
182 | 219 | /// If this [Either] is [Left], then return `false`. |
183 | 220 | bool elem(R r, Eq<R> eq); |
@@ -320,6 +357,10 @@ class Right<L, R> extends Either<L, R> { |
320 | 357 |
|
321 | 358 | @override |
322 | 359 | String toString() => 'Right($_value)'; |
| 360 | + |
| 361 | + @override |
| 362 | + TaskEither<L, R2> bindFuture<R2>(Future<Either<L, R2>> Function(R r) f) => |
| 363 | + TaskEither(() async => f(_value)); |
323 | 364 | } |
324 | 365 |
|
325 | 366 | class Left<L, R> extends Either<L, R> { |
@@ -396,4 +437,8 @@ class Left<L, R> extends Either<L, R> { |
396 | 437 |
|
397 | 438 | @override |
398 | 439 | String toString() => 'Left($_value)'; |
| 440 | + |
| 441 | + @override |
| 442 | + TaskEither<L, R2> bindFuture<R2>(Future<Either<L, R2>> Function(R r) f) => |
| 443 | + TaskEither.left(_value); |
399 | 444 | } |
0 commit comments