支援 ap
的 Object 稱為 Apply,可使用 ap
將 Apply 與回傳 Apply 的 Function 綁定改變 Apply。
Version
Ramda 0.27.1
Array
import { ap, inc } from 'ramda'
let data = [1, 2]
ap ([inc]) (data) // ?
data
為 Array,inc
為包進 Array 的 function,可使用 ap
將 Array 與 [inc]
綁定改變 Array。
ap
[a → b] → [a] → [b]
將 Array 與包進 Array 的 function 綁定改變 Array
[a -> b]
:包進 Array 的 function
[a]
:data 為 Array
[b]
:回傳新 Array
import { ap, inc, negate } from 'ramda'
let data = [1, 2]
ap ([inc, negate]) (data) // ?
也可將多個 function 包在 Array 內,若 data
有 m
的 element,傳入有 n
個 function,則 ap
會產生 m
x n
element 的新 Array。
Object
import { ap, inc, negate } from 'ramda'
let data = { x: 1, y: 2 }
ap ({ x: inc, y: negate }) (data) // ?
data
為 Object,想傳入 inc
與 negate
改變 data
,理論上可將 inc
與 negate
也包進 Object 再傳入 ap
,function 只會影響相同 key 的 property。
此在 Sanctuary 可正常執行,可惜在 Ramda 無法使用。
Maybe
Just
import { ap, inc, negate } from 'ramda'
import { Just } 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
Data 與 function 必須包在相同 typeclass 的 Object 內,因此都必須是 Maybe
Nothing
import { ap, inc, negate } from 'ramda'
import { Just, Nothing } from 'sanctuary'
let data = Nothing
let inc_ = Just (inc)
ap (inc_) (data) // ?
若 data
為 Nothing,則傳入 ap
的 function 不會執行。
Either
Right
import { ap, inc } from 'ramda'
import { Right } from 'sanctuary'
let data = Right (1)
let inc_ = Right (inc)
ap (inc_) (data) // ?
data
為 Either,inc_
為包進 Either 的 function,可使用 ap
將 Either 與 inc_
綁定改變 Either。
Data 與 function 必須包在相同 typeclass 的 Object 內,因此都必須是 Either
Left
import { ap, inc } from 'ramda'
import { Left, Right } from 'sanctuary'
let data = Left (1)
let inc_ = Right (inc)
ap (inc_) (data) // ?
若 data
為 Left,則傳入 ap
的 function 不會執行。
Future
Resolved
import { resolve, fork } from 'fluture'
import { pipe, ap, inc } from 'ramda'
import { log, error } from 'wink-fp'
let data = resolve (1)
let inc_ = resolve (inc)
pipe (
ap (inc_),
fork (error) (log)
) (data)
data
為 Future,inc_
為包進 Future 的 function,可使用 ap
將 Future 與 inc_
綁定改變 Future。
Data 與 function 必須包在相同 typeclass 的 Object 內,因此都必須是 Future
Rejected
import { resolve, reject, fork } from 'fluture'
import { pipe, ap, inc } from 'ramda'
import { log, error } from 'wink-fp'
let data = reject (1)
let inc_ = (resolve) (inc)
pipe (
ap (inc_),
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 外,也能用在 Maybe、Either 與 Future,因為這些也都是 Apply,可惜 Ramda 的ap
無法用在 Object