>웹 프론트엔드 >JS 튜토리얼 >JavaScript의 함수형 프로그래밍 소개: 다양한 모나드 #11

JavaScript의 함수형 프로그래밍 소개: 다양한 모나드 #11

王林
王林원래의
2024-07-18 20:34:41976검색

Introduction to Functional Programming in JavaScript: Different monads #11

모나드는 계산과 데이터 변환을 구조화된 방식으로 처리하는 방법을 제공하는 함수형 프로그래밍의 기본 개념입니다. 다양한 유형의 모나드가 있으며, 각각은 특정 문제를 해결하고 다양한 종류의 데이터와 효과를 처리하도록 설계되었습니다.

모나드란 무엇입니까?

모나드는 래핑된 값에 대한 작업 연결을 허용하는 추상화입니다. 이는 세 가지 기본 속성으로 정의됩니다.

  1. 유닛(of 또는 return이라고도 함): 값을 가져와 모나드로 래핑하는 함수
  2. 바인드(플랫맵 또는 체인이라고도 함): 모나드 값을 가져오는 함수와 모나드를 반환하는 함수, 해당 함수를 래핑된 값에 적용하고 새 모나드를 반환합니다.
  3. 연관성: 모나드 연산의 구성은 연관적이어야 합니다.

모나드의 일반적인 유형

  1. 아마도 모나드
  2. 모나드
  3. 약속 모나드
  4. 리스트 모나드
  5. 리더 모나드
  6. 작가 모나드
  7. 스테이트 모나드

1. 아마도 모나드

Maybe Monad는 선택적 값을 처리하는 데 사용됩니다. 이는 실패하거나 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. 모나드 중 하나

Elete 모나드는 성공 값(오른쪽) 또는 오류 값(왼쪽)을 반환할 수 있는 계산을 처리하는 데 사용됩니다.

구현
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. 약속 모나드

Promise Monad는 비동기 계산을 처리하는 데 사용됩니다.

용법
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 Monad는 공유 환경이나 구성에 따라 계산을 처리하는 데 사용됩니다.

구현
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 Monad는 로그 또는 추가 데이터와 함께 값을 생성하는 계산을 처리하는 데 사용됩니다.

구현
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 Monad를 사용하여 선택적 값을 처리하는 것부터 Promise Monad를 사용하여 비동기 작업을 관리하는 것까지 특정 목적을 수행합니다.

위 내용은 JavaScript의 함수형 프로그래밍 소개: 다양한 모나드 #11의 상세 내용입니다. 자세한 내용은 PHP 중국어 웹사이트의 기타 관련 기사를 참조하세요!

성명:
본 글의 내용은 네티즌들의 자발적인 기여로 작성되었으며, 저작권은 원저작자에게 있습니다. 본 사이트는 이에 상응하는 법적 책임을 지지 않습니다. 표절이나 침해가 의심되는 콘텐츠를 발견한 경우 admin@php.cn으로 문의하세요.