DAY 16
0
Software Development

## Day 16 - Apply

f g composition
pure pure compose(f, g)
effects pure(unary) f.map(g)
effects pure(n-ary) ?

``````const add = (x, y) => x + y;

add(Identity.of(1), Identity.of(2)) // [object Object][object Object]
``````

``````const result = Identity.of(1).map(x => Identity.of(2).map(y => add(x, y))) // Identity(Identity(3))
``````

``````result.val.val
``````

## Apply

Type Signature

``````ap :: Apply f => f a ~> f (a -> b) -> f b
``````

Law

• Composition: `v.ap(u.ap(a.map(f => g => x => f(g(x))))) === v.ap(u).ap(a)`

Implementation

1. 將 `add` 函式進行 currying

``````const add = R.curry((x, y) => x + y);
``````

2. 實作 `ap`

``````const Identity = (val) => ({
val,
map: (f) => {
const result = f(val);
return Identity(result);
},
ap: function (o) {
// 根據 Fantasy-land 對 Apply 定義，其為 `a.ap(b)` 其 `b` 一定會是函式，而在此範例則是 o.val 必為函式
return this.map(o.val);
},
inspect: () => `Identity(\${val})`,
});
``````

3. 建立一個 helper function `lift2`

``````const lift2 = g => f1 => f2 => f2.ap(f1.map(g));
``````

``````const lift3 = g => f1 => f2 => f3 => f3.ap(f2.ap(f1.map(g)));
``````

4. 接下來就可以輕鬆的解決一開始的問題

``````lift2(add)(Identity(1))(Identity(2)) // Identity(3)
``````

## 小結

f g composition
pure pure compose(f, g)
effects pure(unary) f.map(g)
effects pure(n-ary) f1.map(g).ap(f2)