iT邦幫忙

2023 iThome 鐵人賽

DAY 12
0
Software Development

Should I use fp-ts系列 第 12

[Should I use fp-ts?] Day 12 - fp-ts: Option alt

  • 分享至 

  • xImage
  •  

在本系列文中,所有的程式碼以及測試都可以在 should-i-use-fp-ts 找到,今日的範例放在 src/day-12 並且有習題和測試可以讓大家練習。

O.alt

現在還有一個常用情境用前幾天教的函數無法實現的很優雅,直接看範例。

export type Mice = {
  name: string;
  rank: number;
  award?: string;
};
/** a lot of if else */
export const normalAlt = (mice: Mice) => {
  if (mice.award) return `Awarded with ${mice.award}!`;
  else if (mice.rank <= 5) return `No. ${mice.rank} mice on the board!`;
  else if (mice.rank <= 10) return `In top 10 mouses at ${mice.rank}!`;
  else return 'Is on sale!';
};

前幾天學習到的 getOrElse 以及 match 拿來實現 if...else 的場景會稍嫌繁瑣,所以我們需要建立一個 alt 函式,來表示前一個 Option 失敗(None)後的路徑。

type Alt = <A>(that: () => O.Option<A>) => (me: O.Option<A>) => O.Option<A>;
export const alt: Alt = that => me => O.isNone(me) ? that() : me;

如果 OptionSome 的話,則繼續往下傳,為 None 的話則運算 that 函式,接下來嘗試使用 Alt 改寫上述函式。

export const getMiceAward = (mice: Mice) => pipe(
  mice.award,
  O.fromNullable,
  O.map(award => `Awarded with ${award}!`),
);

export const getMiceTop5 = (mice: Mice) => pipe(
  mice,
  O.fromPredicate(({ rank }) => rank <= 5),
  O.map(({ rank }) => `No. ${rank} mice on the board!`),
);

export const getMiceTop10 = (mice: Mice) => pipe(
  mice,
  O.fromPredicate(({ rank }) => rank <= 10),
  O.map(({ rank }) => `In top 10 at ${rank}!`),
);

// use { name: 'mice', rank: 10 } as an example
export const fpAlt = (mice: Mice) => pipe(
  mice, // { name: 'mice', rank: 10 }
  getMiceAward, // { _tag: 'None' }
  O.alt(() => getMiceTop5(mice)), // { _tag: 'None' }
  O.alt(() => getMiceTop10(mice)), // { _tag: 'Some', value: 'In top 10 at 10!' }
  O.getOrElse(() => 'Is on sale!'), // 'In top 10 mouses at 10!'
);

大家可能也有發現 fromNullable, fromPredicate 等等的功能,之後我們再進行介紹。

今天的主題在 should-i-use-fp-ts src/day-12 有習題和測試可以練習,大家可以嘗試自己能不能寫出自己的 alt , altW

Reference

Option.ts | fp-ts


上一篇
[Should I use fp-ts?] Day 11 - fp-ts: Option match, matchW
下一篇
[Should I use fp-ts?] Day 13 - fp-ts: Option fromNullable, fromPredicate
系列文
Should I use fp-ts25
圖片
  直播研討會
圖片
{{ item.channelVendor }} {{ item.webinarstarted }} |
{{ formatDate(item.duration) }}
直播中

尚未有邦友留言

立即登入留言