Maison > Article > interface Web > Introduction à la programmation fonctionnelle en JavaScript : Différentes monades #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.
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 :
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.
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' }
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).
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 }
La Promise Monad est utilisée pour gérer les calculs asynchrones.
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); });
La List Monad est utilisée pour gérer les calculs qui produisent une liste de valeurs.
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 ] }
Le Reader Monad est utilisé pour gérer les calculs qui dépendent d'un environnement ou d'une configuration partagés.
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' }
Le Writer Monad est utilisé pour gérer des calculs qui produisent une valeur avec un journal ou des données supplémentaires.
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' }
La Monade d'État est utilisée pour gérer les calculs qui maintiennent l'état.
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]
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!