我想在Haskell寫一個小遊戲,並且有相當數量的狀態需要傳遞。我想嘗試隱藏狀態monad使用狀態monad隱藏顯式狀態
現在我遇到了一個問題:功能,採取國家和一個參數很容易寫入工作在狀態單子。但也有一些函數只是將狀態作爲參數(並返回一個修改的狀態,或者可能是其他的)。
在我的代碼的一部分,我有這樣一行:
let player = getCurrentPlayer state
我想它不會採取狀態,而不是寫
player <- getCurrentPlayerM
目前,它的實現看起來像這樣
getCurrentPlayer gameState =
(players gameState) ! (on_turn gameState)
它似乎很簡單,使它在國家單體中的工作,通過這樣寫:
getCurrentPlayerM = do state <- get
return (players state ! on_turn state)
然而,這引起ghc的投訴!它說,沒有使用「get」引起的(MonadState GameState m0)實例。我已經重寫了非常相似的功能,但並不是在其國家單子形式無參,等等預感,我重寫這樣的:
getCurrentPlayerM _ = do state <- get
return (players state ! on_turn state)
果然,它的工作原理!但我當然必須將其稱爲getCurrentPlayerM(),並且我覺得這樣做有點愚蠢。傳遞一個論點是我首先想避免的!
一個額外的驚喜:在ghci中尋找它的類型,我得到
getCurrentPlayerM :: MonadState GameState m => t -> m P.Player
,但如果我嘗試設置,明確在我的代碼,我得到另一個錯誤:「非類型變量參數的約束MonadState GameState m「並提供語言擴展以允許它。我想這是因爲我的GameState是一個類型而不是一個類型類,但是爲什麼它在實踐中被接受了,但是當我嘗試對它進行明確的時候我並沒有更加困惑。
所以總結起來:
- 爲什麼我不能寫在單子國家職能零元?
- 爲什麼我不能聲明我的解決方法函數實際上具有的類型?
明確說明我想要哪個monad似乎是正確的解決方案。是的,我已經遇到了記錄中的記錄問題,並且讀了一些關於Lenses的內容(其中包括我在這裏搜索答案的時候,它似乎被推薦了很多!)。謝謝,優秀的解釋! –