一般 Binary Function 並無法處理 Maybe、Either 或 Future,但只要透過 lift
提升後就可處理。
Version
Ramda 0.27.1
Primitive
import { add } from 'ramda'
import { Just } from 'sanctuary'
add (1) (2) // ?
add (Just (1)) (Just (2)) // ?
add
可處理 Number 相加,但卻無法處理 Maybe Number 相加,因為 add
無法處理 monadic type。
Maybe
Just
import { lift, add } from 'ramda'
import { Just } from 'sanctuary'
let data1 = Just (1)
let data2 = Just (2)
lift (add) (data1) (data2) // ?
add
使用 lift
提升後就能接受 Maybe。
lift
(*… → *) → ([*]… → [*])
將一般 function 提升能處理 Apply 的 function
(*… → *)
:一般 function
([*]… → [*])
:回傳能處理 Apply 的 function
Nothing
import { lift, add } from 'ramda'
import { Just, Nothing } from 'sanctuary'
let data1 = Just (1)
let data2 = Nothing
lift (add) (data1) (data2) // ?
若 data
為 Nothing,則 lift (add)
也會回傳 Nothing。
Either
Right
import { lift, add } from 'ramda'
import { Right } from 'sanctuary'
let data1 = Right (1)
let data2 = Right (2)
lift (add) (data1) (data2) // ?
add
使用 lift
提升後也能接受 Either。
Left
import { lift, add } from 'ramda'
import { Right, Left } from 'sanctuary'
let data1 = Right (1)
let data2 = Left (2)
lift (add) (data1) (data2) // ?
若 data
為 Left,則 lift (add)
也會回傳 Left。
Future
Resolved
import { resolve, fork } from 'fluture'
import { pipe, lift, add } from 'ramda'
import { error, log } from 'wink-fp'
let data1 = resolve (1)
let data2 = resolve (2)
pipe (
lift (add) (data2),
fork (error) (log)
) (data1)
add
使用 lift
提升後也能接受 Future。
Rejected
import { resolve, reject, fork } from 'fluture'
import { pipe, lift, add } from 'ramda'
import { error, log } from 'wink-fp'
let data1 = resolve (1)
let data2 = reject (2)
pipe (
lift (add) (data2),
fork (error) (log)
) (data1)
若 data
為 Rejected,則 lift (add)
也會回傳 Rejected。
Conclusion
- 不用擔心原本寫的 function 無法處理 Maybe、Either 與 Future 而重寫,只要使用
lift
加以提升後就可繼續使用 monadic type - 由於 Monad 就是 Apply,因此經過
lift
提升的 function 也適用於 Monad - Ramda 的
lift
可同時提升 unary function 與 binary function,不像 Sanctuary 需要靠map
提升 unary function,lift2
提升 binary function
Reference
Ramda, lift
stackoverflow, Can’t wrap my head around “lift” in Ramda.js