iT邦幫忙

2023 iThome 鐵人賽

DAY 18
0
Software Development

Haskell 從入門到放棄系列 第 18

[Haskell 從入門到放棄] Day 18 - Functor

  • 分享至 

  • xImage
  •  

Functor

用最簡單的一句話來解釋 functor 就是指可以被 map 的東西像是 List ,而在 Haskell functor 就只是 typeclass

在 Haskell 是這麼定義的

class Functor f where
    fmap :: (a -> b) -> f a -> f b

這邊會看到 Functor 只有定義一個 function fmap ,它接受一個 function (a → b) 作為參數,然後接受一個被 functor 包裝起來 f a 最後回傳被 functor 包裝的 f b

當然這樣解釋還是很模糊那我們先從 list 來看,我們 map list的方式就是使用 map 這個 function

:t map
-- map :: (a -> b) -> [a] -> [b] 

map 的定義是傳入一個 function (a → b)[a] 最後會回傳 [b] ,乍看之下 fmapmap 可以說一模一樣。而實際上的確 map 就是在 list 這個 type 的 fmap ,還記得前面所說的嗎 Functor 是一個 typeclass ,所以只是 list 在實作 Functor 的 instance 時將 fmap 定義為這種形式。

而實際上 Haskell 的原始碼也的確是如此定義

instance Functor [] where
    fmap = map

這邊有一個值得關注的點是這裡是寫作 Functor [] 而不是 Functor [a]instance Functor [] where 的定義表示 [] 本身是一個 Functor,而不僅僅是某一個特定的 [a] 列表,這是因為 Functor 的定義是針對一個 type constructor 而不是特定的 type 。

我們可以再看看 Maybe ,一樣的其實我們不必在意是怎樣具體的 type ,而是只要是 Maybe 就好。

instance Functor Maybe where
    fmap f (Just x) = Just (f x)
    fmap f Nothing = Nothing

而這邊的定義是當我們匹配到 function f 以及 Just x 時就是將 x 丟進 f 最後再加上 Just

又或者我們可以說 fmap 不管是在 Maybe 還是 [] 做的事情就是將一個容器打開執行完 function 再塞回容器。

所以 functor 到底是什麼?儘管我們用了 list、Maybe 等容器的概念輔助解釋,但 functor 終究不是一種「實際的容器」,而是在形容如果某些容器具有可以被 map 這個特性那它就是 functor 。


如果有讀者在之前有透過其他語言先認識到 functor 的話,相信應該會對它的定義有許多混亂的點。當初第一次聽到時我也會傾向用「容器」的想法在看待 functor ,但隨著對於 FP 有了進一步的認識,我感覺不應該把 functor 當作一個「實際存在的資料結構」,而是只是在描述一種抽象概念或者該說一種 typecalss 而已。


上一篇
[Haskell 從入門到放棄] Day 17 - Typeclass
下一篇
[Haskell 從入門到放棄] Day 19 - Applicative
系列文
Haskell 從入門到放棄30
圖片
  直播研討會
圖片
{{ item.channelVendor }} {{ item.webinarstarted }} |
{{ formatDate(item.duration) }}
直播中

尚未有邦友留言

立即登入留言