Have started to learn Scala and stumbled upon Monad concept or I would call it a blunt misconception as all the articles and answers regarding this concept are incomplete, misleading and taste of "confusion".
I recall a discussion, a couple of years ago, with a colleague who was part of Scala study community in the company we were both working for, and an eager promoter of Scala and alike solutions, who mentioned that Scala is more interesting than Java because it contains Monads. When asked about what is a Monad, there was no clear answer however an example was given - "think about it as an Optional(Java8) or Either(from Vavr)".
I ignored it until recently got an opportunity to become a Scala dev that made me analyze and hopefully understand this concept so that there is no ambiguity if I am ever asked about it.
First thing I found out is that Monad is not a concept defined in Scala and that you have to implement it or benefit from already created ones.
Second thing is that a construction like:
int sum = Stream.of("String 1", "String 2", "String 3", "String 4", "String 5")
.mapToInt(String::length)
.reduce(0, Integer::sum);
is a Monad is Java.
Here is how I came to this conclusion.
- Have read the articles about Monad, found out it is a Functor.
- A Functor is a mapping between Categories, in simple terms it associates for any element x in Category A an element y in Category B,
- A Category is a structure that consists of a set of objects, a set of morphisms and a binary operation defined on compatible pairs of morphisms called composition.
- A category that has only one object is a Monoid. And this is the key to reverse engineer the whole concept.
From Monoid to Monad
Monoid definition is simple
- Set
- Binary operation with a result in the same Set
- Identity element
So lets define two monoids
Monoid S
- A set of all strings
- Concatenation operation (returns a string, also a part of set)
- Identity element is ""
Monoid I
- A set of all integers
- (+) operation
- Identity element is 0
From Monoid to Category
Monoid is a particular form of Category, thus we have two categories S and I.
From Category to Functor
We define a morphism from Category S to Category I:
(String item) -> item.length
And we have the java Monad
sum = Stream.of("String 1", "String 2", "String 3", "String 4", "String 5")
.mapToInt(String::length)
.reduce(0, Integer::sum);
I am still at the beginning, so leaving this topic opened until a better answer is found. Feel free to let me know your thoughts, don't forget to mention your sources.
Sources
Monad:
https://en.wikipedia.org/wiki/Monad_(functional_programming)
Functor:
https://en.wikipedia.org/wiki/Functor#endofunctor
Category:
https://mathworld.wolfram.com/Category.html
https://en.wikipedia.org/wiki/Category_(mathematics)
Monoid:
https://en.wikipedia.org/wiki/Monoid#Monoid_homomorphisms
Top comments (0)