Desvendando a Monad Result em JavaScript

Rmag Breaking News

Introdução:

Ao desenvolver em JavaScript, frequentemente nos deparamos com situações em que precisamos lidar com operações que podem ter sucesso ou falhar. Para facilitar esse cenário, podemos recorrer à monad Result, uma ferramenta poderosa que nos permite lidar com essas situações de forma elegante e segura. Neste artigo, vamos explorar como criar e usar a classe Result em JavaScript, inspirada no Result do Rust, e entender como ela se encaixa no conceito de monad.

O que é a Monad Result?

A monad Result encapsula um valor que pode representar um resultado bem-sucedido ou um erro. É como uma caixinha que nos permite tratar operações que podem falhar de forma mais estruturada e previsível. Se você já está familiarizado com o Result em Rust, vai perceber que a ideia é bem similar.

Criando a Classe Result em JavaScript:

Vamos dar uma olhada na implementação básica da classe Result em JavaScript:

class Result {
constructor(value, error) {
this.value = value;
this.error = error;
}

static Ok(value) {
return new Result(value, null);
}

static Err(error) {
return new Result(null, error);
}

map(fn) {
return this.error ? this : new Result(fn(this.value), null);
}

andThen(fn) {
return this.error ? this : fn(this.value);
}

catch(fn) {
return this.error ? fn(this.error) : this;
}

unwrap() {
if (this.error) {
throw new Error(this.error);
}
return this.value;
}
}

// Definindo uma função para dividir dois números
function dividir(a, b) {
// Verificando se o divisor é zero
if (b === 0) {
// Se for, retornamos um Result.Err com uma mensagem de erro
return Result.Err(Não é possível dividir por zero.);
} else {
// Caso contrário, retornamos um Result.Ok com o resultado da divisão
return Result.Ok(a / b);
}
}

// Exemplo de uso da função dividir
const resultadoDivisao = dividir(10, 2)
.map(resultado => resultado * 3) // Multiplicando o resultado por 3
.andThen(resultado => Result.Ok(resultado + 5)) // Adicionando 5 ao resultado
.unwrap(); // Desembrulhando o valor final

console.log(resultadoDivisao); // Resultado = 20

// Tentativa de dividir por zero, erro propagado
const resultadoVoid = dividir(10, 0)
.map(resultado => resultado * 3) // Não será executado devido ao erro
.andThen(resultado => Result.Ok(resultado + 5)) // Não será executado devido ao erro

// Como não foi feito unwrap, o erro não foi tratado e permanece no objeto Result.
console.log(resultadoVoid) // Result { value: null, error: ‘Não é possível dividir por zero.’ }

// Tentativa de dividir por zero, erro propagado e tratado com try-catch
try {
dividir(10, 0)
.map(resultado => resultado * 3) // Não será executado devido ao erro
.andThen(resultado => Result.Ok(resultado + 5)) // Não será executado devido ao erro
.unwrap();
} catch (error) {
console.log(error.message); // A mensagem de erro é capturada e exibida: “Não é possível dividir por zero.”
}

// Tentativa de dividir por zero, erro capturado e manipulado
const resultadoDivisaoPorZero = dividir(10, 0)
.map(resultado => resultado * 3) // Não será executado devido ao erro
.andThen(resultado => Result.Ok(resultado + 5)) // Não será executado devido ao erro
.catch((e) => Result.Err(`Ocorreu um erro: ${e}`)); // O erro é capturado e uma mensagem personalizada é retornada

console.log(resultadoDivisaoPorZero); // Result { value: null, error: ‘Ocorreu um erro: Não é possível dividir por zero.’ }

Conclusão:

A monad Result em JavaScript é uma ferramenta valiosa para lidar com situações de sucesso ou falha de forma estruturada e controlada. Ao entender como criar e usar essa classe, podemos escrever código mais robusto e previsível em nossos projetos.

Se você quiser saber mais sobre monads e programação funcional, recomendo dar uma olhada nestes links:

https://www.treinaweb.com.br/blog/conceitos-de-linguagens-funcionais-uma-breve-introducao-aos-monads/
https://medium.com/tableless/programa%C3%A7%C3%A3o-funcional-avan%C3%A7ada-monads-em-javascript-862e8588fcdf

Leave a Reply

Your email address will not be published. Required fields are marked *