У меня есть следующая функция для обхода «краев» «графика» моего игрового мира. Это меняет состояние мира - в частности, местоположение игрока. Мне нужно сообщить сообщение, предупреждающее игрока об их изменении в локации.
Так что я могу либо вернуть кортеж (message, newWorld), либо использовать монаду State. (Верно? Я новичок в этом деле.)
Вот моя попытка монадного подхода:
walk dir = do
world <- get
let attempt = filter (\e -> edgeDirection e == dir) $ edges
edges = (worldEdges world) M.! playerLoc
playerLoc = playerLocation $ worldPlayer world
case attempt of
[] -> return "You can't go that way."
(edge : _) -> do
put world'
return message
where world' = world { worldPlayer = player' }
player' = (worldPlayer world) { playerLocation = loc }
loc = edgeLocation edge
message = "You go " ++ (downcase $ show dir)
Дело в том, что теперь функция, которую вызывает walk
, должна иметь дело с монадой состояний. Должен ли я runState
сделать это прямо здесь, или у меня эта функция тоже использует монады состояний, например:
parseWalk dir =
let direction = case dir of
('e' : _) -> Just East
('n' : _) -> Just North
('s' : _) -> Just South
('w' : _) -> Just West
('u' : _) -> Just Up
('d' : _) -> Just Down
_ -> Nothing
in case direction of
Just d -> walk d
Nothing -> return "You can't go that way"
Тогда как насчет абонента parseWalk
и так далее? Должен ли я стараться, чтобы эта государственная монада проходила как можно дольше? Должен ли я видеть много MonadState ...
в моих сигнатурах?