First of all, if you didn't read the previous post, go do so, otherwise you might be missing some essential concepts!

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, Kotlin doesn’t have yet a built-in way to deal with Applicatives. But it is very easy to add one! We can define an apply 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:

infix fun <A, B> Option<(A) -> B>.apply(f: Option<A>): Option<B> =

when (this) {

is Option.None -> Option.None

is 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 this and the function are Some , then the function is applied to the unwrapped option, otherwise None is returned.

For the Array I'm using its constructor parameters to generate the array, although note that this wouldn't be the most performant choice for bigger arrays.

Note: this would be the <*> in Haskell, so again we could use a * operator if needed.

i.e: