[fp] 모노이드

dante Yoon·2022년 4월 22일
2

fp

목록 보기
1/2
post-thumbnail

모노이드

모노이드는 다음 두 가지의 특징을 만족하는 집합을 의미한다.

항등원을 가지고 있어야 한다.

항등원이란 어떤 함수 f에 대해 f(x,y) === y 일 때, x는 연산 f에 대해 항등원이라고 하며, 수식이 아닌 말로 풀어쓰자면, 어떤 연산자에 대해 적용된 두 개의 피연산자 중 다른 한개의 피연산자를 그대로 반환시켜주는 피연산자를 의미한다.

항등원은 영어로 identity element라고 한다.

연관 바이너리 함수를 가지고 있어야 한다.

연관 바이너리 함수는 다음과 같이 두 피연산자에 대한 연산의 순서가 변경되어도 동일한 값을 반환하는 연산을 의미한다.

연관 바이너리 함수는 영어로 associative binary operation라고 한다.

여기서 바이너리 함수는 bitwise 연산이 아니라, 두 인자를 가지고 다른 인자를 반환하는 연산을 의미한다

집합 S와 binary operaton X 가 있다고 할 때, S X S -> S 일 때
S와 X는 모노이드라고 이야기 하며,

보다 간단하게 모노이드를 정의하면 다음과 같다.

  1. ⊗ binary 연산에 대해 결합 법칙을 만족하며 (결합 법칙이다. 교환법칙이 아니다.)
  2. ⊗ binary 연산에 대해 항등원 I가 존재 할 때
    항등원 I와 연산 ⊗를 가지고 있는 집합 S는 모노이드이다.

더하기 연산

더하기 연산 '+'는 associative binary operator이다.
더하기에 연산 '+'에 대해 항등원 0이 존재한다.
숫자 집합은 (+,0) 라는 모노이드를 가진다.

typeof string, concat

String.prototype.concat 은 associatve binary operation 이다.
String.prototype.concat은 항등원 ""를 가진다.
String Concatenation은 모노이드를 가지고 있다.

Monoid 객체

object literal를 이용해 Monoid 객체를 만들어볼 것이다.

Monoid 객체는 다음 두 메소드를 가진다.

var Sum =  { empty: () => 0, concat: (x, y) => x + y } 
  • Sum.empty는 항등원을 반환해준다.
  • Sum.concat은 연관 이진 함수를 반환해준다.
Sum.concat(Sum.empty(), 1);

모노이드 활용

단테의 코틀린 컬렉션 글을 보면 fold 함수를 사용해서 리스트를 줄이는 것을 볼 수 있는데, 모노이드는 이렇게 어떤 컬렉션을 폴딩하는데 사용한다.

자바스크립트의 Array.prototype.reduce와 함께 사용해보자

reduce

우선 앞서 만들었던 Sum Monoid 객체를 클래스로 만들어보자.

class Sum {
  empty() {
    return 0
  }
  
  concat(x,y) {
    return x + y
  }
}

Sum 객체를 이용해 다른 인스턴스를 만들 수 있을까?
object literal로 만들어 사용할 수 있는 걸 봐서는 굳이 Sum 클래스를 가지고 다른 인스턴스를 만들 필요가 없을 것 같다.

여기서 말하는 인스턴스는 상속을 의미하지 const sum = new Sum()과 같은 것을 말하는 것이 아니다.


// Sum.js
const Sum = (() => new class Sum {
  empty() {
    return 0
  }
  
  concat(x,y) {
    return (x,y) => x + y
  }
}())

export default Sum;


const reduced = [1,2,3,4,5,6].reduce(Sum.concat, Sum.empty());
profile
성장을 향한 작은 몸부림의 흔적들

0개의 댓글