# And the Result is a monad

Adding superpowers to a custom type

In modern Android and with the advent of Kotlin, functional programming is integrating into our everyday code bit by bit. Do we take full advantage of this paradigm though? In this article, I will explain, how a relative common nowadays type like `Result<T>`

can be “powered up” to become a monad and help via composition, to solve different problems.

**What is a monad ❓**

To begin with, let us see what a monad is. Wikipedia, states as a definition:

In functional programming, a

monadis an abstraction that allows structuring programs generically. Supporting languages may use monads to abstract away boilerplate code needed by the program logic. Monads achieve this by providing their own data type (a particular type for each type of monad), which represents a specific form of computation, along with one procedure to wrap values ofanybasic type within the monad (yielding amonadic value) and another to compose functions that output monadic values (calledmonadic functions).[1]

But what does it actually mean? In Layman’s terms, think about it like creating a type that wraps other types and adds some superpowers to it. For example, the `Option<T>`

is a famous monad that showcases the optionality of a type by having the values of `Some(T)`

and `None`

. When the value is an instance of `Some`

then that indicates that the value exists while in `None`

the value is absent.

Now that we have a rough picture of monads in our mind, let’s see the next ingredient to our functional recipe which is none other than the `Result<T>.`

**Introduction to Result 📥**

Result is a famous type in Android that is commonly used as a sealed class with two subclasses `Success`

and `Error`

. An example of this can be found in the below gist:

The result type is usually used in asynchronous return types. For example, when having a typical API call that can succeed or fail due to any reason. But that is not its only usage option, as we can leverage the type, to handle other domain needs, like validation, or anything in reality that can succeed or fail.

The pitfall of doing this is the constant checking that the type needs to see if something is actually a success or an error, making it cumbersome to work with. Alas if that part was omitted and not needed, wouldn’t that be much better and convenient? So let’s not spend our time and add some superpowers to our type, transforming it essential to a Monad.

**Morphing Time ♻️**So what do we need in order for our type to be

**“elevated”**to a monad? First of all, we need the following operations defined:

- A
`return`

function that can quickly and easily lift an already existing type to our result. - A
`bind`

function that acts on a`Result<T>`

, extracts`T`

and applies a lambda to it, returning a`Result<R>`

.

An easy way to create the `return`

function, is to have a method defined in the companion like the following gist. Due to the return word being a language keyword we can rename it to `of`

and make it part of the companion object.

With the above snippet and taking advantage of Kotlin’s trailing lambda, we can transform anything now safely to a result.

An example would be `val result = Result.of { api.makeCall() }`

Now let’s see about bind and how we can model it.

Leveraging the awesome feature of extension methods in Kotlin, we define an extension to an already existing result that if it’s a success we unwrap it, apply a function to it and wrap it back to success. This looks similar to `flatMap`

and it actually is, so you can go ahead and rename it as such.

Are we done yet? Kinda! What remains is for us to prove that our new **“monad”** actually adheres to the monad laws. So let’s go prove that our type is a monad!

**Monad Laws 📜**

There are 3 monad laws we have to confirm that our type satisfies in order to be fully considered a monad and these are: **Right identity**, **left identity**, and **associativity**.

**Right identity**means that applying`flatMap`

by passing in the`Result.of`

as the expected action, then that means that we should end back to where we started. In other words, if for example, we have a`val result = Result.of{ 5 }`

then by doing`result.flatMap { value -> Result.of { value } }`

it will also produce`Success(5)`

.**Left identity**is kind of the opposite of right identity and that means that we have to prove the following:`Result.of(value).flatMap(::anyMethodThatReturnsResult) == anyMethodThatReturnsResult(value)`

which is expressed as flattening a result and applying to its value a method is the same as applying the same method to the value in the first place.**Associativity**means that the order or the nesting in this example of the flat maps does not alter the result`result.flatMap(::method1).flatMap(::method2) == result.flatMap { method1(x).flatMap(::method2) }`

similar to addition and how (1 + 3) + 2 is equivalent to (3 + 2) + 1.

All the above laws can be easily tested with simple JUnit tests.

**Superpowers 💪**

Now that everything is in place the power of it is already being shown. Our result monad can be used not only for asynchronous calls but for any complex business case. Furthermore, it can be extended with more functionality as an `orElse`

method that will handle the error paths, or a `map`

method that can simply unwrap the result type but let's see an example as it is much better than describing it.

A more complex scenario would be the business logic behind registering a user. Imagine if for registering, we needed an age over 18, a `non-empty`

email, and a password greater than 8 chars. All this could be easily handled in a result chain.

As you can see this can be extended and used in many many ways and it can be very helpful. One change could be to use domain errors instead of a simple string. The above are just ideas and you are free to mix and match to find the preferred solution according to any business needs.

Although all the above are quite simple and easy to use or build upon, one can also use an already established monad like Either from Arrow that is worth experimenting with and trying out!

Thanks for reading this and hopefully found it interesting!❤️