點燈坊

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

使用 chain 將 Chain 與回傳 Chain 的 Function 綁定

Sam Xiao's Avatar 2021-07-10

支援 chain 的 Object 稱為 Chain,可使用 chain 將 Chain 與回傳 Chain 的 Function 綁定改變 Chain。

Version

Ramda 0.27.1

Array

import { of, inc, chain } from 'ramda'
import { compose } from 'sanctuary'

let data = [1, 2]

let inc_ = compose (of) (inc)

chain (inc_) (data) // ?

data 為 Array,inc_ 為回傳 Array 的 function,可使用 chain 將 Array 與 inc_ 綁定改變 Array。

chain
Chain m => (a -> m b) -> m a -> m b
將 Chain 與回傳 Chain 的 function 綁定改變 Chain

a -> m b:回傳 Chain 的 function

m a:data 為 Chain

m b:回傳新 Chain

Array 亦是 Chain,因此 chain 也適用

chain000

Maybe

Just

import { inc, chain } from 'ramda'
import { compose, Just } from 'sanctuary'

let data = Just (1)

let inc_ = compose (Just) (inc)

chain (inc_) (data) // ?

data 為 Maybe,inc_ 為回傳 Maybe 的 function,可使用 chain 將 Maybe 與 inc_ 綁定改變 Maybe。

chain001

Nothing

import { inc, chain } from 'ramda'
import { compose, Just, Nothing } from 'sanctuary'

let data = Nothing

let inc_ = compose (Just) (inc)

chain (inc_) (data) // ?

data 為 Nothing,則傳入 chain 的 function 不會執行。

chain002

Either

import { inc, chain } from 'ramda'
import { compose, Right } from 'sanctuary'

let data = Right (1)

let inc_ = compose (Right) (inc)

chain (inc_) (data) // ?

data 為 Either,inc_ 為回傳 Either 的 function,可使用 chain 將 Either 與 inc_ 綁定改變 Either。

chain003

Left

import { inc, chain } from 'ramda'
import { compose, Left, Right } from 'sanctuary'

let data = Left (1)

let inc_ = compose (Right) (inc)

chain (inc_) (data) // ?

data 為 Left,則傳入 chain 的 function 不會執行。

chain004

Future

Resolved

import { resolve, fork } from 'fluture'
import { inc, chain } from 'ramda'
import S from 'sanctuary'
import { log, error } from 'wink-fp'

let { compose, unchecked: { pipe }} = S

let data = resolve (1)

let inc_ = compose (resolve) (inc)

pipe ([
  chain (inc_),
  fork (error) (log)
]) (data) 

data 為 Future,inc_ 為回傳 Future 的 function,可使用 chain 將 Future 與 inc_ 綁定改變 Future。

chain005

Rejected

import { resolve, reject, fork } from 'fluture'
import { inc, chain } from 'ramda'
import S from 'sanctuary'
import { log, error } from 'wink-fp'

let { compose, unchecked: { pipe }} = S

let data = reject (1)

let inc_ = compose (resolve) (inc)

pipe ([
  chain (inc_),
  fork (error) (log)
]) (data)

data 為 Rejected,則傳入 chain 的 function 不會執行。

chain006

Conclusion

  • 支援 chain 的 Object 稱為 Chain
  • chain 為 Monadic Programming 重要 function,在不同語言有不同稱呼,Haskell 稱為 bind,ECMAScript 稱為 chainflatMap,C# 則稱為 selectMany,事實上指的是同一個 function
  • chain 除了能用在 Array 外,也能用在 Maybe、Either 與 Future,因為這些也都是 Chain

Reference

Ramda, chain