iT邦幫忙

2021 iThome 鐵人賽

DAY 29
0
Software Development

Functional Programming For Everyone系列 第 29

Day 29 - State Monad IV

Review

由於 State 原本可以一篇寫完的,被我拖成四篇的關係,所以來回顧一下,哈哈哈哈哈哈

這是我們的前幾章實作的 State Monad

const State = (run) => ({
  run,
  map: (f) =>
    State((a) => {
      const [y, s] = run(a);
      return [f(y), s];
    }),
  chain: (f) =>
    State((x) => {
      const [y, s] = run(x);
      return f(y).run(s);
    }),
  ap: (m) =>
    State((x) => {
      const [y, s] = run(x);
      return m.map(y).run(s);
    }),
});

State.of = a => State(s => [a, s])

今天來介紹一下 State Monad 的 Helper function

get

就像是 Reader Monad 的 ask 一樣, 我們也可以從 State 取值,就會變成 State s s

// State.get :: () -> State s s
State.get = () => State(x => [x, x])
const data = { address: { postal_code: 123 } };
const getCode = (prop) => prop.address.postal_code || 0;

State.get()
    .map(getCode)
    .run(data); // [123,{"address":{"postal_code":123}}]

modify

也可以修改的 State 的狀態

// State.modify :: (s -> s) -> State s ()
State.modify = f => State(s => [null, f(s)])

還記得在 Lenses 那章有提到如何用 immutable 的方法操縱物件嗎?

如果現在要讓一個物件裡的目標資料進行修改要如何做呢???

沒錯,大家應該都想到了

const mapProps = (target, func) => R.over(R.lensPath(target), func);

這樣就可以用 mapProps 修改我們 data 這個狀態

State
  .modify(mapProps(['address', 'postal_code'], R.add(10)))
  .run(data); // [null,{"address":{"postal_code":133}}]

put

最後可以更新 State 的狀態!

State.put = x => State(s => [null, x])

我們要創建一個 reset 函式,直接用 "missing :))))))" 取代現有的狀態

const reset = () => State.put("missing :))))))");

現在我們就可以將使用 reset 更新現有狀態

State.get().map(getCode).chain(reset).run(data); // [null,""]

小結

明天就是最後一天了,最後一天了,最後一天了,真的要完賽了 QAQ 感動耶 /images/emoticon/emoticon01.gif

感謝大家閱讀!!!!!!!!!

工商時間: 未來會不定期更新,但會放在筆者的部落格 :) Happy Coding!


上一篇
Day 28 - State Monad III
下一篇
Day 30 - The Beginning
系列文
Functional Programming For Everyone30

尚未有邦友留言

立即登入留言