/
History.elm
65 lines (49 loc) · 1.33 KB
/
History.elm
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
module History exposing (History, current, goBack, init, mapPush, peekBack, push)
{-| -}
{-| A linear undo history. Basically works like a list zipper but drops
items older than the retention limit.
-}
type History a
= History
{ retention : Int
, past : List a
, current : a
, future : List a
}
init : Int -> a -> History a
init retention initial =
History
{ retention = retention
, past = []
, current = initial
, future = []
}
current : History a -> a
current (History guts) =
guts.current
push : a -> History a -> History a
push a (History guts) =
History
{ guts
| past = List.take guts.retention (guts.current :: guts.past)
, current = a
, future = []
}
mapPush : (a -> a) -> History a -> History a
mapPush fn history =
push (fn (current history)) history
peekBack : History a -> Maybe a
peekBack (History guts) =
List.head guts.past
goBack : History a -> Maybe (History a)
goBack (History guts) =
case guts.past of
mostRecent :: rest ->
(Just << History)
{ guts
| past = rest
, current = mostRecent
, future = guts.current :: guts.future
}
[] ->
Nothing