UndoList Data Structure.
If the undolist has any past states, set the most recent past state as the current state and turn the old present state into a future state.
i.e.
undo (UndoList [ 3, 2, 1 ] 4 [ 5, 6 ]) --> UndoList [ 2, 1 ] 3 [ 4, 5, 6 ]If the undo-list has any future states, set the next future state as the current state and turn the old present state into a past state.
i.e.
redo (UndoList [ 3, 2, 1 ] 4 [ 5, 6 ]) --> UndoList [ 4, 3, 2, 1 ] 5 [ 6 ]Turn a state into an undo-list with neither past nor future.
Add a new present state to the undo-list, turning the old present state into a past state and erasing the future.
Forget the past and look to the future! This simply clears the past list.
i.e.
forget (UndoList [3,2,1] 4 [5,6]) --> UndoList [] 4 [5,6]Reset the undo-list by returning to the very first state and clearing all other states.
i.e.
reset (UndoList [ 3, 2, 1 ] 4 [ 5, 6 ]) --> UndoList [] 1 []Check if the undo-list has any past states.
hasPast (UndoList [] 1 []) --> False
hasPast (UndoList [ 1, 2, 3 ] 4 []) --> TrueCheck if the undo-list has any future states.
hasFuture (UndoList [] 1 []) --> False
hasFuture (UndoList [] 1 [ 2, 3, 4 ]) --> TrueGet the full length of an undo-list
length (UndoList [ 0 ] 1 [ 2, 3, 4 ]) --> 5Get the length of the past.
lengthPast (UndoList [ 0 ] 1 [ 2, 3, 4 ]) --> 1Get the length of the future
lengthFuture (UndoList [ 0 ] 1 [ 2, 3, 4 ]) --> 3Simple UndoList Msg type. This is a simple type that can be used for
most use cases. This works best when paired with the update function as
update will perform the corresponding operations on the undolist automatically.
Consider using your own data type only if you really need it.
Map a function over a msg.
mapMsg sqrt (New 100) --> New 10
mapMsg sqrt Undo --> UndoMap a function over an undo-list.
Be careful with this. The function will be applied to the past and the future
as well. If you just want to change the present, use mapPresent.
A good use case for map is to encode an undo-list as JSON.
Example:
import UndoList.Encode as Encode
encode encoder undolist =
map encoder undolist
|> Encode.undolistApply a function only to the present.
Convert a function that updates the state to a function that updates an undo-list. This is very useful to allow you to write update functions that only deal with the individual states of your system and treat undo/redo as an add on.
Example:
-- Your update function
update msg state =
case msg of
... -- some implementation
-- Your new update function
updateWithUndo = UndoList.update updateConnect two undo-lists end to end. The present of the first undolist is considered the present of the output undolist.
Alias for foldl
Reduce an undo-list from the left (or from the past)
Reduce an undo-list from the right (or from the future)
Reverse an undo-list.
Flatten an undo-list of undo-lists into a single undo-list.
Map over an undo-list and then flatten the result.
Chain undo-list operations. This is simply an alias of flatMap
Map a function over a pair of undo-lists.
Map a function over any number of undo-lists.
map f xs
|> andMap ys
|> andMap zsFunction to help not having to deal with the full undolist from with your actual view function.
Suppose you define the following:
initial : model
update : msg -> model -> model
view : model -> Html (UndoList.Msg msg)Then, you could construct the main function as follows:
main =
Html.beginnerProgram
{ model = UndoList.fresh initial
, update = UndoList.update update
, view = UndoList.view view
}Convert an undo-list to a list :
toList (UndoList [ 3, 2, 1 ] 4 [ 5, 6 ]) --> [ 1, 2, 3, 4, 5, 6 ]Convert a list to undolist. The provided state is used as the present state and the list is used as the future states.
fromList 1 [ 2, 3, 4 ] --> UndoList [] 1 [ 2, 3, 4 ]
The UndoList data structure. An UndoList has:
The head of the past list is the most recent state and the head of the future list is the next state. (i.e., the tails of both lists point away from the present)