DAY 28
2
Software Development

### Functional Programming in JS系列 第 28 篇

(↑ 沒有誇張，這圖我畫了兩個小時以上，用 Canva 畫曲線實在是太難了啊... )

# Let's talk about the problem

``````const findColor = name => ({
red: '#ff4444',
blue: '#3b5998'
}[name])

const res = findColor('red').toUpperCase(); // '#FF4444',
``````

``````findColor('RED').toUpperCase();
// TypeError: Cannot read property 'toUpperCase' of undefined
``````

``````findColor('RED'.toLowerCase()).toUpperCase();
// '#FF\$\$\$\$'
``````

``````findColor('redd'.toLowerCase()).toUpperCase();
// TypeError: Cannot read property 'toUpperCase' of undefined
``````

• 一條是 Happy Path (Right)，就是運算過程一切順利;
``````// ====================
// Definitions
// ====================
// This is Happy Path
const Right = x =>
({
chain: f => f(x),
map: f => Right(f(x)),
fold: (f, g) => g(x), // run the second g
toString: `Right(\${x})` // 方便檢視
})

const Left = x =>
({
chain: f => Left(x),
map: f => Left(x),
fold: (f, g) => f(x), // run the first f
toString: `Left(\${x})`
})
``````

``````const findColor = name => {

const found = {
red: '#ff4444',
blue: '#3b5998'
}[name];

}

const res = findColor('red') // return 一個 Right() data type
const res = findColor('reddd') // return 一個 Left()
``````
``````const res = findColor('red').map(x => x.toUpperCase()) // Right('#FF\$\$\$\$')
``````

## Fold

``````// Success Happy Path
const res = () =>
findColor('red')
.map(x => x.toUpperCase())
.fold(
() => 'no Color',
color => color
) // '#FF4444'

const res = () =>
findColor('redddd')
.map(x => x.toUpperCase())   // 不會執行這行，會直接輸出 'no Color'
.fold(
() => 'no Color',
color => color
) // 'no Color'
``````

## fromNullable

``````const fromNullable = x =>
x != null ? Right(x) : Left(null)

const findColor = name =>
fromNullable({
red: '#ff4444',
blue: '#3b5998'
}[name]);

// Success Happy Path
const res = () =>
findColor('red')
.map(x => x.toUpperCase())
.fold(
() => 'no Color',
color => color
) // '#FF4444'
``````

## 如何 debug

``````const log = msg => x => {
console.log(msg, '--->', x, '<---');

return x;
};

findColor('red')
.map(log('Before upper Case'))
// "Before upper Case" "--->" "#ff4444" "<---"
.map(x => x.toUpperCase())
.map(log('After upper Case'))
// "After upper Case" "--->" "#FF4444" "<---"
.fold(
() => 'no Color',
color => color
) // '#FF4444'
``````

# 練習

``````const street_ = user => {

} else {
return 'no street'
}
}
``````

``````const Right = x =>
({
chain: f => f(x),
map: f => Right(f(x)),
fold: (f, g) => g(x),
toString: () => `Right(\${x})`
})

const Left = x =>
({
chain: f => Left(x),
map: f => Left(x),
fold: (f, g) => f(x),
toString: () => `Left(\${x})`
})

const fromNullable = x =>
x != null ? Right(x) : Left(null)

const street = user =>
.fold( () => 'no street', x => x )
``````

#### 參考文章

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

``````

### 1 則留言

0
Ken
iT邦新手 5 級 ‧ 2020-10-20 10:58:20