支援 ap
的 Object 稱為 Apply,若想傳入 Function 改變其內部值,可將 Function 包進 Apply 再透過 ap
傳入。
Version
Sanctuary 3.1.0
Array
import { ap, add } from 'sanctuary'
let data = [1, 2]
ap ([add (1)]) (data) // ?
data
為 Array,add (1)
為包進 Array 的 function,可使用 ap
將 Array 與 [add (1)]
綁定改變 Array。
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
Array 亦是 Apply,因此
ap
也適用
import { ap, add, negate } from 'sanctuary'
let data = [1, 2]
ap ([add (1), negate]) (data) // ?
也可將多個 function 包在 Array 內,若 data
有 m
的 element,傳入有 n
個 function,則 ap
會產生 m
x n
element 的新 Array。
Object
import { ap, add, negate } from 'sanctuary'
let data = { x: 1, y: 2 }
ap ({ x: add (1), y: negate }) (data) // ?
data
為 Object,想傳入 add (1)
與 negate
改變 data
,可將 add (1)
與 negate
也包進 Object 再傳入 ap
,function 只會影響相同 key 的 property。
Maybe
Just
import { Just, add, ap } from 'sanctuary'
let data = Just (1)
let add_ = Just (add (1))
ap (add_) (data) // ?
data
為 Maybe,add_
為包進 Maybe 的 function,可使用 ap
將 Maybe 與 add_
綁定改變 Maybe。
Data 與 function 必須包在相同 typeclass 的 Object 內,因此都必須是 Maybe
Nothing
import { Just, Nothing, add, ap } from 'sanctuary'
let data = Nothing
let add_ = Just (add (1))
ap (add_) (data) // ?
若 data
為 Nothing,則傳入 ap
的 function 不會執行。
Either
Right
import { Right, add, ap } from 'sanctuary'
let data = Right (1)
let add_ = Right (add (1))
ap (add_) (data) // ?
data
為 Either,add_
為包進 Either 的 function,可使用 ap
將 Either 與 add_
綁定改變 Either。
Data 與 function 必須包在相同 typeclass 的 Object 內,因此都必須是 Either
Left
import { Left, Right, map, add, ap } from 'sanctuary'
let data = Left (1)
let add_ = Right (add (1))
ap (add_) (data) // ?
若 data
為 Left,則傳入 ap
的 function 不會執行。
Future
Resolved
import { resolve, fork } from 'fluture'
import { create, env } from 'sanctuary'
import { env as flutureEnv } from 'fluture-sanctuary-types'
import { log, error } from 'wink-fp'
let { pipe, add, ap } = create ({ checkTypes: true, env: env.concat (flutureEnv) })
let data = resolve (1)
let add_ = resolve (add (1))
pipe ([
ap (add_),
fork (error) (log)
]) (data)
data
為 Future,add_
為包進 Future 的 function,可使用 ap
將 Future 與 add_
綁定改變 Future。
Data 與 function 必須包在相同 typeclass 的 Object 內,因此都必須是 Future
Rejected
import { resolve, reject, fork } from 'fluture'
import { create, env } from 'sanctuary'
import { env as flutureEnv } from 'fluture-sanctuary-types'
import { log, error } from 'wink-fp'
let { pipe, add, ap } = create ({ checkTypes: true, env: env.concat (flutureEnv) })
let data = reject (1)
let add_ = resolve (add (1))
pipe ([
ap (add_),
fork (error) (log)
]) (data)
若 data
為 Rejected,則傳入 ap
的 function 不會執行。
Conclusion
- 支援
ap
的 Object 稱為 Apply - 可發現
Functor f => map (a -> b) -> f a
與Apply f => ap (f (a -> b)) -> f a
是等效的,只是以不同方式處理 function,Apply 要透過ap
傳入包進 Apply 的 function;而 Functor 則透過map
直接傳入 function 即可 ap
除了能用在 Array 與 Object 外,也能用在 Maybe、Either 與 Future,因為這些也都是 Apply