Heim  >  Artikel  >  Web-Frontend  >  Einführung in die funktionale Programmierung in JavaScript: Verschiedene Monaden #11

Einführung in die funktionale Programmierung in JavaScript: Verschiedene Monaden #11

王林
王林Original
2024-07-18 20:34:41945Durchsuche

Introduction to Functional Programming in JavaScript: Different monads #11

Monaden sind ein grundlegendes Konzept in der funktionalen Programmierung, das eine Möglichkeit bietet, Berechnungen und Datentransformationen strukturiert abzuwickeln. Es gibt verschiedene Arten von Monaden, die jeweils darauf ausgelegt sind, spezifische Probleme zu lösen und unterschiedliche Arten von Daten und Effekten zu verarbeiten.

Was ist eine Monade?

Eine Monade ist eine Abstraktion, die die Verkettung von Operationen an umschlossenen Werten ermöglicht. Es wird durch drei Haupteigenschaften definiert:

  1. Einheit (auch of oder return genannt): Eine Funktion, die einen Wert annimmt und ihn in eine Monade verpackt.
  2. Bind (auch FlatMap oder Chain genannt): Eine Funktion, die einen monadischen Wert annimmt, und eine Funktion, die eine Monade zurückgibt, die Funktion auf den umschlossenen Wert anwendet und eine neue Monade zurückgibt.
  3. Assoziativität: Die Zusammensetzung monadischer Operationen sollte assoziativ sein.

Häufige Arten von Monaden

  1. Vielleicht Monad
  2. Entweder Monade
  3. Promise Monad
  4. Monade auflisten
  5. Lesermonade
  6. Schriftstellermonade
  7. Staatsmonade

1. Vielleicht Monade

Die Maybe-Monade wird zur Verarbeitung optionaler Werte verwendet. Es stellt eine Berechnung dar, die möglicherweise fehlschlägt oder null oder undefiniert zurückgibt.

Durchführung
class Maybe {
  constructor(value) {
    this.value = value;
  }

  static of(value) {
    return new Maybe(value);
  }

  isNothing() {
    return this.value === null || this.value === undefined;
  }

  map(fn) {
    return this.isNothing() ? this : Maybe.of(fn(this.value));
  }

  flatMap(fn) {
    return this.isNothing() ? this : fn(this.value);
  }
}

// Usage
const maybeValue = Maybe.of('hello')
  .map(str => str.toUpperCase())
  .flatMap(str => Maybe.of(`${str} WORLD`));
console.log(maybeValue); // Maybe { value: 'HELLO WORLD' }

2. Entweder Monade

Die Entweder-Monade wird verwendet, um Berechnungen durchzuführen, die entweder einen Erfolgswert (rechts) oder einen Fehlerwert (links) zurückgeben können.

Durchführung
class Either {
  constructor(value, isRight = true) {
    this.value = value;
    this.isRight = isRight;
  }

  static right(value) {
    return new Either(value, true);
  }

  static left(value) {
    return new Either(value, false);
  }

  map(fn) {
    return this.isRight ? Either.right(fn(this.value)) : this;
  }

  flatMap(fn) {
    return this.isRight ? fn(this.value) : this;
  }
}

// Usage
const rightValue = Either.right(5)
  .map(x => x + 1)
  .flatMap(x => Either.right(x * 2));
console.log(rightValue); // Either { value: 12, isRight: true }

const leftValue = Either.left('error')
  .map(x => x + 1)
  .flatMap(x => Either.right(x * 2));
console.log(leftValue); // Either { value: 'error', isRight: false }

3. Versprechensmonade

Die Promise Monad wird zur Abwicklung asynchroner Berechnungen verwendet.

Verwendung
const fetchData = url => {
  return new Promise((resolve, reject) => {
    setTimeout(() => {
      resolve(`Data from ${url}`);
    }, 1000);
  });
};

// Usage
fetchData('https://api.example.com')
  .then(data => {
    console.log(data); // 'Data from https://api.example.com'
    return fetchData('https://api.example.com/2');
  })
  .then(data => {
    console.log(data); // 'Data from https://api.example.com/2'
  })
  .catch(error => {
    console.error(error);
  });

4. Monade auflisten

Die Listenmonade wird verwendet, um Berechnungen durchzuführen, die eine Liste von Werten erzeugen.

Durchführung
class List {
  constructor(values) {
    this.values = values;
  }

  static of(values) {
    return new List(values);
  }

  map(fn) {
    return List.of(this.values.map(fn));
  }

  flatMap(fn) {
    return List.of(this.values.flatMap(value => fn(value).values));
  }
}

// Usage
const list = List.of([1, 2, 3])
  .map(x => x + 1)
  .flatMap(x => List.of([x, x * 2]));
console.log(list); // List { values: [ 2, 4, 3, 6, 4, 8 ] }

5. Lesermonade

Die Reader-Monade wird verwendet, um Berechnungen durchzuführen, die von einer gemeinsamen Umgebung oder Konfiguration abhängen.

Durchführung
class Reader {
  constructor(fn) {
    this.fn = fn;
  }

  static of(value) {
    return new Reader(() => value);
  }

  map(fn) {
    return new Reader(env => fn(this.fn(env)));
  }

  flatMap(fn) {
    return new Reader(env => fn(this.fn(env)).fn(env));
  }

  run(env) {
    return this.fn(env);
  }
}

// Usage
const config = { baseURL: 'https://api.example.com' };

const fetchUser = new Reader(env => `${env.baseURL}/user`);
const fetchPosts = new Reader(env => `${env.baseURL}/posts`);

const fetchUserAndPosts = fetchUser.flatMap(userURL =>
  fetchPosts.map(postsURL => ({ userURL, postsURL }))
);

console.log(fetchUserAndPosts.run(config)); 
// { userURL: 'https://api.example.com/user', postsURL: 'https://api.example.com/posts' }

6. Schriftsteller Monade

Die Writer-Monade wird verwendet, um Berechnungen durchzuführen, die einen Wert zusammen mit einem Protokoll oder zusätzlichen Daten erzeugen.

Durchführung
class Writer {
  constructor(value, log) {
    this.value = value;
    this.log = log;
  }

  static of(value) {
    return new Writer(value, '');
  }

  map(fn) {
    const result = fn(this.value);
    return new Writer(result.value, this.log + result.log);
  }

  flatMap(fn) {
    const result = fn(this.value);
    return new Writer(result.value, this.log + result.log);
  }

  tell(log) {
    return new Writer(this.value, this.log + log);
  }
}

// Usage
const writer = Writer.of(3)
  .map(value => new Writer(value + 1, 'Incremented\n'))
  .flatMap(value => new Writer(value * 2, 'Doubled\n'));

console.log(writer); 
// Writer { value: 8, log: 'Incremented\nDoubled\n' }

7. Staatsmonade

Die Zustandsmonade wird verwendet, um Berechnungen durchzuführen, die den Zustand aufrechterhalten.

Durchführung
class State {
  constructor(runState) {
    this.runState = runState;
  }

  static of(value) {
    return new State(state => [value, state]);
  }

  map(fn) {
    return new State(state => {
      const [value, newState] = this.runState(state);
      return [fn(value), newState];
    });
  }

  flatMap(fn) {
    return new State(state => {
      const [value, newState] = this.runState(state);
      return fn(value).runState(newState);
    });
  }

  run(initialState) {
    return this.runState(initialState);
  }
}

// Usage
const increment = new State(state => [state + 1, state + 1]);

const result = increment
  .flatMap(() => increment)
  .flatMap(() => increment)
  .run(0);

console.log(result); // [3, 3]

Abschluss

Monaden bieten eine strukturierte und vorhersehbare Möglichkeit, Berechnungen und Datentransformationen in der funktionalen Programmierung durchzuführen. Jeder Monadentyp dient einem bestimmten Zweck, von der Verarbeitung optionaler Werte mit der Maybe-Monade bis zur Verwaltung asynchroner Vorgänge mit der Promise-Monade.

Das obige ist der detaillierte Inhalt vonEinführung in die funktionale Programmierung in JavaScript: Verschiedene Monaden #11. Für weitere Informationen folgen Sie bitte anderen verwandten Artikeln auf der PHP chinesischen Website!

Stellungnahme:
Der Inhalt dieses Artikels wird freiwillig von Internetnutzern beigesteuert und das Urheberrecht liegt beim ursprünglichen Autor. Diese Website übernimmt keine entsprechende rechtliche Verantwortung. Wenn Sie Inhalte finden, bei denen der Verdacht eines Plagiats oder einer Rechtsverletzung besteht, wenden Sie sich bitte an admin@php.cn