A small monad library for dart/flutter project 🎯
Tags: Flutter, Functional Programming, Dart, Monads

I will introduce with simple words what monad is? and how can we use it through my library either_option in flutter project? It targets mainly readers who are unfamiliar with this concept, or who want to see how we can do it in an imperative object oriented language. We will focus on two monads: Either and Option

Common practice : example 1

Imagine we want to fetch an url with an id to get an User details

If user is not found or response from server is not 200, we return null at line 10. We now want to consume the result

we check that the instance isn’t null at line 5 before accessing its properties… We can do two trivial remarks:

In getUser function, we are not precise about kind of error that happens when we try to fetch user. Simple null is return We hold a detail about possible null instance and add a guard

if(user!=null){ ... }

each time we will try to consume and use user instance else get a runtime error.

Common practice : example 2

We can instead of returning null throw an exception in getUser function and in main function add a try {…} catch block.

Here remarks are :

We are not precise about kind of error that happens when we try to fetch user We must read the content of getUser function body to know where exceptions are thrown. In case of important project maintained by many developers, these details can be difficult to follow

A better solution

We modify the previous example by using an abstraction Either from either_option library. We put error value in an instance of Left and success value in an instance of Right

So now to consume result we can use for example fold method and say what to do with value in case of Left or Right:

Here we have fixed issue from previous example:

We are precise about kind of error that happens when we try to fetch user We don’t need to read the getUser function body to understand its behavior All informations about the getUser function are resume in the type signature We are safe from runtime error because we don’t use null and don’t throw any exception

Either used in this solution is a monad.

Why Monad?

Initially, a monad is an abstraction which come from the functional programming paradigm. This abstraction encapsulate data and allows easy composition of functions applied to those data. In practice we use it for error handling, concurrency management, IO composition and others in a totally safe way.

This concept could be used in Dart/flutter to built more reliable programs. We will don’t go deeper about theoretical stuff under monad but bring a simple exposure and how we can use it easily.

Examples of monads

Option<A>

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.

Either<L,R>

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. It’s like an Option, but with a more general and specific on kind of error.

What is a Monad?

Basically, a monad is a generic class, simple container (or wrapper type) where we can put an element into and satisfies some properties.

Besides, it is an immutable generic data structure that offers the three following methods:

a type constructor: from a type A return the monadic type M[A]

Example : A is int, M is Option and Option.of is the constructor

final Option<int> value = Option.of(10); // Some(10)

a map method: from a monadic type M[A] transform A to an another type B and return the monadic type M[B]

int doubleValue(int value) => value*2; Option<int> mapResult = value.map(doubleValue); //Some(20)

a flatMap method: from a monadic type M[A] transform A to a monadic type M[B] and return the monadic type M[B]

Option<int> tripleValue(int value) => Option.of(value*3); Option<int> flatMapResult = value.flatMap(tripleValue); //Some(30)

Implementation of monads

Option<A>

Unfortunately, Dart doesn’t have pattern matching. A solution to avoid using if…else instruction to know if we are a None or Some instance and what to do is to define an abstract fold method:

Z fold<Z>(Z Function() onNone, Z Function(A a) onSome)

And now concretes type Some and None implementation

see full implementation here

Either<L,R>

Unlike Option’s implementation, Left in Either may contains a value so we use 2 intermediates objects call Projection to project Either instance on the Left or Right and play with them

And finally Right and Left definitions are :

see full implementation here

Hope you appreciate this little article. In a next article we will expose by examples a flutter project with use of either_option