點燈坊

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

使用 lift 提升 Binary Function

Sam Xiao's Avatar 2021-07-04

一般 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。

binary000

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

binary001

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。

binary002

Either

import { lift, add } from 'ramda'
import { Right } from 'sanctuary'

let data1 = Right (1)
let data2 = Right (2)

lift (add) (data1) (data2) // ?

add 使用 lift 提升後也能接受 Either。

binary003

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。

binary004

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。

binary005

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。

binary006

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