點燈坊

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

Functor、Apply 與 Chain 簡單比較

Sam Xiao's Avatar 2021-08-17

Functor、Apply 與 Chain 本質都是 Typeclass,只是各提供不同方式處理 Function 而已。

Version

Sanctuary 3.1.0

Functor

import { inc } from 'ramda'
import { Just, map } from 'sanctuary'

let data = Just (1)

map (inc) (data) // ?

data 為 Maybe,inc 為一般 function,可使用 map 將 Maybe 與 inc 綁定改變 Maybe。

map :: Functor f => (a -> b) -> f a -> f b
將 Functor 與一般 function 綁定改變 Functor

a -> b:一般 function

f a:data 為 Functor

f b:回傳新 Functor

monad000

Apply

import { inc } from 'ramda'
import { Just, ap } from 'sanctuary'

let data = Just (1)
let inc_ = Just (inc)

ap (inc_) (data) // ?

data 為 Maybe,inc_ 為包進 Maybe 的 function,可使用 ap 將 Maybe 與 inc_ 綁定改變 Maybe。

ap :: Apply f => f (a -> b) -> f a -> f b
將 Apply 與包進 Apply 的 function 綁定改變 Apply

f (a -> b):包進 Apply 的 function

f a:data 為 Apply

f b:回傳新 Apply

monad001

Chain

import { inc } from 'ramda'
import { compose, Just, chain } from 'sanctuary'

let data = Just (1)
let inc_ = compose (Just) (inc)

chain (inc_) (data) // ?

data 為 Maybe,inc_ 為回傳 Maybe 的 function,可使用 chain 將 Maybe 與 inc_ 綁定改變 Maybe。

chain :: Chain m => (a -> m b) -> m a -> m b
將 Chain 與回傳 Chain 的 function 綁定改變 Chain

a -> m b:回傳 Chain 的 function

m a:data 為 Chain

m b:回傳新 Chain

monad002

Conclusion

  • 為什麼本文都以 Maybe 討論呢 ? 因為 Maybe 既是 Functor、Apply 也是 Chain,因此 mapapchain 都可使用,只是傳入 function 形式不同而已
  • Fantasy Land 稱為 Apply,但 Haskell 稱為 Applicative,事實上都是支援 ap 的 Object

Reference

Adit Bhargava, Functors, Applicatives, And Monads in Pictures
Sanctuary, map
Sanctuary, ap
Sanctuary, chain