Nido.JS | Mónadas -> Estado

Jan 27 2023
La mónada de estado es un concepto de programación funcional que le permite administrar el estado de una manera funcional e inmutable. Le permite escribir código que actualiza el estado de un cómputo de una manera pura y componible, lo que hace que sea más fácil razonar y probar.

La mónada de estado es un concepto de programación funcional que le permite administrar el estado de una manera funcional e inmutable. Le permite escribir código que actualiza el estado de un cómputo de una manera pura y componible, lo que hace que sea más fácil razonar y probar.

La mónada de estado se usa a menudo para administrar cálculos con estado en un lenguaje de programación funcional, como JavaScript. La mónada de estado le permite describir un cálculo que actualiza algún estado de una manera pura y componible, lo que facilita el razonamiento y la prueba de su código.

Una mónada de estado normalmente se implementa como un objeto que tiene un solo método, llamado run, que toma el estado inicial como entrada y devuelve el resultado del cálculo y el estado actualizado. La mónada State se puede usar para encadenar varios cálculos que actualizan el mismo estado y crean cálculos más complejos.

Aquí hay un ejemplo de la mónada State en JavaScript:

class State {
  constructor(fn) {
    this.run = fn
  }
  map(f) {
    return new State((state) => {
        const [result, updatedState] = this.run(state);
        return [f(result), updatedState];
    });
  }
  chain(f) {
    return new State((state) => {
        const [result, updatedState] = this.run(state);
        return f(result).run(updatedState);
    });
  }
  // ...
}

Por ejemplo, podría crear un Estado que tome un número inicial y devuelva un nuevo número incrementado en uno, luego podría encadenar varios de estos Estados para crear un cálculo más complejo que actualice el estado varias veces, sin tener que pasar manualmente el Estado a través de cada paso.

Es importante tener en cuenta que State Monad no es un patrón común en JavaScript, se usa principalmente en lenguajes de programación funcionales como Haskell, scala, etc.

Aquí hay un ejemplo de cómo podría usar StateMonad en Nest.js:

import { Injectable } from '@nestjs/common';
import { State, state } from 'fp-ts/lib/State';

interface StateType {
  counter: number;
}

@Injectable()
export class MyService {
  public incrementCounter(): State<StateType, number> {
    return state.get().map(s => s.counter + 1).put({ counter: s.counter + 1 });
  }

  public decrementCounter(): State<StateType, number> {
    return state.get().map(s => s.counter - 1).put({ counter: s.counter - 1 });
  }

  public getCounter(): State<StateType, number> {
    return state.get().map(s => s.counter);
  }
}

Monad Statese usa para administrar el estado de una manera funcional, este ejemplo usa un contador simple como estado, pero el estado podría ser cualquier cosa como un objeto o una matriz.

El incrementCounter()método incrementa el contador y actualiza el estado, el decrementCounter()método disminuye el contador y actualiza el estado, el getCounter()método devuelve el valor actual del contador.

Puede encadenar varios cálculos utilizando los métodos .map(), .chain(), .ap().

const program: State<StateType, number> = myService
  .incrementCounter()
  .chain(() => myService.incrementCounter())
  .chain(() => myService.getCounter());

console.log(program.run({ counter: 0 }).value);

Es importante tener en cuenta que este ejemplo es básico y no demuestra todo el poder de Monads en la programación funcional. Las mónadas se pueden usar para manejar varios casos, como el manejo de errores, el encadenamiento de múltiples cálculos y más. Es mejor comprender el problema y los casos de uso antes de aplicar las mónadas.

Además, el run()método debe ser llamado para ejecutar State Monad y obtener los resultados, toma un estado inicial como argumento.

Lista de piezas: