一般我們所寫的 Function 都只能處理 ECMAScript 的原生 Type,而無法處理 Maybe、Either、Future 這類 Monadic Type,透過 lift2
可將普通 Binary Function 提升成能處理 Apply 的 Function。
Version
Sanctuary 3.1.0
Primitive
import { add, Just } from 'sanctuary'
add (1) (2) // ?
add (Just (1)) (Just (2)) // ?
add
可處理 Number 相加,但卻無法處理 Maybe Number 相加,因為 add
無法處理 monadic type。
Maybe
Just
import { lift2, add, Just } from 'sanctuary'
let data1 = Just (1)
let data2 = Just (2)
lift2 (add) (data1) (data2) // ?
add
使用 lift2
提升後就能接受 Maybe。
lift2
Apply f => (a -> b -> c) -> f a -> f b -> f c
將 binary function 提升成能接受 Apply 的 function
a -> b -> c
:一般 binary function
f a -> f b -> f c
:回傳能接受 Apply 的 binary function
Nothing
import { lift2, add, Just, Nothing } from 'sanctuary'
let data1 = Just (1)
let data2 = Nothing
lift2 (add) (data1) (data2) // ?
若 data
為 Nothing,則 lift2 (add)
也會回傳 Nothing。
Either
Right
import { lift2, add, Right } from 'sanctuary'
let data1 = Right (1)
let data2 = Right (2)
lift2 (add) (data1) (data2) // ?
add
使用 lift2
提升後也能接受 Either。
Left
import { lift2, add, Right, Left } from 'sanctuary'
let data1 = Right (1)
let data2 = Left (2)
lift2 (add) (data1) (data2) // ?
若 data
為 Left,則 lift2 (add)
也會回傳 Left。
Future
Resolved
import { resolve, fork } from 'fluture'
import { env as flutureEnv } from 'fluture-sanctuary-types'
import { create, env, add } from 'sanctuary'
import { error, log } from 'wink-fp'
let { pipe, lift2 } = create ({ checkTypes: true, env: env.concat (flutureEnv) })
let data1 = resolve (1)
let data2 = resolve (2)
pipe ([
lift2 (add) (data2),
fork (error) (log)
]) (data1)
第 6 行
let { pipe, lift2 } = create ({ checkTypes: true, env: env.concat (flutureEnv) })
Sanctuary 並不認識 Future 而導致無法通過 type checking,因此要使用 Fluture 提供的 fluture-sanctuary-types
。
11 行
pipe ([
lift2 (add) (data2),
fork (error) (log)
]) (data1)
add
使用 lift2
提升後也能接受 Future。
Rejected
import { resolve, reject, fork } from 'fluture'
import { env as flutureEnv } from 'fluture-sanctuary-types'
import { create, env, add } from 'sanctuary'
import { error, log } from 'wink-fp'
let { pipe, lift2 } = create ({ checkTypes: true, env: env.concat (flutureEnv) })
let data1 = resolve (1)
let data2 = reject (2)
pipe ([
lift2 (add) (data2),
fork (error) (log)
]) (data1)
若 data
為 Rejected,則 lift2 (add)
也會回傳 Rejected。
Conclusion
- 只要遵循 Fantasy Land 的 monadic type,function 就能彼此支援,因此 Sanctuary 的
lift2
也能使用 Fluture 的 Future - Sanctuary 的 type checking 預設並不認識 Future,但 Fluture 支援 Sanctuary,只要使用
fluture-sanctuary-types
後,Sanctuary 也能對 Future 使用 type checking - Ramda 的
lift
可同時提升 unary function 與 binary function,不像 Sanctuary 需要靠map
提升 unary function,lift2
提升 binary function