Monads, Comonads, come on, go nuts

TL;DR: Comonads give you access to a context.

There is a stormy discussion about writing Swift in a functional manner. I am not gonna dive deep into it. But i like to demonstrate one particular piece of Type, coming out of the FP world: The Commonad.

Even if Swift is missing so called Higher Kinded Types (TypeConstructors or Types that create Types a.k.a. * -> *), we got some monadic flavored Types in the stdlib. Optionals for example. If you feel unsure about understanding monads, don`t panic. Someday it will click.

Anyway, when you read on about the category theory stuff, you might come across a Type called Comonad. Described as the categorical dual to a Monad it sounds fairly abstract and possibly without use case for the 9-5 programmer.

But as always, it helps to try it out yourself.

Beware: Adding a comonadic type in swift is possible. Wether you see a use case is up to you.

Monads 📦

The easy way - missing out many important parts:

// simplified flatMap method of Optional
flatMap<U>(f: Wrapped -> U?) -> U? 

Comonads 🎊

A Comonad flips the direction of the provided flatMap function, and the method name itself gets renamed to extend. So if we wanna make the Optional Type a Comonad it would also need to have an extend method.

// hypothetical, silly extend method of optional 
extend<U>(f: Wrapped? -> U) -> U?

If you want the full fledged answer: Wikipedia

But that type signature makes no sense with Optionals. And to be honest: Its kinda hard to see what it does at all. So lets build a Type that makes sense.

Imagine 💭

  • ☑️ You have an Array of Ints.
  • ☑️ And you know you point to a certain position within that array.
  • ☑️ And now you want to get the average of the value at the position, the position before, the position after.
  • ☑️ And in the next step you wanna know if this calculated average is higher than the average of the position before.

Doing this in an imperative way is possible. easy. But it can get a bit messy, and might not really be reusable.

Tada, Time for Comonad. 🎉

I am not gonna write too much in advance. You should be able to run the snippet below in a playground. Here an example screenshot of the playground:


As people often say: Once you understand the concept of Monads you loose the capability to explain them. The same is valid for Comonads. But keep in mind:

  • Comonads care deeply about their structure
  • Comonads are great for things where you have a position in a structure (e.g. TreeZipper)
  • Comonads might not be relevant to the code you write next week

Follow Up

There is a folllow up on how to make that type lazy

👻 Feel free to hit me on twitter. @elmkretzer