Estoy tratando de escribir un pequeño juego en Haskell, y hay una buena cantidad de estado necesario para pasar. Quiero tratar de ocultar el estado con la mónada de estadoUsando la mónada de estado para ocultar el estado explícito
Ahora me he encontrado con un problema: las funciones que toman el estado y un argumento eran fáciles de escribir para trabajar en la mónada de estado. Pero también hay funciones que simplemente toman el estado como argumento (y devuelven un estado modificado, o posiblemente algo más).
En una parte de mi código, tengo esta línea:
let player = getCurrentPlayer state
me gustaría que no toma estado, y en lugar de escribir
player <- getCurrentPlayerM
Actualmente, su puesta en práctica se parece a esto
getCurrentPlayer gameState =
(players gameState) ! (on_turn gameState)
y parecía lo suficientemente simple como para que funcione en la mónada de estado escribiéndola así:
getCurrentPlayerM = do state <- get
return (players state ! on_turn state)
Sin embargo, eso provoca quejas de ghc! No hay instancia para (MonadState GameState m0) que surja de un uso de `get ', dice. Yo ya había vuelto a escribir una función muy similar, excepto que no se nularia en su forma mónada Estado, por lo que en una corazonada, Reescribí así:
getCurrentPlayerM _ = do state <- get
return (players state ! on_turn state)
y, efectivamente, funciona! Pero, por supuesto, tengo que llamarlo getCurrentPlayerM(), y me siento un poco tonto al hacerlo. ¡Pasar una discusión era lo que quería evitar en primer lugar!
Una sorpresa adicional: mirando su tipo en ghci consigo
getCurrentPlayerM :: MonadState GameState m => t -> m P.Player
pero si trato de establecer que de forma explícita en mi código, me sale otro error: "El argumento para no tipo variable en la restricción MonadState GameState m "y una oferta de extensión de idioma para permitirlo. Supongo que es porque mi GameState es un tipo y no una clase de tipo, pero por qué se acepta en la práctica, pero no cuando trato de ser explícito al respecto. Estoy más confundido.
Para resumir:
- Por qué no puedo escribir funciones nullary en la mónada Estado?
- ¿Por qué no puedo declarar el tipo que tiene mi función de solución alternativa?
Explicar explícitamente qué mónada quiero parece ser la solución correcta en mi caso. Sí, ya me encontré con el problema con los registros dentro de los registros, y leí un poco sobre Lentes (entre otras cosas, cuando busqué la respuesta aquí, ¡parece que me recomiendan mucho!). Gracias, excelentes explicaciones! –