Gniazdo.JS | Monady -> IO

Jan 27 2023
Monada IO, znana również jako „monada wejścia/wyjścia”, jest funkcjonalną koncepcją programowania, która pozwala oddzielić opis operacji wejścia/wyjścia od jej wykonania. Innymi słowy, umożliwia zdefiniowanie obliczeń, które wykonują pewne działania we/wy (takie jak odczyt z pliku lub interakcja z bazą danych) bez faktycznego wykonywania tych działań, dopóki nie zostaną jawnie wywołane.

Monada IO, znana również jako „monada wejścia/wyjścia”, jest funkcjonalną koncepcją programowania, która pozwala oddzielić opis operacji wejścia/wyjścia od jej wykonania. Innymi słowy, umożliwia zdefiniowanie obliczeń, które wykonują pewne działania we/wy (takie jak odczyt z pliku lub interakcja z bazą danych) bez faktycznego wykonywania tych działań, dopóki nie zostaną jawnie wywołane.

Monada IO jest często używana do zarządzania efektami ubocznymi w funkcjonalnym języku programowania, takim jak JavaScript. Monada we/wy umożliwia opisanie efektywnego obliczenia w czysty, łatwy do ułożenia sposób, co ułatwia rozumowanie i testowanie kodu.

Monada IO jest zwykle implementowana jako obiekt, który ma pojedynczą metodę o nazwie run, która wykonuje akcję I/O i zwraca wynik. Monada IO może być używana do łączenia wielu operacji I/O i tworzenia bardziej złożonych obliczeń.

Oto przykład monady IO w JavaScript:

class IO {
  constructor(effect) {
    this.effect = effect
  }
  run() {
    return this.effect()
  }
  map(f) {
    return new IO(() => f(this.run()))
  }
  chain(f) {
    return new IO(() => f(this.run()).run())
  }
  // ...
}

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

@Injectable()
export class MyService {
  public async getUsers(): IO<User[]> {
    return io.fromPromise(this.userRepository.find());
  }

  public async getUserById(id: string): IO<User> {
    return io.fromPromise(this.userRepository.findOne(id));
  }
}

Możesz połączyć wiele obliczeń za pomocą metod .map(), .chain(), .ap().

const program: IO<string> = myService.getUsers()
    .map(users => users.filter(user => user.age > 18))
    .chain(users => myService.getUserById(users[0].id))
    .map(user => user.name)

  program.run()

Należy zauważyć, że ten przykład jest prosty i nie pokazuje pełnej mocy monad w programowaniu funkcjonalnym. Monad można używać do obsługi różnych przypadków, takich jak obsługa błędów, łączenie wielu obliczeń i nie tylko. Najlepiej zrozumieć problem i przypadki użycia przed zastosowaniem monad.

Ponadto run()metoda musi zostać wywołana w celu wykonania monady IO i uzyskania wyników, jest to znane jako impurezależne od zewnętrznego stanu/kontekstu, monady IO są używane do oddzielenia nieczystego kodu od czystego kodu w celu lepszej organizacji kodu i testowanie.

Lista części: