> 추상대수학에서, 모노이드는 항등원을 갖는, 결합 법칙을 따르는 이항 연산을 갖춘 대수 구조이다. 군의 정의에서 역원의 존재를 생략하거나, 반군의 정의에서 항등원의 존재를 추가하여 얻는다. - 위키피디아 ## Set - 집합 #### Magma - Set에 이항 연산자가 추가된 타입 ```ts interface Magma<T> { readonly op: (first: T, second: T) => T } ``` ## Semigroup - 반군 - Magma가 결합 법칙을 만족하면 Semigroup이 된다. ```ts // 결합 법칙을 타입으로 표현할 수 있는 방법이 있을까...? interface Semigroup<T> extends Magma<T> {} // 뺄셈은 결합 법칙을 만족하지 않으므로 아래는 Semigroup이 아니다. const notSemigroup: Magma<number> = { op: (first, second) => first - second; }; // 덧셈은 결합 법칙을 만족하므로 아래는 Semigroup이다. const semigroup: Magma<number> = { op: (first, second) => first + second; }; ``` ### folding - 여러 개의 Monoid를 연결하는 방법 - Semigroup이 아닐 경우, 즉 결합 법칙을 만족하지 않는 경우에는 folding의 결과가 달라질 수 있기 때문에 folding이 불가능하다. - folding을 할 수 있으면 여러 연산을 병렬적으로 처리할 수 있다. ```ts notSemigroup.op(notSemigroup.op(1, 2), 3) // => -4 notSemigroup.op(1, notSemigroup.op(2, 3)) // => 0 semigroup.op(semigroup.op(1, 2), 3) // => 6, foldLeft semigroup.op(1, semigroup.op(2, 3)) // => 6, foldRight // 병렬은 이렇게... const firstResult = semigroup.op(1, 2); const secondResult = semigroup.op(3, 4); const finalResult = semigroup.op(firstResult, secondResult); ``` ## Monoid - 모노이드 - Semigroup이 항등원을 가지면 Monoid가 된다. ```ts interface Monoid<T> extends Semigroup<T> { zero: T; } const sumNumberMonoid: Monoid<number> = { op: (first, second) => first + second; zero: 0; }; const multipleNumberMonoid: Monoid<number> = { op: (first, second) => first * second; zero: 1; }; const addStringMonoid: Monoid<string> = { op: (first, second) => first + second; zero: ''; }; ``` #monoid #functional_programming