Использование монады состояния для сокрытия явного состояния.

Я пытаюсь написать небольшую игру на 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 является типом, а не классом типов, но почему он принят на практике, но не тогда, когда я пытаюсь сказать об этом явно, я больше запутался.

Подводя итог:

  1. Почему я не могу писать нульарные функции в монаде State?
  2. Почему я не могу объявить тип моей обходной функции?
10
задан Harald Korneliussen 2 June 2012 в 21:08
поделиться