Tag: functional programming

Recently I have spent some time delving into Kotlin, I quickly noticed Jetbrains have decided not to include some useful monads that you find in Scala’s standard library, namely Option, Try and Either. Although the need for an Optional type is somewhat offset by Kotlin’s nullable type (?), it was a surprise the others are omitted as they are incredibly useful when writing functional code. Jetbrains have heavily promoted Kotlin on Android, so perhaps they wanted to keep the language lightweight to continue appealing to this platform and drive adoption.

When to use Either?

Either is a typeclass that wraps the return of 2 possible values, generalised as Left and Right. An example might be the result of a coin toss, Heads and Tails. If you wanted a return type for a function coinToss() then it could be represented by Either. Another more common use of Either is when you need to return an error condition with some contextual information, for example given a:

The returned right hand side denotes a successfully validated name, and the left hand side an error if validation failed. Typically convention says you should use the right hand branch for happy path and the left branch for error conditions.

You may be thinking what is the point in using Either as an error container over throwing an exception. Using exceptions to denote this kind of logic introduces problems of its own. The error is no longer a value, as the control flow of the application is broken by the thrown exception, we are now reliant on the error being handled in an arbitrary place in the stack. Exceptions will usually be more heavyweight than a data class as they contain details of the stack, not to mention any associated stack operations that occur. From a clients perspective we lose the explicitness of the resulting error that can be raised. All of these are undesirable side effects, in functional codebases, exceptions are best left for exceptional cases (or omitted entirely where possible).

Creating your own Either

First we define our type class with parameters to represent both left and right, along with 2 data classes that wrap our left and right values. This allows us to construct our Either instances for any types.

map

Now we can write a map function in terms of our type class objectives, in order to be able to compose a new Either with an arbitrary function we need to define how a left and right instance will be handled. As we stated earlier, the Right hand side is used to denote the happy path, therefore it makes sense to define our map function to run on the right hand value. Our map function:

fun map(fn: (R) -> N): Either = when (this) {
is Right -> Right(fn(rightValue))
is Left -> this as Either
}

The N type parameter denotes the new Right hand-side type after fn has been applied. For cases where you call map and the current value of the Either is a Left (non happy path), then the map function cannot be applied as there is no Right value. As we know the current instance is already a Left, rather than create a new Left, we can safely cast the current instance to an Either as an optimisation.

flatMap

Implementation of flatMap is simpler than map in this case as fn already returns an Either. Therefore we just run the function against our right hand value. The left hand branch uses the same logic as above for map.

fun flatMap(fn: (R) -> Either): Either = when (this) {
is Right -> fn(rightValue)
is Left -> this as Either
}

L and R accessors

In order to access the underlying values we can provide getters for both left and right branches of the Either, an exception is thrown if the underlying type is not the expected value:

L and R Covariance

One problem with our current implementation is we can’t assign our Either expression to a value of Either with a subtype type parameter, for example take the model Cat extends Mammal, an Either[Error, Cat] could not be assigned to Either[Error,Mammal]. This is not desirable as it is generally a useful property to generalise on a particular interface type when writing generic code. We can achieve this by making our type parameters covariant, the keyword in Kotlin to denote this is out as a suffix to the type parameter:

sealed class Either<out L, out R>

A further explanation of covariance and contra-variance in Kotlin can be found on here.

inline and crossinline

In Kotlin higher order functions as parameters can be marked inline to avoid object allocations (lambdas are instances of objects underneath on the JVM!). This will inline the code at the call site during compilation removing any performance penalties. In addition crossinline disables the ability to local return inside a lambda (something we should enforce as we have no guarantee of scope or context when the lambda is run, there is a detailed blog post here describing the differences.

Arrow

Writing your own monads can be fun a exercise but if you want to start getting more serious with Functional programming then I would recommend checking out Arrow, a functional programming library for Kotlin. It contains all the common monad types (including Either) plus constructs to build your own monads. It also contains optics and recursion schemes which can be very useful.

Whilst gaining a deeper understanding of functional programming concepts and patterns I have found myself delving more deeply into the world of scalaz. Today the agenda is monad transformers, after some initial reading I very quickly started to see patterns in our codebase which could immediately benefit from their application.

What is a monad transformer? My definition (as a Software Engineer) is… a monad transformer is a typeclass that abstracts a monad which wraps another monad. This may not sound like something that happens a lot but it’s surprisingly common, take Future for example, all these cases below are monads nested within a monad.

Future[Option[T]]
Future[List[T]]
Future[scalaz.\/[A, B]]

Lets take the following scenario, you have two Lists of integers, and you want to add every element in List A to every element in List B and get a final List C. However both lists are wrapped in a Future. In pure Scala this may look something like this:

Notice that there is no way of accessing the underlying data without having to map over the Future followed by the List, which leads to the nested code you see above, this situation is where monad transformers can help us.

In our example our top level type was a Future[List[Int]], when choosing which monad transformer to use, you always choose the inner most type, in this case List[Int] is our inner most type so we will use the ListT monad transformer. The ListT apply function is as follows:

def apply[A](a: M[List[A]]) = new ListT[M, A](a)

Therefore we can use this to convert our Future[List[Int]] to the ListT monad type which in this case will be a ListT[Future, Int]. We can now write our addition in terms of the new monad type which has abstracted the mapping of the Future:

Notice we returned ListT[Future, Int], as with any Functor, calling map will always return the same monad type wrapping the transformed value. This allows you to chain/compose operations in terms of your monad transformers until you are ready to unwrap back to your original type, which can be done using the run method:

In summary monad transformers give you a powerful abstraction to work on the underlying data of a monadic type when it itself is wrapped in a monad. It reduces code complexity and enhances readability by abstracting the wiring of drilling down into the nested datatypes. ScalaZ provides implementations of monad transformers for many types including EitherT, ListT, OptionT and ReaderT to name a few.

Recent Posts

About the author

I'm Rama Nallamilli, software engineer and brazillian jujitsu practitioner based in London, UK. I have a passion for technology and modern engineering practices. My blog will discuss topics across the whole spectrum of development but Scala, DevOps and Distributed Systems are subjects I am particularly passionate about.

My previous experience includes working in engineering teams at the BBC, HMRC, Sky and Expedia. I am currently working as a Data/Software Engineer for Babylon Health, a UK leading startup in the A.I healthcare space.

I spend my spare time training in Brazilian Jujitsu and currently hold a purple belt.