點燈坊

失くすものさえない今が強くなるチャンスよ

深入淺出 Functor Laws

Sam Xiao's Avatar 2021-07-17

Functor 遵循 2 個 Functor Laws,專門描述 map 的 2 個特性:Identity 與 Composition。

Version

Fantasy Land 5.0.0

Identity

import { map, I } from 'sanctuary'

let data = [1, 2, 3]

map (I) (data) // ?
I (data) // ?
  • 使用 map 將 Functor 與 I 綁定
  • 使用 I 將 Functor 綁定

兩者結果相同。

也就是 map 傳入 I 相當於 I,都不會改變 Functor 內部 value。

Identity
fmap id = id

  • fmap id:將 id 傳入 fmap

  • id:只有 id

  • =:兩個 function 等價

laws000

Composition

import { pipe, compose, map, add, negate } from 'sanctuary'

let data = [1, 2, 3]

pipe ([map (add (1)), map (negate)]) (data) // ?
map (compose (negate) (add (1))) (data) // ?
  • 多次使用 map 將 Functor 與 function 綁定
  • 使用 compose 將所有 function 先組合再一次與 map 綁定

兩者結果相同。

也就是可將多次 map 的所有 function 先組合成單一 function 後,再一次傳進 map

Composition
fmap f . fmap g = fmap (f . g)

  • fmap f . fmap g:多次使用 fmap 傳入 function
  • fmap (f . g):將 function 先組合再傳入 fmap
  • =:兩個 function 等價

laws001

Conclusion

  • Haskell 稱為 id,在 Ramda 稱為 identity,在 Sanctuary 稱為 I
  • Haskell 稱為 fmap,在 Fantasy Land 稱為 map,為 Functor 必備 function

Reference

Haskell Wiki, Functor