點燈坊

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

如何解開 Future Either Maybe ?

Sam Xiao's Avatar 2021-07-31

Future Either Maybe 為常見的 Monad Stack,如呼叫 API 回傳 Future,再使用回傳 Either 的 Function 判斷 API 回傳值,又使用回傳 Maybe 的 Function 運算,就會出現 Future Either Maybe。

Version

Fluture 14.0.0
Sanctuary 3.1.0

Fluture Either Maybe

import { create, env } from 'sanctuary'
import { thunkify } from 'ramda'
import { resolve, reject, fork } from 'fluture'
import { env as flutureEnv } from 'fluture-sanctuary-types'
import { toMaybe, error, log } from 'wink-fp'

let { pipe, map, add, ifElse, equals, Left, Right, either, maybe, I } = create ({ checkTypes: true, env: env.concat (flutureEnv) })

// let data = resolve (1)
let data = resolve (2)
// let data = reject (1)

let chkOne = ifElse 
  (equals (1))
  (thunkify (Left) (`Can't input one`))
  (Right)

let add2 = map (toMaybe) (add (2)) 

pipe ([
  map (chkOne), 
  map (map (add2)), 
  map (map (maybe (0) (I))),
  map (either (I) (I)),
  fork (error) (log)
]) (data) 

第 9 行

// let data = resolve (1)
let data = resolve (2)
// let data = reject (1)

data 為 Future。

13 行

let chkOne = ifElse 
  (equals (1))
  (thunkify (Left) (`Can't input one`))
  (Right)

chkOne 回傳 Either,若輸入為 1 則回傳 Left,否則回傳 Right。

18 行

let add2 = map (toMaybe) (add (2))

add2 回傳 Maybe,使用 map 組合 add (2)toMaybe

20 行

pipe ([
  map (chkOne), 
  map (map (add2)), 
  map (map (maybe (0) (I))),
  map (either (I) (I)),
  fork (error) (log)
]) (data) 

使用 pipe 組合 IIFE:

  • map (chkOne)data 為 Future,chkOne 回傳 Either,最後為 Future Either
  • map (map (add2))add2 回傳 Maybe,最後為 Future Either Maybe
  • map (map (maybe (0) (I))):解開 Mabye
  • map (either (I) (I)):解開 Either
  • fork (error) (log):解開 Future

maybe000

Conclusion

  • Future Either Maybe 看起來很嚇人,關鍵是從內往外解,先解開 Maybe,再解開 Either,最後解開 Future,永遠將 fork 放在 pipe 內最後一行