">
 

You've Been Using Monads Without Realizing It

Iniciado por joomlamz, Hoje at 06:09

Respostas: 0   |   Visualizações: 2

Tópico anterior - Tópico seguinte

0 Membros e 1 Visitante estão a ver este tópico.

You've Been Using Monads Without Realizing It



Tópico: You've Been Using Monads Without Realizing It
Categoria: Tutoriais | Programação & Tecnologia
Idioma Principal: Português (Conteúdo de Tecnologia)

Descrição do Conteúdo / Informações:
-------------------------------------------------------------------------
Let's get the scary part out of the way.

The word:

Monad

has probably scared away more developers than any other term in programming.

The moment somebody mentions Monads, the conversation usually becomes:

Category Theory
Endofunctors
Monoids
Kleisli Composition
Higher-Kinded Types

Most developers immediately think:

This isn't for me.

Which is unfortunate.

Because Monads are actually one of the most practical abstractions in software engineering.

And if you've ever used:

Promise.then(...)

or

Array.flatMap(...)

or

RxJS switchMap(...)

then you've already been using Monads.

You just didn't know the name.



Why Developers Fear Monads


Monads suffer from a marketing problem.

Most concepts in programming are taught from examples.

For example:

const doubled =
[1,2,3].map(
x => x * 2
)

Nobody starts by defining Arrays using abstract mathematics.

We start with examples.

Monads are often taught backwards.

The theory comes first.

The intuition comes last.

Let's fix that.



The Problem That Creates Monads


Imagine we have:

const users = [
{
id: 1,
orders: [101, 102]
},
{
id: 2,
orders: [103]
}
]

If we do:

users.map(
user => user.orders
)

we get:

[
[101, 102],
[103]
]

Nested arrays.

We saw this in the previous article.

To solve it:

users.flatMap(
user => user.orders
)

Result:

[
101,
102,
103
]

FlatMap removes the extra container layer.



The Same Problem Exists Everywhere


Arrays are not special.

Consider Promises.

Promise.resolve(10)
.then(x => {
return Promise.resolve(
x * 2
)
})

What do we get?

Not:

Promise<Promise<number>>

Instead:

Promise<number>

The nesting disappears.

Why?

Because Promise.then behaves like FlatMap.



The Monad Recipe


Every Monad has two operations.

A way to put a value into the container:

Value

Container<Value>

For Promises:

Promise.resolve(10)

For Arrays:

[10]

For RxJS:

of(10)

And a way to chain operations that return containers:

flatMap

or equivalent.

That is essentially the Monad pattern.



Arrays Are Monads


Most developers never hear this.

But Arrays are Monads.

Let's prove it.

Create a value:

const value = [10]

Chain computations:

const result =
value.flatMap(
x => [x * 2]
)

Output:

[20]

Now chain again:

const result =
[10]
.flatMap(x => [x * 2])
.flatMap(x => [x + 1])

Output:

[21]

Each step returns a container.

FlatMap composes them.

Monad behavior.



Promises Are Monads


This one surprises people.

Promise.resolve(10)
.then(x =>
Promise.resolve(
x * 2
)
)
.then(x =>
Promise.resolve(
x + 1
)
)

Result:

Promise<21>

Not:

Promise<
Promise<
Promise<21>
>
>

Promises flatten automatically.

Which means Promises satisfy the same pattern.



Why Async/Await Feels Natural


Async/await became popular because it hides Monad plumbing.

This:

const user =
await fetchUser()

const orders =
await fetchOrders(
user.id
)

feels straightforward.

Underneath:

fetchUser()
.then(user =>
fetchOrders(user.id)
)

is doing Monad composition.

JavaScript developers use Monads daily without realizing it.



RxJS Is Monad City


Consider:

searchText$
.pipe(
switchMap(
text => api.search(text)
)
)

Without switchMap:

Observable<
Observable<SearchResult>
>

With switchMap:

Observable<SearchResult>

The nesting disappears.

Again.

The same abstraction.



Why Monads Exist


Imagine a world without them.

Every operation returning a container would create another layer.

Array<Array<Array<T>>>

Promise<Promise<T>>

Observable<Observable<T>>

Composition would become painful.

Monads solve this.

They allow:

Container Operations

Compose Naturally

Without Nesting

That is their real purpose.

Not mathematics.

Not academic theory.

Composition.



Real World Example: Database Queries


Suppose:

getUser(id)

returns:

Promise<User>

And:

getOrders(userId)

returns:

Promise<Order[]>

Without flattening:

Promise<
Promise<Order[]>
>

Everywhere.

With Promise.then:

getUser(id)
.then(user =>
getOrders(user.id)
)

One clean chain.

This is why Monads matter.



Real World Example: API Pipelines


authenticate()
.then(session =>
fetchProfile(session)
)
.then(profile =>
fetchPermissions(profile)
)

Every step returns a Promise.

Yet the code remains flat.

Because Promise.then keeps flattening.



Monad Laws (Don't Panic)


Just like Functors have laws.

Monads have laws.

The good news?

They're surprisingly sensible.



Left Identity


Putting a value into a Monad and immediately chaining should behave the same as calling the function directly.

Conceptually:

Wrap

Chain

=

Direct Call



Right Identity


Wrapping and unwrapping should not change behavior.



Associativity


This:

value
.flatMap(f)
.flatMap(g)

should behave like:

value.flatMap(
x => f(x)
.flatMap(g)
)

This consistency is what makes composition reliable.



Why Most Monad Tutorials Fail


Because they start with:

Monad

Theory

Examples

This article does the opposite.

Arrays

Promises

RxJS

FlatMap

Monad

By the time we reached the word Monad, you already understood the idea.



Pros Of Monads




1. Powerful Composition


Container-producing functions chain naturally.



2. Eliminate Nesting


Avoid:

Promise<Promise<T>>

Array<Array<T>>

Observable<Observable<T>>



3. Common Across Ecosystems


Arrays.

Promises.

RxJS.

Streams.

Functional libraries.



4. Predictable Behavior


The laws provide consistency.



5. Foundation Of Modern Async Programming


Promises rely heavily on Monad-like behavior.



Cons Of Monads




1. Terrible Terminology


The word scares people.



2. Often Explained Poorly


Many tutorials focus on theory before intuition.



3. Easy To Overcomplicate


Simple ideas become academic discussions.



4. Different Libraries Use Different Names


flatMap
then
switchMap
mergeMap
chain
bind

Same family.

Different vocabulary.



5. Can Feel Abstract Initially


Until you connect them to familiar tools.



The Real Lesson


The funny thing about Monads is that they're not particularly complicated.

The terminology is.

The mathematics can be.

The idea itself isn't.

If you've used:

Promise.then(...)

or

Array.flatMap(...)

or

switchMap(...)

you've already been using Monads.

You simply learned the practical version before learning the name.

And honestly, that's probably the best way to learn them.



What's Next?


In the next article we'll leave pure FP terminology behind and explore a topic that surprises almost every JavaScript developer:

RxJS Is Just Arrays Over Time

Because once you see that relationship, most RxJS operators become dramatically easier to understand.



About The Author


Hi, I'm Amrish Khan.

I enjoy building developer tools, exploring software architecture, and writing about the deeper ideas behind everyday programming concepts.

I'm also building Aruvix — a growing ecosystem of local-first developer tools designed to process data directly in the browser without unnecessary uploads.

Here's a detailed blog on Aruvix:

https://dev.to/amrishkhan05/aruvix-the-ultimate-offline-first-developer-toolkit-e0i

You can follow my work and thoughts here:

Portfolio:

https://www.amrishkhan.dev

LinkedIn:

https://www.linkedin.com/in/amrishkhan

GitHub:

https://www.github.com/amrishkhan05

If you enjoyed this article, consider following for more deep dives into JavaScript, architecture, local-first software, and performance engineering.


Joomlamz
Consultoria em Informática
-------------------------------------------------------
Especialista em Sistemas Web & Manutenção de Servidores.
A desenvolver o novo AplPortal com suporte a PHP 8.
Precisa de ajuda profissional? Contacte-me.

Tags: