# Functors, Applicatives, and Monads in Plain English

Let’s learn what Monads, Applicatives, and Functors are, only instead of relying on obscure functional vocabulary or category theory we’ll just, you know, use plain english instead .

## Functors

Functors are containers you can call `map` on. That’s it. Seriously.

A million words of category theory and Haskell examples to say Functors contain stuff and if you apply a function to that stuff you get the same kind of container back out with the stuff inside it transformed.

Functors you already know and love include `Optional` and all the Swift standard library sequence types like `Dictionary` , `Array` , and `Set` .

To put it another way, a Functor applies functions to the values it contains, instead of to itself. Normally if I call some function `doStuff(value: Int)` it requires I pass an `Int` . If I have an `Optional<Int>` , `doStuff` has no clue what to do with that. But since `Optional` is a Functor it understands how to take `doStuff` and execute it on the value inside itself, then spit out a new `Optional` . You don’t lose the int-ness or optional-ness .

Know what else can be a Functor? Functions!

`// hooray, functions are functors now. func map<T>(f1: (T) -> T, f2: (T) -> T) -> (T) -> T {     return { f1(f2(\$0)) } }`

Swift can’t represent Functor in the type system at the moment because it doesn’t have "Higher-Kinded Types".

## Applicatives

Applicative lets you stuff the function itself inside a container, otherwise it’s almost identical to Functors.

I told you we were going to use plain english.

Why? Because you may want to have a function in the container and apply it to value(s) in another container of the same kind. You could extend Optional with `apply` like this:

`extension Optional {     func apply<U>(f: ((Wrapped) throws -> U)?) rethrows -> U? {         return try f.flatMap(self.map)     } }`

(Some versions of the compiler require dual definitions because it doesn’t consider an optional throwing closure as a candidate for `rethrows` but I believe that bug is fixed.)

Swift doesn’t have a built-in definition for applicative because you can’t extend a protocol to say it returns the same container type but with a different element type.

Monads are containers you can call `flatMap` on. Again, that’s it.

Why? Because a monad takes special care to avoid double-containering (take that Oxford English Dictionary ). `flatMap` just says unwrap a value from it’s container, apply some function to it, then re-wrap it in a container. If the function spits out the same kind of container just use that instead of wrapping it in a second level container.

Once again, `Optional` is in fact a Monad. That’s because you can do this:

`let value: Int? = 5 // <-- value is wrapped inside a container  // This function has no idea about containers, // it only wants Ints. It may or may not give us a String. func sayHello(x: Int) -> String? {     return arc4random() % 2 == 0 ? "hi there /(x)" : nil }  // That's OK, flatMap will unwrap value if not nil // and feed it to sayHello. We get a String? back out // so if value is nil we don't lose our optional-ness either. let greeting: String? = value.flatMap(sayHello)`

We have to preserve the optionality of the result because if our input is `nil` the only valid thing we can do is return `nil` . We can’t sensibly cast `nil` to an `Int` and call `sayHello` anyway. `flatMap` saves us from gobs of boilerplate:

`let value: Int? = 5 // <-- value is wrapped inside a container  // This function has no idea about containers, // it only wants Ints. It may or may not give us a String. func sayHello(x: Int) -> String? {     return arc4random() % 2 == 0 ? "hi there /(x)" : nil }  // Manually doing what flatMap does let greeting: String? switch value { case .Some(let wrapped):     //if we have a value      switch sayHello(wrapped) {     case .Some(let result):         //function produced a value         greeting = Optional<String>.Some(result)     case .None:         //function produced nil         greeting = Optional<String>.None     } case .None:      //value itself was nil     greeting = Optional<String>.None }`

## Conclusion

It’s nice to be able to preserve the "ness" of something, especially when you have containers with multiple states (like Optional) or values inside them (like Collections).

You can take a function that doesn’t understand arrays and feed it values one at a time, while still preserving the "array"-ness.

You can take a function that doesn’t understand optionals and feed it the wrapped value if there is one, while still preserving the optionality (which comes in handy if it happens to be `nil` ).

Monads are about taking stupid dumb functions that don’t have any clue about containers and applying those functions to the values inside the containers while preserving the containers in the result .

Update: @al_skipp pointed out my original `flatMap` example could be improved to better show how `flatMap` avoids double-wrapping values in the container. I’ve updated the post.