Maison > interface Web > js tutoriel > Introduction à la programmation fonctionnelle en JavaScript : Différentes monades #11

Introduction à la programmation fonctionnelle en JavaScript : Différentes monades #11

王林
Libérer: 2024-07-18 20:34:41
original
971 Les gens l'ont consulté

Introduction to Functional Programming in JavaScript: Different monads #11

Les monades sont un concept fondamental de la programmation fonctionnelle qui permet de gérer les calculs et les transformations de données de manière structurée. Il existe différents types de monades, chacune conçue pour résoudre des problèmes spécifiques et gérer différents types de données et d'effets.

Qu'est-ce qu'une Monade ?

Une monade est une abstraction qui permet d'enchaîner des opérations sur des valeurs enveloppées. Il est défini par trois propriétés principales :

  1. Unité (également appelée of ou return) : Une fonction qui prend une valeur et l'enveloppe dans une monade.
  2. Bind (également appelé flatMap ou chain) : une fonction qui prend une valeur monadique et une fonction qui renvoie une monade, applique la fonction à la valeur encapsulée et renvoie une nouvelle monade.
  3. Associativité : La composition des opérations monadiques doit être associative.

Types courants de monades

  1. Peut-être Monade
  2. Soit Monade
  3. Promesse Monade
  4. Liste des monades
  5. Monade de lecture
  6. Monade d'écrivain
  7. Monade d'État

1. Peut-être Monade

La Maybe Monad est utilisée pour gérer les valeurs facultatives. Il représente un calcul qui pourrait échouer ou renvoyer null ou indéfini.

Mise en œuvre
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' }
Copier après la connexion

2. Soit Monade

La Monade Soit est utilisée pour gérer des calculs qui peuvent renvoyer soit une valeur de réussite (à droite), soit une valeur d'erreur (à gauche).

Mise en œuvre
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 }
Copier après la connexion

3. Promesse Monade

La Promise Monad est utilisée pour gérer les calculs asynchrones.

Usage
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);
  });
Copier après la connexion

4. Liste des monades

La List Monad est utilisée pour gérer les calculs qui produisent une liste de valeurs.

Mise en œuvre
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 ] }
Copier après la connexion

5. Lecteur Monade

Le Reader Monad est utilisé pour gérer les calculs qui dépendent d'un environnement ou d'une configuration partagés.

Mise en œuvre
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' }
Copier après la connexion

6. Monade de l'écrivain

Le Writer Monad est utilisé pour gérer des calculs qui produisent une valeur avec un journal ou des données supplémentaires.

Mise en œuvre
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' }
Copier après la connexion

7. Monade d'État

La Monade d'État est utilisée pour gérer les calculs qui maintiennent l'état.

Mise en œuvre
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]
Copier après la connexion

Conclusion

Les monades offrent un moyen structuré et prévisible de gérer les calculs et les transformations de données en programmation fonctionnelle. Chaque type de monade répond à un objectif spécifique, de la gestion des valeurs facultatives avec Maybe Monad à la gestion des opérations asynchrones avec Promise Monad.

Ce qui précède est le contenu détaillé de. pour plus d'informations, suivez d'autres articles connexes sur le site Web de PHP en chinois!

source:dev.to
Déclaration de ce site Web
Le contenu de cet article est volontairement contribué par les internautes et les droits d'auteur appartiennent à l'auteur original. Ce site n'assume aucune responsabilité légale correspondante. Si vous trouvez un contenu suspecté de plagiat ou de contrefaçon, veuillez contacter admin@php.cn
Tutoriels populaires
Plus>
Derniers téléchargements
Plus>
effets Web
Code source du site Web
Matériel du site Web
Modèle frontal