I'm somewhat new to Haskell and I'm having some trouble with the State monad.
I have created the following types.
Stat a
has a monoid, functor, applicative and monad instance created for it.
The "main" type in my program is creature and it has many arguments:
data Creature = Creature {
strength :: Stat Integer,
dexterity :: Stat Integer,
...
}
data Stat a = Stat {
modifiers :: [StatModifier],
stat :: a
}
data StatModifier = StatModifier {
modifierType :: ModifierType,
value :: Integer
}
data ModifierType =
Enhancement
| Morale
| ...
There are many things that can happen to a creature. I chose to represent those things with the state monad:
anyPossibleChange :: State Creature Creature
This could be damage being done to the creature, an increase to the creature's strength, basically anything. The possibility of anything made me think the State monad was a good choice here. I will accept a creature in it's original state, perform some modification, and return the original state and the new state in a tuple.
An original state might be:
Creature {
strength = Stat [] 10,
dexterity = Stat [] 10
}
An end state might be:
Creature {
strength = Stat [StatModifier Enhancement 2] 10,
dexterity = Stat [StatModifier Enhancement 4, StatModifier Morale 2] 10
}
I would like to build a list of all the changes a creature needs to go through and then run the creature through all of those changes.
This is the signature I had in mind, but I am having trouble coming up with an implementation. I am open to it being different.
applyChanges :: Creature -> [State Creature Creature] -> Creature
I feel like I should be able to do this with a fold, possibly FoldM
but my brain is getting hung up around the types.
What would a good implementation be?