Functors 函子

Page content

前言

以下是從

  • 魔力 Haskell
  • Haskell Typeclassopedia

擷取出的程式碼和我自己的理解,如有錯誤還請海涵並告知

最近在看 Haskell,純 function 的設計和其他語言很不一樣,滿有趣的,但 Monad 的概念真的不是很好懂。 Monads 是 Applicative Functors,Applicative Functors 是 Functor,所以決定從 Functor 開始記。

所以總共會有三篇文章 :

WHAT I WISH I KNEW WHEN LEARNING HASKELL 推薦從 Haskell typesystem 看起,接著是 Typeclassopedia,讀關於 Monad 的定義,並且不要讀 Monad 的 tutorial,不要寫關於 Monad 的類比或比喻,並且實際把 Monad 用在 code 中。

定義

Prelude> :i Functor
class Functor (f :: * -> *) where
  fmap :: (a -> b) -> f a -> f b
  (<$) :: a -> f b -> f a
  {-# MINIMAL fmap #-}
  	-- Defined in ‘GHC.Base’

(下面還有 instances 的部分,例如 Maybe, [ ] 等,這裡先拿掉)

Functor instances 必須實作 fmap,fmap 的 type signature 是 (a -> b) -> f a -> f b ,可以把他看成接收一個 a -> b 的普通函數,並把它提升成 f a -> f b

f 是什麼

f 不是像 Int 一樣 concrete 的 type,他是 type constructor,需要一個 type 作為他的參數。f 的 kind 是 * -> *,舉例來說,Maybe 的 kind 就是 * -> *Maybe 本身不是一種 type,但 Maybe Int

fmap

fmap applies a function to each element of a container, without altering the structure of the container

(>$)

Finally, we can understand (<$): instead of applying a function to the values a container/context, it simply replaces them with a given value. This is the same as applying a constant function, so (<$) can be implemented in terms of fmap.

常見的 Functor instances

  • Maybe
  • Either
  • IO

Functor Laws

fmap id = id
fmap (g . h) = (fmap g) . (fmap h)

第一條說把 identity function map 到容器裡的每個元素沒有影響

第二條則是把兩個 function 的 composition map 過去,和先 map 一個 function,再 map 另一個,結果要是一樣的。

編譯器不會主動檢查這些規則,我們必須自己注意。

-- Evil Functor instance
instance Functor [] where
  fmap :: (a -> b) -> [a] -> [b]
  fmap _ [] = []
  fmap g (x:xs) = g x : g x : fmap g xs
a = [1..3]
fmap' id a == id a

Haskell Wiki: Category_theory/Functor

參考

You Could Have Invented Monads! (And Maybe You Already Have.)

工程化:Javascript中的Monad

參考資料

https://wiki.haskell.org/Typeclassopedia

http://dev.stephendiehl.com/hask/#functors

https://sovmedcare.github.io/archives/

https://hackage.haskell.org/package/base-4.11.0.0/docs/src/GHC.Base.html#Functor

https://en.wikibooks.org/wiki/Haskell/Applicative_functors