This is a translation ofFunctors, Applicatives, And Monads In PicturesfromHaskellintoKotlin.

Actually this is a translation ofanother translation from Haskell to Swift.

I read through the original post and I found it really interesting for learning new concepts of FP, so I decided to do an additional translation (having also some fun in the way).

I also wanted to see how far can Kotlin get compared to Swift :)

If you enjoy this post be sure to say thanks to the author of the original version:Aditya Bhargava,@_egonschieleon Twitter.

Here’s a simple value:

And we know how to apply a function to this value:

Simple enough. Lets extend this by saying that any value can be in a context. For now you can think of a context as a box that you can put a value in:

Now when you apply a function to this value, you’ll get different results **depending on the context**. This is the idea that Functors, Applicatives, Monads, Arrows etc are all based on. The `Option`

data type defines two related contexts:

Note:the pictures use Maybe (Just | None) from Haskell, which correspond to a custom Kotlin’sOption(Some | None) implementation.

sealed class Option<out A> {

object None : Option<Nothing>()

data class Some<out A>(val value: A) : Option<A>()

}

In a second we will see how function application is different when something is a `Some(T)`

versus a `None`

. First let’s talk about Functors!

### Functors

When a value is wrapped in a context, you can’t apply a normal function to it:

This is where `map`

comes in (`fmap`

in Haskell). `map`

is from the street, `map`

is hip to contexts. `map`

knows how to apply functions to values that are wrapped in a context. For example, suppose you want to apply a function that adds 3 to `Some(2)`

. Use `map`

:

`fun sumThree(n: Int) = n + 3`

Option.Some(2).map(::sumThree)

// => Some(5)

or with a simple syntax using an anonymous lambda:

`Option.Some(2).map`

{ it + 3 }

// => Some(5)

**Bam!** `map`

shows us how it’s done! But how does `map`

know how to apply the function?

### Just what is a Functor, really?

A Functor is any type that defines how `map`

(`fmap`

in Haskell) applies to it. Here’s how `map`

works:

So we can do this:

`Option.Some(2).map`

{ it + 3 }

// => Some(5)

And `map`

magically applies this function, because `Option`

is a Functor. It specifies how `map`

applies to `Some`

s and `None`

s:

inline fun <B> map(f: (A) -> B): Option<B> = when (this) {

is None -> this

is Some -> Some(f(value))

}

Here’s what is happening behind the scenes when we write `Option.Some(2).map { it + 3 }`

:

So then you’re like, alright `map`

, please apply `{ it + 3 }`

to a `None`

?

`Option.None.map { it + 3 }`

// => None

Well, there's a gotcha here since the code above doesn't compile. Why? Well because in this case None doesn't have a proper type, so you cannot do a plus with type `Nothing`

. But it should be fine because you normally won't write that code but something like:

`val option: Option<Int> = someCallThatMightReturnNone()`

option.map { it + 3 }

// => None

Like Morpheus in the Matrix, `map`

knows just what to do; you start with `None`

, and you end up with `None`

! `map`

is zen. Now it makes sense why the `Option`

type exists. For example, here’s how you work with a database record in a language without `Option`

:

`val post = Post.findByID(1)`

return post?.title

But in Kotlin using the `Option`

functor:

`findPost(1).map(::getPostTitle)`

If `findPost(1)`

returns a post, we will get the title with `getPostTitle`

. If it returns `None`

, we will return `None`

!

We can even define `map`

as an infix function for (`<$>`

in Haskell), and do this instead:

inline infix fun <B> map(f: (A) -> B): Option<B> { ... }

findPost(1) map ::getPostTitle

Note:we have to use just

mapbecause

<$>wouldn't compile. Another option would be to override a common operator like

/or

*

Here’s another example: what happens when you apply a function to an array?

Arrays are functors too*!

*Basically Kotlin provides an extension function to all iterables in the form:

inline fun <T, R> Iterable<T>.map(transform: (T) -> R): List<R> {..}

Okay, okay, one last example: what happens when you apply a function to another function?

`{ a: Int -> a + 2 } map { a: Int -> a + 3 }`

// => ???

Here's a function:

Here’s a function applied to another function:

The result is just another function!

`typealias IntFunction = (Int) -> Int`

infix fun IntFunction.map(g: IntFunction): IntFunction {

return { x -> this(g(x)) }

}

val foo = { a: Int -> a + 2 }map{ a: Int -> a + 3 }foo(10)

// => 15

So functions can be Functors too! When you use `map`

on a function, you’re just doing function composition!

#### Well, that's it for today, I hope you got the idea about what's a Functor. Since the original post was pretty long, I'll continue in the next series with Applicatives. Now go try write some Functors in Kotlin!

#### Wanna play around with the code? Take a look at https://github.com/aballano/FAM-Playground

Want more? Go try applicatives in the second part!

Hacker Noon is how hackers start their afternoons. We’re a part of the @AMI family. We are now accepting submissions and happy to discuss advertising & sponsorship opportunities.

If you enjoyed this story, we recommend reading our latest tech stories and trending tech stories. Until next time, don’t take the realities of the world for granted!