DAY 23
2
Software Development

## Functor 3: 程式碼解說篇

Box 這種 data type 除了可以把 value 當參數， function 當然也可以

### value 當參數

``````const Box = x => ({
map: f => Box(f(x))
});
``````

### Function 當參數

``````const Box = f => ({
map: g => Box( x => g(f(x)) )
});
``````

``````// logSomething :: () -> Number
function logSomething () {
console.log('Hello World');
return 0;
}
``````

``````// Box :: Function -> Box
const Box = f => ({
map: g => Box( x => g(f(x)) ), // 神奇的運算在此
});

const increment = x => x + 1;
const one = Box(logSomething).map(increment); // return Box data Type
``````

``````// Box :: Function -> Box
const Box = f => ({
map: g => Box( x => g(f(x)) ), // 神奇的運算在此
runEffects: x => f(x), // 執行 Effect 看是輸出什麼
});

const increment = x => x + 1;
const one = Box(logSomething).map(increment); // return Box data Type
one.runEffects();
/*
Hello World
1
*/
``````

### result1 = `Box(logSomething)`

``````const Box = logSomething => ({
map: g => Box( x => g(logSomething(x)) ),
runEffects: x => logSomething(x),
});
``````

### result2 = result1 `.map(increment)`

``````const Box = ( x => increment(logSomething(x) ) => ({
map: g => Box( x => g( ( x => increment(logSomething(x) )(x)) ),
runEffects: x => increment(logSomething(x)), // 執行 Effect 看是輸出什麼
});
``````

### result3 = result2 `.runEffects()`

``````increment(logSomething(x))
/*
Hello World
1
*/
``````

`logSomething(x)` 會觸發 `console.log('Hello World')` 以及回傳 0; 而 `increment(0)` 會回傳 1，也就是最後答案。

## Can keep calling `map()`

``````const double = x => x * 2;
const cube = x => Math.pow(x, 3);
const eight = Box(logSomething) // 0
.map(increment) // 1
.map(double) // 2
.map(cube); // 4

eight.runEffects(); // 4
``````

``````Box(logSomething).runEffects()  // 0
Box(logSomething).map(increment).runEffects() // 1

Box(logSomething)
.map(increment)
.map(double)
.runEffects() // 2

Box(logSomething)
.map(increment)
.map(double)
.map(cube)
.runEffects() // 4
``````

## Can use `Compose` instead?

``````cube(double(increment(logSomething())))
``````

To be continued...

#### 參考文章

``````如有錯誤或需要改進的地方，拜託跟我說。

``````

### 1 則留言

0
linche0859
iT邦新手 5 級 ‧ 2020-09-23 17:08:17

``````const Box = x => {
map: fn => Box(fn(x)),
fold: fn(x) // 取值 remove from the box
}
const nextCharForNumberString = str =>
Box(str)
.map(x => x.trim())
.map(x => parseInt(x))
.map(x => x + 1)
.map(x => String.fromCharCode(x))
``````

``````const Box = x => ({
map: fn => Box(fn(x)),
fold: fn => fn(x) // 取值 remove from the box
})
const nextCharForNumberString = str =>
Box(str)
.map(x => x.trim())
.map(x => parseInt(x))
.map(x => x + 1)
.map(x => String.fromCharCode(x))
.fold(x => x)
``````

hannahpun iT邦新手 5 級 ‧ 2020-09-24 15:38:13 檢舉

(前幾篇覺得解釋不夠清楚，所以 exercise 會移到後面篇幅)

hannahpun iT邦新手 5 級 ‧ 2020-10-07 17:37:36 檢舉

https://monet.github.io/monet.js/