由於 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 感動耶
感謝大家閱讀!!!!!!!!!
工商時間: 未來會不定期更新,但會放在筆者的部落格 :) Happy Coding!