dart_either library

Author: Petrus Nguyễn Thái Học.

Either is a type that represents either Right (usually represent a "desired" value) or Left (usually represent a "undesired" value or error value).

Elm Result. Haskell Data.Either. Rust Result.

In day-to-day programming, it is fairly common to find ourselves writing functions that can fail. For instance, querying a service may result in a connection issue, or some unexpected JSON response.

To communicate these errors, it has become common practice to throw exceptions; however, exceptions are not tracked in any way, shape, or form by the compiler. To see what kind of exceptions (if any) a function may throw, we have to dig through the source code. Then, to handle these exceptions, we have to make sure we catch them at the call site. This all becomes even more unwieldy when we try to compose exception-throwing procedures.

double throwsSomeStuff(int i) => throw UnimplementedError();

String throwsOtherThings(double d) => throw UnimplementedError();

List<int> moreThrowing(String s) => throw UnimplementedError();

List<int> magic(int i) => moreThrowing( throwsOtherThings( throwsSomeStuff(i) ) );

Assume we happily throw exceptions in our code. Looking at the types of the functions above, any could throw a number of exceptions -- we do not know. When we compose, exceptions from any of the constituent functions can be thrown. Moreover, they may throw the same kind of exception (e.g., ArgumentError) and, thus, it gets tricky tracking exactly where an exception came from.

How then do we communicate an error? By making it explicit in the data type we return.

Either

Either is used to short-circuit a computation upon the first error. By convention, the right side of an Either is used to hold successful values.

Because Either is right-biased, it is possible to define a Monad instance for it. Since we only ever want the computation to continue in the case of Right (as captured by the right-bias nature), we fix the left type parameter and leave the right one free. So, the map and flatMap methods are right-biased.

Classes

Either<L, R>
Author: Petrus Nguyễn Thái Học.
Left<L, R>
The left side of the disjoint union, as opposed to the Right side.
The right side of the disjoint union, as opposed to the Left side.

Extensions

AsFutureEitherExtension on Either<L, R>
Adds toFuture to Either.
AsyncFlatMapFutureExtension on Future<Either<L, R>>
Provides thenFlatMapEither on a Future of Either.
AsyncMapFutureExtension on Future<Either<L, R>>
Provides thenMapEither on a Future of Either.
BindEitherEffectExtension on EitherEffect<L>
Provides binding syntax on a scope-bound EitherEffect.
BindEitherExtension on Either<L, R>
Provides binding syntax on an Either.
BindEitherFutureExtension on Future<Either<L, R>>
Provides binding syntax on a Future of Either.
BindFutureEitherEffectExtension on EitherEffect<L>
Provides bindFuture on a scope-bound EitherEffect.
CombineEitherExtension on Either<L, R>
Adds combine to Either.
EnsureEitherEffectExtension on EitherEffect<L>
Provides ensure on a scope-bound EitherEffect.
EnsureNotNullEitherEffectExtension on EitherEffect<L>
Provides ensureNotNull on a scope-bound EitherEffect.
FlatMapEitherExtension on Either<L, R>
Adds flatMap to Either.
FlattenEitherExtension on Either<L, Either<L, R>>
Adds flatten to nested Either values.
GetOrDefaultEitherExtension on Either<L, R>
Adds getOrDefault to Either.
GetOrElseEitherExtension on Either<L, R>
Adds the deprecated getOrElse fallback to Either.
GetOrHandleEitherExtension on Either<L, R>
Adds getOrHandle to Either.
GetOrThrowEitherExtension on Either<L, R>
Adds getOrThrow to Either.
HandleErrorEitherExtension on Either<L, R>
Adds handleError to Either.
HandleErrorWithEitherExtension on Either<L, R>
Adds handleErrorWith to Either.
MergeEitherExtension on Either<T, T>
Adds merge to Either.
RaiseEitherEffectExtension on EitherEffect<L>
Provides convenience raise syntax on a scope-bound EitherEffect.
ToEitherFutureExtension on Future<R>
Provide toEitherFuture extension on Future.
ToEitherObjectExtension on T
Provide left and right extensions on any types.
ToEitherStreamExtension on Stream<R>
Provide toEitherStream extension on Stream.

Typedefs

EitherEffect<L> = _BindingScope<Never Function(L)>
A scope-bound capability for binding Either values with the same L.
ErrorMapper<T> = T Function(Object error, StackTrace stackTrace)
Map error and stackTrace to a T value.

Exceptions / Errors

ControlError<T>
Internal control-flow signal raised when EitherEffect short-circuits by binding a Left or calling RaiseEitherEffectExtension.raise.