„Wenn ein Arbeiter seine Arbeit gut machen will, muss er zuerst seine Werkzeuge schärfen.“ – Konfuzius, „Die Gespräche des Konfuzius. Lu Linggong“
Titelseite > Programmierung > Einführung in die funktionale Programmierung in JavaScript: Verschiedene Monaden #11

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

Veröffentlicht am 29.07.2024
Durchsuche:127

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, von denen jede darauf ausgelegt ist, 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 für umschlossene Werte 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 einschließt.
  2. Bind (auch FlatMap oder Chain genannt): Eine Funktion, die einen monadischen Wert und eine Funktion, die eine Monade zurückgibt, annimmt, 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 Monade
  2. Entweder Monade
  3. Promise Monad
  4. Monade auflisten
  5. Lesermonade
  6. Autor Monad
  7. Staatsmonade

1. Vielleicht Monade

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

Implementierung
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.

Implementierung
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.

Implementierung
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.

Implementierung
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.

Implementierung
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.

Implementierung
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.

Freigabeerklärung Dieser Artikel ist abgedruckt unter: https://dev.to/francescoagati/introduction-to-Functional-programming-in-javascript-different-monads-11-2je1?1 Bei Verstößen wenden Sie sich bitte an [email protected] um es zu löschen
Neuestes Tutorial Mehr>

Haftungsausschluss: Alle bereitgestellten Ressourcen stammen teilweise aus dem Internet. Wenn eine Verletzung Ihres Urheberrechts oder anderer Rechte und Interessen vorliegt, erläutern Sie bitte die detaillierten Gründe und legen Sie einen Nachweis des Urheberrechts oder Ihrer Rechte und Interessen vor und senden Sie ihn dann an die E-Mail-Adresse: [email protected] Wir werden die Angelegenheit so schnell wie möglich für Sie erledigen.

Copyright© 2022 湘ICP备2022001581号-3