iT邦幫忙

2023 iThome 鐵人賽

DAY 5
1

今天的目標是用 function 讓資料模型「動」起來。想像一個 function 串著一個 function ,把資料揉揉捏捏,經過一道道工序的處理最後變成我們想要的樣子,聽起來就很棒對吧 \(^∀^)メ(^∀^)ノ

https://ithelp.ithome.com.tw/upload/images/20230920/20158615PErfFCUWqx.png

我們同樣用課程名稱的輸入來舉例

  1. 當使用者輸入課程名稱,每打一個字就會觸發一次 ui event
  2. 每次出現 ui event,我們掛在 event hookfunction 就會被呼叫,這時候我們要做的就是把React event (例如輸入改變事件) 轉換成我們剛剛設計的 domain type (課程名稱)
  3. 為了方便跨元件狀態共享,我們使用 Atom 來管理我們的 domain type (Atom 來自 Jotai)
  4. 每次 Atom 所管理的 domain type 被改變都會讓有使用這個 domain typecomponent 被重新渲染,使得更新後的 domain type 能轉換成參數傳遞到所屬的子元件,完成畫面的更新。

實際上不只是課程名稱,整個表單的驗證都只需要遵循步驟一到步驟四就可以完成 !

如果你不熟悉 React 還有 Atom,可能會覺得有點抽象,不過這很正常,沒有關係,多看看多寫寫就會了

Function ! 組合 !

把上面的文字轉換後,我們可以用以下兩個 function 來組成 function A

type getInputString = (event:ChangeEvent) => string // 從輸入事件取出字串
type courseNameOf = (input:string) => CourseName // 把字串傳換成先前定義的資料模型

可是 ... 該怎麼把這兩個 function 組合在一起做呢 ?

https://ithelp.ithome.com.tw/upload/images/20230920/20158615rlqs2HXllp.jpg
來源

照一般原生寫法我們會寫成這樣

const input = getInputString(event)
const name = courseNameOf(input)

看起來沒有甚麼問題,可是如果想要組合的 function 變多會發生甚麼事呢 ?

https://ithelp.ithome.com.tw/upload/images/20230920/20158615e3gGeVcELm.png
來源

const temp1 = add7(3)
const temp2 = exp2(temp1)
const temp3 = sub2(temp2)
const result = mul5(temp3)

無意義的變數命名好累好麻煩(T▽T)

const result = mul5(sub2(exp2(add7(3))))

省略掉變數以後,閱讀順序怪怪的不太自然,還要加上很多括號,好像更糟糕了 (T▽T)

https://ithelp.ithome.com.tw/upload/images/20230920/201586151OCWPbxw33.png
來源

pipe

為了解決以上問題,pipe 就出現啦 ! 有了 pipe 以後,多個 function 的組合看起來會像這樣

import { pipe } from 'effect/Function'

const result = pipe(1, add7, exp2, sub2, mul5) 

課程名稱的範例則會像這樣

const courseName = (event:ChnageEvent)=>pipe(event, getInputString, courseNameOf)

我們之後會常常用到這種語法,克服習慣問題以後,會發現看起來很舒服唷 (^ω^)

flow

在使用 pipe 的時候常常會發現如下圖 calculate function 的輸入參數等於 pipe 的第一個參數的情形

const calculate = (input:number)=>pipe(input, add7, exp2, sub2, mul5)

這時候我們可以用 flow 來取代重複出現的 input,看起來又更簡潔了!

import { flow } from 'effect/Function'

const calculate = flow(add7, exp2, sub2, mul5)

更多 FP buzzwords

講完 pipe 跟 flow 聯想到兩個酷酷的術語跟大家分享。

https://ithelp.ithome.com.tw/upload/images/20230920/20158615vnp2bvHvKV.png
來源

flow 或 pipe 和其他的範例 function 不太一樣,這是因為它們把 function 當作輸入或是輸出了,這代表他們是 higher order function

Higher-order function
指某個 function 滿足以下任一條件

  1. 把其他 function 作為參數傳入
  2. 把其他 function 做回回傳值傳出

在 js 語言中 function 是一等公民,因為它符合以下定義

Functions are first-class citizen
指在某個語言中,function 像其他物件一樣可以作為變數儲存、作為參數傳遞、作為 function 的回傳值回傳。

在寫 JS 的時候我們可以把 function 當作參數丟進去一個 higher order funciton 產生另一個 function,真是太有趣了,對吧 ..... ?


上一篇
D04 - 設計資料模型
下一篇
D06 - 測試驅動開發
系列文
從 Next.js 開始的 Functional Programming30
圖片
  直播研討會
圖片
{{ item.channelVendor }} {{ item.webinarstarted }} |
{{ formatDate(item.duration) }}
直播中

尚未有邦友留言

立即登入留言