一般 Unary Function 並無法處理 Maybe、Either 或 Future,但只要透過 lift
提升後就可處理。
Version
Ramda 0.27.1
Primitive
import { negate } from 'ramda'
import { Just } from 'sanctuary'
negate (1) // ?
negate (Just (1)) // ?
negate
可處理 Number 為負值,但卻無法處理 Maybe Number 相加,因為 negate
無法處理 monadic type。
Maybe
Just
import { lift, negate } from 'ramda'
import { Just } from 'sanctuary'
let data = Just (1)
lift (negate) (data) // ?
negate
使用 lift
提升後就能接受 Maybe。
lift
(*… → *) → ([*]… → [*])
將一般 function 提升能處理 Apply 的 function
(*… → *)
:傳入一般 function
([*]… → [*])
:回傳能處理 Apply 的 function
Nothing
import { lift, negate } from 'ramda'
import { Nothing } from 'sanctuary'
let data = Nothing
lift (negate) (data) // ?
若 data
為 Nothing,則 lift (negate)
也會回傳 Nothing。
Either
Right
import { lift, negate } from 'ramda'
import { Right } from 'sanctuary'
let data = Right (1)
lift (negate) (data) // ?
negate
使用 lift
提升後也能接受 Either。
Left
import { lift, negate } from 'ramda'
import { Left } from 'sanctuary'
let data = Left (1)
lift (negate) (data) // ?
若 data
為 Left,則 lift (negate)
也能回傳 Left。
Future
Resolved
import { resolve, fork } from 'fluture'
import { pipe, lift, negate } from 'ramda'
import { error, log } from 'wink-fp'
let data = resolve (1)
pipe (
lift (negate),
fork (error) (log)
) (data)
negate
使用 lift
提升後也能接受 Future。
Rejected
import { reject, fork } from 'fluture'
import { pipe, lift, negate } from 'ramda'
import { error, log } from 'wink-fp'
let data = reject (1)
pipe (
lift (negate),
fork (error) (log)
) (data)
若 data
為 Rejected,則 lift (negate)
也能回傳 Rejected。
Why ?
看到這裡可能會覺得很神奇,為什麼 negate
這種一般 function 經過 lift
提升後就可以使用 Maybe、Either 與 Future 呢 ?
lift
原意是將普通 function 提升成能處理 Apply 的 function,它在內部會呼叫 Apply 的 ap
,因此一般 function 得以在 Apply 內運算。
別忘了 Monad 必須符合 Functor、Apply、Applicative 所有特性,也就是 Monad 就是 Apply,它必須提供 ap
,因此可被 lift
所提升的 function 能呼叫使用。
Conclusion
- 不用擔心原本寫的 function 無法處理 Maybe、Either 與 Future 而重寫,只要使用
lift
加以提升後就可繼續使用 monadic type - 由於 Monad 就是 Apply,因此經過
lift
提升的 function 也適用於 Monad
Reference
Ramda, lift
stackoverflow, Can’t wrap my head around “lift” in Ramda.js