ネスト.JS | モナド -> 状態

Jan 27 2023
State モナドは、機能的で不変な方法で状態を管理できるようにする関数型プログラミングの概念です。これにより、純粋で構成可能な方法で計算の状態を更新するコードを作成できるため、推論とテストが容易になります。

State モナドは、機能的で不変な方法で状態を管理できるようにする関数型プログラミングの概念です。これにより、純粋で構成可能な方法で計算の状態を更新するコードを作成できるため、推論とテストが容易になります。

State モナドは、JavaScript などの関数型プログラミング言語でステートフル計算を管理するためによく使用されます。State モナドを使用すると、純粋で構成可能な方法で一部の状態を更新する計算を記述することができるため、コードの推論とテストが容易になります。

State モナドは通常、 と呼ばれる単一のメソッドを持つオブジェクトとして実装されますrun。このメソッドは初期状態を入力として受け取り、計算の結果と更新された状態を返します。State モナドを使用すると、同じ状態を更新し、より複雑な計算を作成する複数の計算を連鎖させることができます。

以下は JavaScript の State モナドの例です。

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);
    });
  }
  // ...
}

たとえば、最初の数値を受け取り、1 ずつ増分された新しい数値を返す State を作成できます。その後、これらの State を複数連結して、手動でパラメータを渡すことなく、状態を複数回更新するより複雑な計算を作成できます。各ステップの状態を示します。

State Monad は JavaScript では一般的なパターンではなく、主に Haskell、scala などの関数型プログラミング言語で使用されることに注意することが重要です。

StateNest.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);
  }
}

モナドStateは機能的な方法で状態を管理するために使用されます。この例では状態として単純なカウンターを使用していますが、状態はオブジェクトや配列など何でも構いません。

メソッドincrementCounter()はカウンタをインクリメントして状態を更新し、decrementCounter()メソッドはカウンタをデクリメントして状態を更新し、メソッドはgetCounter()現在のカウンタ値を返します。

.map()、.chain()、メソッドを使用して複数の計算を連鎖させることができます.ap()。

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

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

この例は基本的な例であり、関数型プログラミングにおけるモナドの能力をすべて実証するものではないことに注意することが重要です。モナドは、エラー処理、複数の計算の連鎖など、さまざまなケースを処理するために使用できます。モナドを適用する前に、問題とユースケースを理解することが最善です。

また、run()State モナドを実行して結果を取得するにはメソッドを呼び出す必要があり、初期状態を引数として受け取ります。

パーツのリスト: