iT邦幫忙

2023 iThome 鐵人賽

DAY 18
0

API 的代數性質

在 API 實作過程中,我們都是先把 function 的型態定義好,然後在隨著型態去實現它,例如 map 就是用了 map2unit 來實現,這些是自然的演變,也可以說是我們簡化了代數方程式。我們讓 API 有了代數性質,或者說當我們有了基礎定律後,然後我們照著這個代數性的遊戲規則做一連串操作;

就像所有設計選擇,定律選擇都有後果,它限制了操作的意義以及何種實現可行,讓我們用一個例子看一下 mapping 的定律。

mapping 定律

首先我們創造一個看起來合理的定律如下(定律通常都是從具體的方程式範例而來),

map(unit(1))(_ + 1) == unit(2)

unit(1)_ + 1unit(2) 相等,以 Par 來說,就是 Future 裡的值相等,

然後定律和 function 有許多共同點,就像我們一般化 (抽象) function 那樣,我們也可以一般化定律,

map(unit(x))(f) == unit(f(x))

這裡不只限定了 1 和 _ + 1,我們可以用任何的 f 來讓等號 2 邊相等,接下來我們可以繼續簡化定律,若我們將 f 替換成 function id 的話,

def id[A](a: A): A = a

我們可以簡化方程式 2 邊的表達式然後最後得到新的定律,

map(unit(x))(id) == unit(id(x))
map(unit(x))(id) == unit(x)     // 簡化
map(y)(id) == y 								// 用 y 將 2 邊的 unit(x) 替換

我們新的定律現在不需要 unit 這個 function 了。

邏輯上來看,我們能自由做這些轉換,是因為 map 不可能對其接收的 function type 不同而有不同行為,因此,當給定 map(y)(id) = y 時,它等同於 map(unit(x))(id) == unit(id(x))

這個新的第二個定律通常也被稱為 free theorem

總結

這幾天我們設計了平行化計算和非同步 library,重點是透過設計 API,來了解遭遇問題時該怎麼以 purely functional 的設計思維去解決,我們使用容器型態 Par 來做為平行化計算的依據,將 執行(run) 這個真正初始化執行緒的動作分離出來,最後設計出核心 API 來使 Par 能自由組合、操作。


上一篇
Purely Function 的平行化 (3)
下一篇
能自由組合的解析器 Library (1)
系列文
用 Scala 3 寫的 Functional Programming 會長什麼樣子?30
圖片
  直播研討會
圖片
{{ item.channelVendor }} {{ item.webinarstarted }} |
{{ formatDate(item.duration) }}
直播中

尚未有邦友留言

立即登入留言