do我在符號的背景關系中看到了很多 ST monad 的例子;但是,由于這不適合我的目的,因此我嘗試在執行緒newSTRef之外使用 ST monad 。modifySTRefdo
型別由 VSCode 的 HLS 自動添加。
ref :: ST s (STRef s Integer)
ref = newSTRef (1)
x :: ST s ()
x = modifySTRef ref 2
錯誤:ref在最后一行
Couldn't match expected type ‘STRef s a0’
with actual type ‘ST s0 (STRef s0 Integer)’
好吧,當然我可以看到錯誤說型別不匹配,但我不知道如何修復它。
ST Monad 的正確用法是do什么?
編輯:
我的目的do是
就像提到的那樣,
do它只是一種語法糖,我經常想避免它,以便以更直接的功能方式撰寫代碼。獲取可變物件的目的是為了開發FRP,單執行緒
ref中的順序定義和更新do對目的沒有用處。
uj5u.com熱心網友回復:
這里的問題是modifySTRef需要一個STRef s a,而不是一個ST s (STRef s a)。ST旨在利用 monad 屬性來保護可變操作不被濫用,因此所有修改只能在ST背景關系中發生。因此,您需要使用背景關系的力量來提取純STRef參考。
通常你會do這樣:
x :: ST s ()
x = do
refv <- ref
modifySTRef refv 2
但既然你想避免這種糖,你可以做正確的事情來減少糖:
x :: ST s ()
x = refv >>= \refv -> modifySTRef refv 2
您可以在此處閱讀有關該do符號及其解決方式的更多資訊
評論中的備注:請注意,您的代碼沒有這種方式的全域變數。每次在 ST 背景關系中呼叫它時都會newSTRef分配一塊新的 RAM 。因此,在這個例子中,實際上什么都不做(除了浪費一些記憶體和 GC 時間)。x
如果您打算保留參考,則必須將其“拿在手中”,例如放在ReaderT包裝紙中。
轉載請註明出處,本文鏈接:https://www.uj5u.com/shujuku/427296.html
標籤:哈斯克尔
