I wanted to try something new, so I've decided to wrap my head around Haskell. Coming from a mainly C#/Java background, I have a question about updating various values. I've managed to narrow it down to a single problem. Consider the following function:
appendHistory :: State -> Action -> State
appendHistory (State gs p1 p2 h) a = State gs p1 p2 (a : h)
This basically appends the action to the state's history. gs
, p1
and p2
are rather irrelevant in this case, since we're trying to update h
. For the sake of copying the variables they need to be named (so I can use them on the right hand side of =
). Is there any way I can write appendHistory
, so that h
gets updated without having to specify gs
, p1
and p2
explicitly?
One option would be to let other functions handle retrieving and updating state. appendHistory
now doesn't have to specify the other parameters. Not my faviorite, as we've just moved our problem to updateHistory
. In Haskell:
appendHistory :: State -> Action -> State
appendHistory s a = updateHistory s (a : (history s))
history :: State -> History
history (State _ _ _ h) = h
updateHistory :: State -> History -> State
updateHistory (State s p1 p2 _) h = State s p1 p2 h
Another way would be to use records. But I've been told (/read) that name clashes might occur when using the same names. I think I'm going to have a lot of records with fieldname state
, so I've been avoiding those for the moment.
I guess, all I want to do is (non-functionally):
void Update(State state, Action action) {
state.history.append(action);
}
Is there a way to do this 'nicely' in Haskell, without having to write a 'getter' and a 'setter' for every data
parameter?
For full reference:
type History = [Action]
type Deck = [Card]
type Hand = [Card]
type Graveyard = [Card]
data Card = Card -- Still to expand
data PlayerState = PlayerState Hand Deck Graveyard
data GameState = NotStarted | Playing | Finished
data State = State GameState PlayerState PlayerState History
Action
s are just definitions on how to mutate State
.