A flutter/dart library : either_option
About
A small typed and safe library for error handling with functionnal programming concept in Dart and utter project (MIT licence).
either_option is a simple library typed for easy and safe error handling with functional programming style in Dart.
It aims to allow flutter/dart developpers to use the 2 most popular patterns and abstractions :
Either
and Option
, mainly used in FP language like Scala, Haskell, OCaml,…
Installation
Package link on pub either_option In your pubspec.yaml dependencies add
either_option: ^1.0.6
Overview
Either
Either
Represents a value of one of two possible types.
By convention we put missing or error value in an instance of Left
and expected success value in an instance of Right
.
For example, we fetch an url from a repository repository to get an User details and use Either<ServerError,User>
:
Future<Either<ServerError, User>> getUser(int id) async {
final baseUrl = "https://fakerestapi.azurewebsites.net/api/Users/$id";
final res = await http.get(baseUrl);
if (res.statusCode == 200) {
dynamic body = json.decode(res.body);
User user = User.fromJson(body);
return Right(user);
}
if (res.statusCode == 404)
return Left(ServerError("This user doesn't exist"));
return Left(ServerError("Unknown server error"));
}
So now to consume result we can use for example fold
method and say what to do with value :
main() async {
final Repository repository = Repository();
final Either<ServerError, User> res = await repository.getUser(3);
final defaultUser = User(id: 0, username: "ko", password: "ko");
final userName = res.fold((_) => defaultUser.username, (user) => user.username);
print(userName); // "User 3"
//if res was a Left, print(userName) would give "ko"
}
Option
Option
Represents a value of one of two possible types.
By convention we consider missing value as an instance of None
and expected success value in an instance of Some
.
Future<Option<User>> getUserOpt(int id) async {
final res = await http.get(baseUrl);
return Option.cond(
res.statusCode == 200, User.fromJson(json.decode(res.body)));
}
// -----------------------------------------
main() async {
final Repository repository = Repository();
final Option<User> res = await repository.getUserOpt(3);
final defaultUser = User(id: 0, username: "ko", password: "ko");
final userName = res.getOrElse(defaultUser).username;
print(userName); // "User 3"
//if res was a None, print(userName) would give "ko"
}
Ressources & explanation
Features
Functions available :
Option | Either | |
---|---|---|
fold | yes | yes |
map | yes | yes |
flatMap | yes | yes |
getOrElse | yes | |
orElse | yes | |
toLeft | yes | |
toRight | yes | |
toEither | yes | |
Option.empty | yes | |
Option.of | yes | |
filter | yes | |
exists | yes | |
contains | yes | |
swap | yes | yes |
cond | yes | yes |