«Если рабочий хочет хорошо выполнять свою работу, он должен сначала заточить свои инструменты» — Конфуций, «Аналитики Конфуция. Лу Лингун»
титульная страница > программирование > Введение в функциональное программирование на JavaScript: разные монады #11

Введение в функциональное программирование на JavaScript: разные монады #11

Опубликовано 29 июля 2024 г.
Просматривать:951

Introduction to Functional Programming in JavaScript: Different monads #11

Монады — это фундаментальная концепция функционального программирования, которая обеспечивает способ структурированного выполнения вычислений и преобразований данных. Существуют различные типы монад, каждый из которых предназначен для решения конкретных задач и обработки различных типов данных и эффектов.

Что такое Монада?

Монада — это абстракция, позволяющая объединять операции над обернутыми значениями. Он определяется тремя основными свойствами:

  1. Единица измерения (также называемая или return): функция, которая принимает значение и оборачивает его в монаду.
  2. Привязка (также называемая плоской картой или цепочкой): функция, которая принимает монадическое значение, и функция, возвращающая монаду, применяет функцию к обернутому значению и возвращает новую монаду.
  3. Ассоциативность: состав монадических операций должен быть ассоциативным.

Распространенные типы монад

  1. Может быть, Монада
  2. Любая монада
  3. Монада обещаний
  4. Список монад
  5. Монада чтения
  6. Монада писателя
  7. Монада состояния

1. Возможно, Монада

Монада Maybe используется для обработки необязательных значений. Он представляет собой вычисление, которое может завершиться неудачно или вернуть значение null или неопределенное значение.

Выполнение
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. Либо монада

Ибо монада используется для обработки вычислений, которые могут возвращать либо значение успеха (справа), либо значение ошибки (слева).

Выполнение
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. Монада обещаний

Монада обещаний используется для обработки асинхронных вычислений.

Применение
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. Список монад

Монада списка используется для обработки вычислений, в результате которых создается список значений.

Выполнение
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. Читающая монада

Монада Reader используется для обработки вычислений, которые зависят от некоторой общей среды или конфигурации.

Выполнение
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. Писательская монада

Монада Writer используется для обработки вычислений, которые создают значение вместе с журналом или дополнительными данными.

Выполнение
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. Государственная монада

Монада состояний используется для обработки вычислений, поддерживающих состояние.

Выполнение
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]

Заключение

Монады предоставляют структурированный и предсказуемый способ выполнения вычислений и преобразований данных в функциональном программировании. Каждый тип монады служит определенной цели: от обработки необязательных значений с помощью монады Maybe до управления асинхронными операциями с помощью монады обещаний.

Заявление о выпуске Эта статья воспроизведена по адресу: https://dev.to/francescoagati/introduction-to-functional-programming-in-javascript-dependent-monads-11-2je1?1. Если есть какие-либо нарушения, пожалуйста, свяжитесь с [email protected] удалить его
Последний учебник Более>

Изучайте китайский

Отказ от ответственности: Все предоставленные ресурсы частично взяты из Интернета. В случае нарушения ваших авторских прав или других прав и интересов, пожалуйста, объясните подробные причины и предоставьте доказательства авторских прав или прав и интересов, а затем отправьте их по электронной почте: [email protected]. Мы сделаем это за вас как можно скорее.

Copyright© 2022 湘ICP备2022001581号-3