"일꾼이 일을 잘하려면 먼저 도구를 갈고 닦아야 한다." - 공자, 『논어』.
첫 장 > 프로그램 작성 > JavaScript의 함수형 프로그래밍 소개: 다양한 모나드 #11

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

2024-07-29에 게시됨
검색:925

Introduction to Functional Programming in JavaScript: Different monads #11

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

모나드란 무엇입니까?

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

  1. 유닛(of 또는 return이라고도 함): 값을 가져와 모나드로 래핑하는 함수.
  2. Bind(플랫맵 또는 체인이라고도 함): 모나드 값을 취하는 함수와 모나드를 반환하는 함수, 해당 함수를 래핑된 값에 적용하고 새 모나드를 반환합니다.
  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를 사용하여 비동기 작업을 관리하는 것까지 특정 목적을 수행합니다.

릴리스 선언문 이 기사는 https://dev.to/francescoagati/introduction-to-function-programming-in-javascript- Different-monads-11-2je1?1에서 복제됩니다. 침해가 있는 경우에는 [email protected]으로 문의하시기 바랍니다. 그것을 삭제하려면
최신 튜토리얼 더>

부인 성명: 제공된 모든 리소스는 부분적으로 인터넷에서 가져온 것입니다. 귀하의 저작권이나 기타 권리 및 이익이 침해된 경우 자세한 이유를 설명하고 저작권 또는 권리 및 이익에 대한 증거를 제공한 후 이메일([email protected])로 보내주십시오. 최대한 빨리 처리해 드리겠습니다.

Copyright© 2022 湘ICP备2022001581号-3