[함수형 프로그래밍] 모나드 란

참고

모나드 정의

어떤 타입 M에 대해 아래의 두 함수, purecompose가 존재할 때, M은 모나드이다.

type Pure = <A>(a: A) => M<A>;
type Compose = <A, B, C>(f: (a: A) => M<B>, g: (a: B) => M<C>) => (a: A) => M<C>;

type M은 연산 M을 의미하며 type M\<A>는 A 타입의 연산 M을 의미 M\<number>는 number 타입의 값을 만드는 연산 M을 의미

pure 함수는 일반적인 값을 연산 M이 적용된 값인 것 처럼 꾸며 주는 함수

compose 함수는 같은 연산을 하는 두 프로그램을 받아 하나로 합치는 형태 모나드인 연산의 합성 가능성을 보장하는 함수로 합성 가능한 연산들만이 모나드가 될 수 있게 하기 위해 존재하는 제한

모나드 사용 이유

프로그래밍에서 모나드는 합칠 수 있는 연산을 정의하고 추상화 하기 위해 사용한다.

프로그램은 수 많은 서브 프로그램의 집합. 각각의 서브 프로그램들은 하나 하나가 연산이고 이들이 합쳐져 프로그램이 된다. 즉 프로그램은 연산의 집합이다.

정리하면 프로그램은 곧 연산이고, 연산은 곧 프로그램이다. 어떤 연산이 모나드로 정의되면 그 연산에 해당하는 모든 프로그램은 합쳐질 수 있다.

예시

Maybe

가장 간단한 형식의 모나드

type Maybe<A> = A | null;

const pure = <A>(value: A): Maybe<A> => {
  return value;
};

const compose =<A, B, C>
  (
    f: (a: A) => Maybe<B>,
    g: (a: B) => Maybe<C>
  ) =>
  (a: A): Maybe<C> => {
    const ma = f(a);

    if (ma === null) return null;
    else return g(ma);
};


pure<string>("10");
// -> 10


const makeNumber = (str: string): number | null => {
  if (str.length === 0) return null;
  else return Number(str);
};

const makeBoolean = (num: number): boolean | null => {
  if (num === 0) return null;
  else return Boolean(num);
}

compose<string, number, boolean>(makeNumber, makeBoolean)('10');
// -> true

compose<string, number, boolean>(makeNumber, makeBoolean)('');
// -> null

compose<string, number, boolean>(makeNumber, makeBoolean)('0');
// -> null

links

social