[백업][가리사니] monad (모나드) javascript 로 설명
javascript

이 문서는 가리사니 개발자 포럼에 올렸던 글의 백업 파일입니다. 오래된 문서가 많아 현재 상황과 맞지 않을 수 있습니다.

참고 https://curiosity-driven.org/monads-in-javascript https://en.wikipedia.org/wiki/Monad_(functional_programming)

모나드는 수학적으로 어려운 개념이다보니.. 실무자들도 실습 위주로 알아서 쓰는 경우가 많다고합니다. (영어와 수학만 있다보니 필자가 이해못해서 그런게… 아닐꺼에요.. 그..그렇죠?;;) 그러던 중 자바스크립트로 정리된 몇 가지 예제를 발견하고 강의해설을 써보게 되었습니다. 원본 : https://curiosity-driven.org/monads-in-javascript

여기서는 [ Identity, Maybe, List, Continuation ] 모나드 만 다루도록 하겠습니다.

  • 더 많은 종류는 본문 아래 참고를 확인해주시기 바랍니다.

Identity 모나드

정의 : Identity 객체 (bind 함수를 포함)

function Identity(value)
{
	this.value = value;
}
Identity.prototype.bind = function(transform)
{
	return transform(this.value);
};

사용 예제

new Identity(1).bind
(
	value => new Identity(2).bind
	(
		value2 => new Identity(value - value2)
	)
);

결과 : Identity {value: -1} 해설

  1. Identity 생성
    • new Identity(1)
  2. 생성된 객체의 bind 함수 실행 -> 람다 파라미터 value -> new Identity(1)의 값 1
    • new Identity(1).bind( value => … );
  3. 내부에서 다시 new Identity(2) 실행 다시 바인드
    • new Identity(1).bind( value => { new Identity(2).bind( value2 => … ) } );
    • 여기서 value 는 new Identity(1) value2 는 new Identity(2) 이다.
  4. new Identity(2).bind 실행
    • value (1) - value2 (2) == -1 의 값을 같는 Identity 을 생성
      new Identity(1).bind
      (
       value => new Identity(2).bind
       (
         // value2 => new Identity(value - value2) : 계산결과 value - value2 == -1;
         value2 => new Identity(-1)
       )
      );
      
  5. bind 는 실행 반환만 한다. 즉 상위 객체로 반환값을 연쇄적으로 전달.
    • new Identity(-1) 즉 Identity {value: -1} 값이 올라간다.
  6. 최종 반환
    • 결과 Identity {value: -1}

Maybe 모나드

function Just(value)
{
	this.value = value;
}
Just.prototype.bind = function(transform)
{
	return transform(this.value);
};
Just.prototype.toString = function()
{
	return 'Just(' + this.value + ')';
};
// 빈 값을 표현하기 위한.
var Nothing =
{
	bind: function()
	{
		return this;
	},
	toString: function()
	{
		return 'Nothing';
	}
};

사용 예제 1

new Just(5).bind
(
	value => new Just(6).bind
	(
		value2 => new Just(value + value2)
	)
);

결과 1 : Identity {value: 11} 해설

  • 위 Identity 와 완전히 동일하다. 그럼 왜 Identity 가 아닌 Maybe 일까? 사용 예제 2
    var out = new Just(5).bind
    (
      value => Nothing.bind
      (
          value2 => new Just(value + alert(value2))
      )
    );
    out.toString();
    

    결과 2 : “Nothing” 해설

  • 얼핏보기엔 Identity 와 똑같아보이지만 Nothing 을 통한 전파를 중지 시키는 예제이다.
  • Identity 를 봤다면 같은 구조이기 때문에 순차적으로 처리된다는 것을 알 수 있다.
    1. Just에 5값을 넣어서 생성 바인드
  • new Just(5).bind( value => … )
    1. 전역객체 Nothing 의 bind 함수 실행 (소스를 보면 프로토타입-new 객체가 아닌 상시 객체이다.)
  • new Just(5).bind( value => Nothing.bind( value2 => …) )
    1. Nothing.bind 에는 콜이 없다. 다만 this 를 리턴할 뿐이다.
  • 때문에 인자로 넣은 value2 => { new Just(value + alert(value2)) } 는 에초에 실행되지 않는다.
  • 바로 Maybe 모나드가 Identity 와 다른점이다.
  • 즉 문법이 틀리지 않은이상 Nothing.bind 안에 오류가 날만한 함수가 들어있어도.. 람다함수를 인자로 넣었을뿐.
  • Nothing.bind 는 람다함수를 실행시키지 않는다.
  • 즉 this를 리턴할 뿐이다.
    1. Identity 와 마찬가지로 상단으로 반환값 Nothing을 전달한다.
    2. out 에 입력 후 toString() 을 통해 출력한다.
  • 결과 : “Nothing” 결론 자바스크립트에서 자주있는 단계적 null을 처리할 때 유용한 방법이다. 예를들어 user.dynamicData.nameData.nickname 이 있을때..
    if ( user != null )
    {
      if ( user.dynamicData != null )
      {
          if ( user.dynamicData.nameData != null )
          {
              // ....
          }
      }
    }
    

    위와 같이 예외처리 하는 것이 아닌 도중에 값이 없을때 전파를 중지시켜 값을 얻어 낼 수 있다.

List 모나드

function* (제네레이터 함수) 에대한 설명은 아래 강의를 참조하세요.

Continuation 모나드

이것을 이해하기 위해선 먼저 Promise 를 알아야한다.

p.then(function(value) { console.log(value); }); ```

  1. 무조건 성공하는 Promise.resolve(5) 에서
  2. 다시 무조건 성공하는 Promise.resolve(10) 를 작성
  3. Promise 는 바로 상태를 p에 저장하고 실행후 비동기적으로 상태를 바꾼다.
  4. p.then(function(value) 를 통해 실행이 완료되면 값을 가져온다.

모나드의 구성

위 예제를 해봤다면 다 비슷한 구성이라는 것을 알 수 있다. unit / bind 로 구성된다. unit 의 경우는 타입을 래핑하는 역활을 한다. 생성자일 경우는 생성자이며 생성자가 아닐경우는 정적 메서드 팩토리에 속하게 된다.

  • https://en.wikipedia.org/wiki/Type_constructor bind 는 상태값이 없는 순수함수를 바인딩 해주는 역활을한다. 여기서 바인딩이란 파라미터를 받아 반환을 연결 해주는 람다를 바인딩(심어주는것이다.) 하는 것이다.
  • 그리고 필요할때 바인딩이 된 함수가 실행되는 것이다.

참고

참고 : https://en.wikipedia.org/wiki/Monad_(functional_programming) 모나드의 종류 Identity monad State monads Writer monad Continuation monad I/O monad Maybe monad List monad 등… 코모나드의 종류 Identity comonad Product comonad Function comonad Costate comonad 등…