點燈坊

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

自行實作 Functor

Sam Xiao's Avatar 2021-08-05

Functor 是 Monadic Programming 中最基本 Typeclass,透過自行實作 Functor 可更清楚了解 Functor 本質。

Version

Fantasy Land 5.0.0

Fantasy Land

functor003

在眾多 ADT 中,Functor 位於最底層,也是眾多 ADT 的基礎。

Functor

import { compose, map, inc } from 'ramda'

let Functor = x => {
  let _x = x

  let map = f => Functor (f (_x))

  let getValue = _ => _x

  return {
    map,
    getValue
  }
}

let getValue = x => x.getValue ()

let data = Functor (1)

compose (getValue, map (inc)) (data) // ?

使用 module 實現 Functor。

第 4 行

let _x = x

相當於 constructor 將 x 值存進 _x 內。

第 6 行

let map = f => Functor (f (_x))

根據 Fantasy Land 定義:

fantasy-land/map :: Functor f => f a ~> (a → b) → f a → f b

Object 必須有 map 才是 Functor。

將 Object 內部 _x 透過傳入 f 運算後,使用 Functor 包成新 Functor 回傳。

第 8 行

let getValue = _ => _x

使用 getValue 取出 Functor 內部值。

getValue 並非 Fantasy Land 所要求,只是方便取出 Object 內部 value

16 行

let getValue = x => x.getValue ()

提供 free function 方便使用:

  • getValue:呼叫 Functor 的 getValue

18 行

let data = Functor (1)

compose (getValue, map (inc)) (data) // ?

使用 Ramda 的 map 將 Functor 與 inc 綁定,確認自行建立的 Functor 符合 Fantasy Land 規格。

functor001

Conclusion

  • Functor 為 Monadic Programming 基礎,是最基本 typeclass,其定義是必須支援 map 且實踐 Functor law