Haskell有多少跟State/Reference有關的東西?
比如IO/IORef,State,ST/STRef,Lens等等。。。
實現 State/Reference 的方法分為 2 類:純函數顯式傳遞 state,或者使用 rts 提供的 state 相關特性。
純函數這個原理當然很簡單,s -&> (a, s) 用表示結果類型為 a,並且變更一個類型為 s 的狀態的計算過程,這個在 transformers 庫里有定義。State/StateT 可以通過 monad bind 將一系列狀態類型為 s 的計算過程結合起來,最終輸入初始狀態可以獲取計算結果和最終狀態。
純函數模擬的狀態簡單高效,但不能解決多線程共享狀態和隨機訪問的問題,所以有時還是需要底層實現的 state。首先 ghc-prim 中提供了許多帶副作用的指針/引用/數組的讀寫操作,這些帶副作用的操作類型簽名大致都是 State# s -&> (# State# s, a #),這個 State# 是 state token(比如 IO monad 對應的 state token 就是 RealWorld 類型,這個類型經過 codegen 以後不產生運行時表示,僅用於在 codegen 之前確定副作用的發生順序),然後基於這些操作,可以封裝出 IO/ST monad 中的帶副作用讀寫。跟純函數的版本相比,我們可以像操作 C 數組一樣隨機訪問,可以調用 CAS 指令做原子操作,可以用各種 unsafeFreeze/unsafeThaw 將可變/不可變的數組相互轉換,等等。
實現原理就以上兩類,至於提供給用戶的介面,比如 mtl 中的 MonadState,或者各種基於 free monad 的 effect system 中的 State,它們在同一個介面下可以切換不同的 State 實現。
P.S.
每次調用 ghc-prim 裡帶副作用的 primop,手動傳遞 RealWorld token 時,感覺就像
推薦閱讀:
※Rust相較於Haskell有何優勢?
※Haskell 裡面的 Functor 是個什麼概念?
※怎樣學習 haskell 效率比較高?
※如何評價最新推出的 Glasgow Haskell Compiler (GHC) 8.0.1 版本?
※haskell中的immutable array是如何實現隨機訪問的?
TAG:Haskell |