-
Notifications
You must be signed in to change notification settings - Fork 0
Expand file tree
/
Copy pathListMap.roc
More file actions
134 lines (121 loc) · 3.23 KB
/
ListMap.roc
File metadata and controls
134 lines (121 loc) · 3.23 KB
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
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
module [
ListMap,
insert,
get,
map,
walk,
to_list,
from_list,
]
ListMap a b := {
count : U16,
list : List (Result (a, b) {}),
} where a implements Eq
implements [
Inspect {
to_inspector: list_map_to_inspector,
},
]
list_map_to_inspector : ListMap a b -> Inspector _ where a implements Eq & Inspect, b implements Inspect
list_map_to_inspector = |@ListMap(list_map)|
Inspect.to_inspector(list_map)
compaction_threshold : U16
compaction_threshold = 255
maybe_compact2 : List (Result (a, b) {}), U16 -> List (Result (a, b) {})
maybe_compact2 = |list, count|
if count > compaction_threshold then
List.keep_if(list, Result.is_ok)
else
list
maybe_compact : ListMap a b -> ListMap a b
maybe_compact = |@ListMap(list_map)|
if list_map.count > 255 then
@ListMap(
{
count: 0,
list: List.keep_if(list_map.list, Result.is_ok),
},
)
else
@ListMap(
{
count: list_map.count + 1,
list: list_map.list,
},
)
remove_entry_if_exists2 : List (Result (a, b) {}), a -> List (Result (a, b) {}) where a implements Eq
remove_entry_if_exists2 = |list, key|
List.drop_if(
list,
|result|
when result is
Ok((k, _)) -> k == key
Err(_) -> Bool.false,
)
insert : ListMap a b, a, b -> ListMap a b
insert = |@ListMap(list_map), key, value|
new_list =
list_map.list
|> remove_entry_if_exists2(key)
|> maybe_compact2(list_map.count)
|> List.append(Ok((key, value)))
@ListMap(
{
count: (
if list_map.count > compaction_threshold then
0
else
list_map.count + 1
),
list: new_list,
},
)
get : ListMap a b, a -> Result b {}
get = |@ListMap(list_map), key|
list_map.list
|> List.walk_until(
Err({}),
|_, result|
when result is
Err(_) -> Continue(Err {})
Ok((k, v)) ->
if k == key then
Break(Ok(v))
else
Continue(Err({})),
)
walk : ListMap a b, state, (state, a, b -> state) -> state
walk = |@ListMap(list_map), state, fn|
list_map.list
|> List.walk(
state,
|s, result|
when result is
Ok((k, v)) -> fn(s, k, v)
Err(_) -> s,
)
to_list : ListMap a b -> List (a, b)
to_list = |@ListMap(list_map)|
List.keep_oks(list_map.list, |result| result)
from_list : List (a, b) -> ListMap a b where a implements Eq
from_list = |list|
@ListMap(
{
count: 0,
list: List.map(list, |pair| Ok(pair)),
},
)
map : ListMap a b, (b -> c) -> ListMap a c
map = |@ListMap(list_map), fn|
@ListMap(
{
count: list_map.count,
list: List.map(
list_map.list,
|result|
when result is
Ok((k, v)) -> Ok((k, fn(v)))
Err({}) -> Err({}),
),
},
)