This is a Haskell style question.
As an example of a tutorial, I created a small program that supports operations undoand redo. It uses a data structure with two stacks.
data History a = History [a] [a]
The first stack is the story of, say, a game. The second stack holds the states that were selected undo. So
undo (History (x:xs) redoStack) = History xs (x:redoStack)
undo history = history -- in case there is nothing to undo
and
redo (History hStack (x:redoStack)) = History (x:hStack) redoStack
redo history = history -- in case there is nothing to redo
There is also a general operation that applies the change to the current state.
applyAChange change (History (x:xs) _) = History ((change x):x:xs) []
Type applyAChange-
applyAChange :: (a -> a) -> History a -> History a
I decided to determine the type Change:
type Change a = a -> a
Then the type applyAChangebecomes
applyAChange :: Change a -> Change (History a)
This seemed useful, and I used the type Changeelsewhere in the code.
In the String instance definition , I found that I defined a series of functions with types such as:
convertASomethingToString :: Something -> String
So, I determined the type ToString
type ToString a = a -> String
convertASomethingToString :: ToString <Something>
, .
.