First of all, if you didn't read the previous post, go do so, otherwise you might be missing some essential concepts! _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…_medium.com Kotlin Functors, Applicatives, And Monads in Pictures. Part 1/3 (draft) Applicatives Applicatives take it to the next level. With an applicative, our values are wrapped in a context, just like : Functors But our functions are wrapped in a context too! Yeah. Let that sink in. Applicatives don’t kid around. Unlike Haskell, doesn’t have a built-in way to deal with Applicatives. But it is very easy to add one! We can define an function for every type supporting Applicative, which knows how to apply a function wrapped in the context of the type to a value wrapped in the same context: Kotlin yet apply infix fun <A, B> Option<(A) -> B>.apply(f: Option<A>): Option<B> =when (this) {is Option.None -> Option.Noneis Option.Some -> f.map(this.value)} infix inline fun <A, reified B> Array<(A) -> B>.apply(a: Array<A>) =Array(this.size * a.size) {this[it / a.size](a[it % a.size])} If both and the function are , then the function is applied to the unwrapped option, otherwise is returned. this Some None For the I'm using its constructor parameters to generate the array, although note that this wouldn't be the most performant choice for bigger arrays. Array this would be the in Haskell, so again we could use a operator if needed. Note: <*> * i.e: Some({ a: Int -> a + 3 }) apply Some(2) // => Some(5) If you look carefully you will see that our operator only works in this specific order: why? Because our extension function is defined in that order. Then, couldn’t I just make another extension function to work the other way around, like: Option(function) apply Option(value) fun <A, B> Option<A>. (o: Option<(A) -> B>) = {...}fun <A, B> Option<(A) -> B>. (o: Option<A>) = {...} apply apply Technically not. Since Kotlin produces same code as Java would, it has to deal with our friend the . So basically those 2 functions would loose the generic types at compile time (and become just ), making them equal and therefore invalid. But here’s a trick, we could use a so called (and you can read why ) so it would look like: type erasure Option dummyImplicit here fun <A, B> Option<A>.apply(f: Option<(A) -> B>,dummyImplicit: Any? = null): Option<B> =when (this) {is Option.None -> Option.Noneis Option.Some -> f.map { it(value) }} This allows us to do: Some(2). (Some( a: Int a + 3 )) apply { -> } // => Some(5) But unfortunately it makes the infix impossible since infix functions only have one parameter :( So, following our previous explanation, using can lead to some interesting situations. For example: apply arrayOf<(Int) -> Int>({ it + 3 }, { it * 2 }) arrayOf(1, 2, 3) apply // => [ 4, 5, 6, 2, 4, 6 ] Note: the original article now shows how Applicatives are more powerful than Functors in that they allow function application with multiple parameters. Again this is not feasible in vanilla Kotlin, but we can work around it by defining the function we want to handle in a curried way . Here’s something you can do with Applicatives that you can’t do with Functors. How do you apply a function that takes two arguments to two wrapped values? fun curriedAddition(a: Int) = { b: Int ->a + b} Some(3) map ::curriedAddition map Some(2) // => COMPILER ERROR Applicatives: Some(3) map ::curriedAddition apply Some(2)// => Some(5) Wait, what?? Let me break it down step by step: Some(3) map ::curriedAddition// => Some({ 3 + b }) Some({ 3 + b }) apply Some(2)// => Some(5) pushes aside. “Big boys can use functions with any number of arguments,” it says. “Armed with map and apply, I can take any function that expects any number of unwrapped values. Then I pass it all wrapped values, and I get a wrapped value out! AHAHAHAHAH!” Applicative Functor fun curriedTimes(a: Int) = b: Int a * b { -> } Some(3) map ::curriedTimes apply Some(5)// => Some(15) But wait, what if we want to go deeper? Suppose we have a triple product function: fun tripleProduct(a: Int, b: Int, c: Int) = a * b * c We want to do the same as before but we don't want to manually curry it, so we have a curry function, in this case for 3 params: fun <A, B, C, D> curry(f: (A, B, C) -> D): (A) -> (B) -> (C) -> D = a b c f(a, b, c) { -> { -> { -> } } } Thanks for the suggestion! Ľuboš Mudrák Well, that's easy: Some(3) map (::tripleProduct) apply Some(5) apply Some(4)// => Some(60) curry That’s it! Hope you enjoyed this second part as much as I did while writting it, remember that you can find all the code in the and hope to see you in the next and final series! playground repo I created The third and final part is already available" _This is a translation of Functors, Applicatives, And Monads In Pictures from Haskell into Kotlin._medium.com Kotlin Functors, Applicatives, And Monads in Pictures. Part 3/3