2013-10-18 58 views
2

我想實現把與修改哈斯克爾MonadState工具把與修改

put :: s -> m() 
    modify :: (s -> s) m s 

當我這樣做

put s = modify $ const((), s) 

我得到的錯誤,
預期類型:M()
實際類型:m((),s)
我試過類似的東西

modify $ const((), s) >>= \x -> return (fst x) 

獲得預期的M型()
但這種方法行不通

可能有人向我解釋如何通過使用修改工具放?
謝謝你的時間和幫助。

回答

3

modify具有類型

modify :: (MonadState s m) => (s -> s) -> m() 

第一個參數是一個純s -> s函數修改的狀態。所以,當你試圖使用const在正確的軌道上,你不必把狀態在一個元組:

put s = modify $ const s 

需要注意的是,當你可以在modify來定義put ,這意味着您將無法給出modify的一般定義;相反,您必須爲每個具體的monad(MonadState的實例)執行此操作。這解釋了爲什麼在Control.Monad.State,getputMonadState的類方法:您如何實現它們取決於特定的狀態monad。然後,根據getput來定義。

+0

感謝您的回覆, 我應該如何使用put和get來實現修改。 你的put實現似乎不適用於我的修改實現。 我執行的修改是修改f = do {x < - get; put(f x)} – BARJ

+0

你的'modify'的實現是正確的,但它是通過'get'和'put'完成的。所以如果你試圖用'modify'實現'put',它就變成了循環。你正在實現一個特定的狀態monad的方法,還是你正在試圖編寫一般的實現? – duplode

+0

@Neckronis我更新了答案,以使這一點更清晰。它有幫助嗎? – duplode