iT邦幫忙

第 12 屆 iThome 鐵人賽

DAY 22
1
Software Development

mostly:functional 從零開始的異世界程式觀 --- 函數式程式設計的試煉系列 第 22

mostly:functional 第二十一章:Monoid 的法則

…那我告訴你一件有趣的事吧。
----- 腦只是鏡子。連接在機械上的腦所生出的不是腦的原主意識,而是所接續的機械的意識。

-- 京極夏彥, 魍魎之匣


而當我走到門前的時候,金屬板也慢慢飄過來停在我的眼前,上面的字也換了,寫著:

Monoid 的實作:

class Semigroup a => Monoid a where
mempty :: a
mappend :: a -> a -> a
mconcat :: [a] -> a
{-# MINIMAL mempty #-}

Monoid 的法則:

  1. 封閉律
  2. 結合律
  3. 單位元素 (Identity)

正想著難道這就是那個 Monad...仔細一看,才發現只是長得很像而已。這個 Monoid 法則的前兩條,跟之前 Semigroup 的一樣。但是…嗯…又來外星文了,這個單位元素又是什麼?




讓我們再次回到整數加法。在這麼多的整數裡,有一個特別的數字。任何數加上它,都會是它們自己,也就是 0。例如

https://chart.googleapis.com/chart?cht=tx&chl=10%20%2B%200%20%3D%200%20%2B%2010%20%3D%2010

當然,在整數乘法上,也有這樣一個特別的數字,可以使得任何數乘上它,都會是它們自己。


函式的名字: m for Monoid

memptymappendmconcat這幾個函式的名字,都符合 "m" 後面加上一個動詞的規則。而這幾個 m 代表的就是這裡的 Monoid。所以可以看成是 monoid 的 emptymonoid 的 append 等等。而這個命名的慣例,之後會還會再看到好幾次。


型別標記:前題

當我們看到型別宣告是寫成 class Semigroup a => Monoid a 的時候,箭號 => 的左邊,稱為前題,代表當已知 a 是一個 Semigroup 時。而右邊跟下面的敘述代表:若能再多證明一些性質,就可以推導出 a 也是一個 Monoid。而在證明中,你可以把 a 當做一個 Semigroup 來使用。


抽象

當我們知道某群東西 https://chart.googleapis.com/chart?cht=tx&chl=S 是 Semigroup 後,我們只需要再多做一件事:找到那個特別的東西。

  1. 單位元素
    https://chart.googleapis.com/chart?cht=tx&chl=S 裡,有個特別的成員,任何其它成員跟它 https://chart.googleapis.com/chart?cht=tx&chl=%3C%3E 在一起,都還是它自己。

我們假設這個東西叫 https://chart.googleapis.com/chart?cht=tx&chl=e ,另外隨便挑任意一個成員 https://chart.googleapis.com/chart?cht=tx&chl=a,那麼可以寫成:

https://chart.googleapis.com/chart?cht=tx&chl=a%20%3C%3E%20e%20%3D%20a

加上交換律,可以說這三個東西都一樣:

https://chart.googleapis.com/chart?cht=tx&chl=a%20%3C%3E%20e%20%3D%20e%20%3C%3E%20a%20%3D%20a

能夠符合封閉律、結合律,並能找到單位元素的,我們稱這種群體為 Monoid 。




所以這個門,想要的是單位元素囉?我找到了一個 0,然後四處探尋,找了好久,才在其它房間的書櫃上找到一個標著 Sum 的小盒子。我把 0 裝進盒子裡,再次往盡頭的房間走去。

[to be continue]


上一篇
mostly:functional 第二十章:Semigroup 的實體
下一篇
mostly:functional 第二十二章:Monoid 的實體
系列文
mostly:functional 從零開始的異世界程式觀 --- 函數式程式設計的試煉35

尚未有邦友留言

立即登入留言