點燈坊

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

如何解開 Future Maybe ?

Sam Xiao's Avatar 2021-07-24

Future Maybe 為常見的 Monad Stack,如呼叫 API 回傳 Future,再使用回傳 Maybe 的 function 改變 API 回傳值,就會出現 Future Maybe。

Version

Fluture 14.0.0
Sanctuary 3.1.0

Future Maybe

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

let { pipe, compose, map, chain, Just, add, maybe, I } = create ({ checkTypes: true, env: env.concat (flutureEnv) })

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

pipe ([
  map (add (1)),
  chain (encase (add (2))),
  map (compose (Just) (add (3))),
  fork (error) (compose (log) (maybe (0) (I)))
]) (data)

第 8 行

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

data 為 Future。

11 行

pipe ([
  map (add (1)),
  chain (encase (add (2))),
  map (compose (Just) (add (3))),
  fork (error) (compose (log) (maybe (0) (I)))
]) (data)

使用 pipe 組合 IIFE:

  • map (add (1)):將 Future 與一般 function 綁定,回傳 Future
  • chain (encase (add (2))):將 Future 與回傳 Future 的 function 綁定,回傳 Future
  • map (compose (Just) (add (3))):將 Future 與回傳 Maybe 的 function 綁定,回傳 Future Maybe
  • fork (error) (compose (log) (maybe (0) (I))):從外層開始依序解開 Future 與 Maybe,因此先使用 fork 解開 Future,再使用 compose (log) (maybe (0) (I)) 解開 Maybe

最後在 fork 一次解開 Future 與 Maybe 雖然可行,但可讀性稍差,似乎不是最佳解法

fluture000

map (maybe)

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

let { pipe, compose, map, chain, Just, add, maybe, I } = create ({ checkTypes: true, env: env.concat (flutureEnv) })

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

pipe ([
  map (add (1)),
  chain (encase (add (2))),
  map (compose (Just) (add (3))),
  map (maybe (0) (I)),
  fork (error) (log)
]) (data)

11 行

pipe ([
  map (add (1)),
  chain (encase (add (2))),
  map (compose (Just) (add (3))),
  map (maybe (0) (I)),
  fork (error) (log)
]) (data)
  • map (maybe (0) (I)):先解 Maybe,因此使用 map 將 Future 與 maybe (0) (I) 綁定先將 Future 內的 Maybe 解開
  • fork (error) (log):最後再解開 Future

如此 fork 就很清爽,可讀性更高了

fluture001

Conclusion

  • 無論是 Future Maybe 或 Maybe Future,拆開的關鍵都是先解 Maybe,最後解 Future,永遠將 fork 放在 pipe 內最後一行