DAY 13
0
Software Development

yo, what's up

## Semigroup II

### 多組 Semigroup 進形合併

``````const Tuple = (x, y) => ({
x,
y,
concat: o => Tuple(x.concat(o.x), y.concat(o.y)),
inspect: () => `Tuple(\${x}, \${y})`
})
``````

``````Tuple(Sum(1), Max(1)).concat(Tuple(Sum(1), Max(100))).inspect() // Tuple(2, 100)
``````

### Example

``````const Jing1 = {
name: 'Jing',
techStacks: ["JavaScript"]
}

const Jing2 = {
name: 'Jing*5',
techStacks: ["Functional Programming", "React"]
}
``````

• 取第一組資料結構的 `name`
• 取最近登入的 `lastLoginTime`
• 合併該使用者的 `techStacks`

Step01

``````const Tuple3 = (x, y, z) => ({
x,
y,
z,
concat: o => Tuple(x.concat(o.x), y.concat(o.y), z.concat(o.z)),
inspect: `Tuple(\${x}, \${y}, \${z})`
})
``````

Step02

``````const mergeStrategy = {
to: user => Tuple3(First(user.name), Max(user.lastLoginTime), user.techStacks),
from: ({x, y, z}) => ({name: x.val,lastLoginTime: y.val, techStacks:z })
}

const merge = strategy => x => y =>
strategy.from(strategy.to(x).concat(strategy.to(y)));

merge(mergeStrategy)(Jing1)(Jing2)

// {
//    "name":"Jing",
//    "techStacks":[
//       "JavaScript",
//       "Functional Programming",
//       "React"
//    ]
// }
``````

isn't neat!! 而這就是 Semigroup 的強項!

## Monoid

### Definition of a Monoid

#### Type Signature

``````empty :: Monoid m => () -> m
``````

`m` 是 Monoid， 則 empty 這個函式的 signature `() -> m` 成立

#### Law

• 一個集合(Set)或稱型別(Type)
• 有 concat method
• 必須符合 associative
• 此一集合(aka, A) 內有一個元素 (a)，可以被稱作 empty，且其符合以下定理
• Right identity: `a.concat(empty) === a`
• Left identity: `empty.concat(a) === a`

Sum & Product

``````Sum.empty = () => Sum(0);

Sum(1).concat(Sum.empty()) === Sum(1) // true
Sum.empty().concat(Sum(1)) === Sum(1) // true

// Product
Product.empty = () => Product(1);
``````

Any & All

``````// Any
Any.empty = () => Any(false)

// All
All.empty = () => All(true)
``````

Intersection

Intersection semigroup 沒有 empty value 所以不是 monoid!

### Rewrite `concatAll`

``````const concatAll = R.curry((m, arr) =>
arr.map(m).reduce((acc, val) => acc.concat(val), m.empty()))
``````

NEXT: Functor