TypeScript の fp-ts の Option を使って例外処理をなくしてみた

以下の処理を考えます。
- ユーザーデータから、指定したIDを持つユーザーを取得
- ユーザーから年齢を取得
- 年齢から 100 / (age – 10) の値を取得
- 3が80を超えていたら、OKを返す。それ以外はKOを返す
この処理の中にはいくつか例外処理を入れる必要があります。
- ユーザーが見つからなかった場合
- 年齢が10以下だった場合
これらの例外処理を途中でせずに、最後の4のステップで判定します。
以下コードです。
import * as O from 'fp-ts/Option'
import { findFirst } from "fp-ts/lib/Array"
import { pipe } from 'fp-ts/lib/function'
type User = {
id: number
name: string
age: number
}
const users: User[] = [
{
id: 1,
name: 'hoge',
age: 10,
},
{
id: 2,
name: 'foo',
age: 20,
},
{
id: 3,
name: 'bar',
age: 80,
},
{
id: 4,
name: 'bar',
age: 11,
},
{
id: 5,
name: 'bar',
age: 9,
},
]
const eqId = (id: number) => (user: User) => user.id === id
const getAge = (user: User) => user.age
const calcNumFromAge = (age: number) => 100 / (age - 10)
const isTarget = (num: number) => num > 80
// これは pipe を使わないバージョン
// const main = (userId: number) => {
// const user = findFirst(eqId(userId))(users)
// const age = O.map(getAge)(user)
// const calculatedNum = O.chain((num: number) => {
// return num <= 10 ? O.none : O.some(calcNumFromAge(num))
// })(age)
// const target = O.filter(isTarget)(calculatedNum)
// return O.fold(() => 'ko', () => 'ok')(target)
// }
const main = (userId: number) => {
return pipe(
findFirst(eqId(userId))(users),
O.map(getAge),
O.chain((num: number) => {
return num <= 10 ? O.none : O.some(calcNumFromAge(num))
}),
O.filter(isTarget),
O.fold(() => 'ko', () => 'ok'),
)
}
console.log(main(0)) // userがみつからないのでko
console.log(main(1)) // age <= 10 をみたすのでko
console.log(main(2)) // calculatedNum が 10 なので ko
console.log(main(4)) // ok
console.log(main(5)) // age <= 10 をみたすのでko
console.log(main(100)) // userがみつからないのでko
例外をなくせるし、pipe で見やすくなるが、関数型プログラミングがそこまで一般的ではないので、チーム開発には向いていない印象でした。
最近のコメント