Я пытаюсь написать небольшую игру на Haskell, и мне нужно передать изрядное количество состояний. . Я хочу попробовать скрыть состояние с помощью монады State
Теперь я столкнулся с проблемой: функции, которые принимают состояние и аргумент, было легко написать для работы в монаде состояния. Но есть также функции, которые просто принимают состояние в качестве аргумента (и возвращают измененное состояние или, возможно, что-то еще).
В одной части моего кода есть такая строка:
let player = getCurrentPlayer state
Я бы хотел, чтобы она не принимала состояние, а вместо этого писала
player <- getCurrentPlayerM
в настоящее время ее реализация выглядит так
getCurrentPlayer gameState =
(players gameState) ! (on_turn gameState)
и она казалась достаточно простой, чтобы сделать он работает в монаде State, записав это следующим образом:
getCurrentPlayerM = do state <- get
return (players state ! on_turn state)
Однако это вызывает жалобы со стороны ghc! Нет экземпляра для (MonadState GameState m0), возникающего из-за использования `get', говорится в нем. Я уже переписал очень похожую функцию, за исключением того, что она не была nullary в своей форме монады State, поэтому по наитию я переписал ее так:
getCurrentPlayerM _ = do state <- get
return (players state ! on_turn state)
И действительно, она работает! Но, конечно, я должен называть это как getCurrentPlayerM(), и я чувствую себя немного глупо, делая это.В первую очередь я хотел избежать спора!
Дополнительный сюрприз: просматривая его тип в ghci, я получаю
getCurrentPlayerM :: MonadState GameState m => t -> m P.Player
, но если я пытаюсь установить это явно в своем коде, я получаю другую ошибку: «Аргумент, не зависящий от типа, в ограничении MonadState GameState m» и предложение расширения языка, чтобы разрешить это. Я полагаю, это потому, что мой GameState является типом, а не классом типов, но почему он принят на практике, но не тогда, когда я пытаюсь сказать об этом явно, я больше запутался.
Подводя итог: