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 in 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);
Update
After reviewing it I realized monads are much more simpler and can be explained from a programming perspective. No need for Category theory.
So far I observed two programming cases monads solve.
First case
Supposedly there is this list
parentList = List[List[B]]
The generic problem is to doSomeStuff on each element.
for(every i in parentList ) {
for(every j in childList[i]){
doSomeStuff
}
}
Writen in a monadic way:
parentList.forEachElementDo(childList -> childList.forEachElementDo(doSomeStuff))
It is clear now that the result is flattened(into doSomeStuff return type) therefore the flatMap function used in monads.
Thus, in a conventional manner, the code becomes:
parentList.flatMap(childList -> childList.flatMap(someStuff))
Second case
If you chain "fors" as:
parentList.flatMap(doFirstStuff).flatMap(doSecondStuff)
You basically "monaded" this code:
for(int i=0; i<....){
doFirstStuff
}
for(int j=0; j<....){
doSecondStuff;
}
Conclusion
I know it is explained in the most simple way possible and it seems unbelievable for people who spent years learning and explaining monads. Sorry for this attack on your vanity, if you will not be able to get over it you will comment that there is a bind function and an identity element and much more related to monads. Whatever makes you happy. However, would appreciate comments that will show my mistake or additional examples that are solved through monads. With your permission I will reference them in this article.
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)