Reputation: 113
Background: I'm creating a game with a stateful monad for reading and writing changes to the global state of the game.
I would like to divide my game into components, such as "Characters", providing a domain specific way for these components to interact with the global state. Ideally this might be define specific actions of the form MonadState Character m => m a
that I could use, but each such m a
would enact changes on the parent (global state).
I've searched around for converting between state monads, or providing an interface from one state monad to another, but the specific language for this is beyond my scope of knowledge. I am also already using Lenses, and I'm wondering if I can do something with them.
EDIT:
I'd like to be able to do something like
moveCharacter :: MonadState Character m => Int -> Int -> m ()
and have that perform move :: MonadState World m => Int -> Int -> m ()
inside. Basically, abstracting the world specifics away from the character.
Thanks!
Upvotes: 1
Views: 96
Reputation: 1766
You actually need 2 conversion functions: one to extract the character from the world and another one to modify the world with the modified character. You can put them together like this:
extractCharacter :: World -> Character
extractCharacter = error "Tried to call placeholder function"
replaceCharacter :: World -> Character -> World
replaceCharacter = error "Tried to call placeholder function"
runCharacterSubroutine :: (Functor m) =>
StateT Character m a -> StateT World m a
runCharacterSubroutine act = StateT $ \w ->
fmap (\(a,c') -> (a,replaceCharacter w c')) $
runStateT act (extractCharacter w)
In your game, you probably want something a little more complicated, but that's just a matter of adding an extra parameter to extractCharacter
and replaceCharacter
Note that the function I gave only works if the StateT
is at the top of the monad transformer stack. If it's not: you will have to use the mmorph
package
Upvotes: 0
Reputation: 153182
Sounds like you're looking for Zoom
, which lets you convert a stateful action on the view of a lens into a stateful action on the source of the lens.
Upvotes: 3