Commit | Line | Data |
---|---|---|
a6244ba2 SK |
1 | -module(hope_list). |
2 | ||
3 | -export_type( | |
4 | [ t/1 | |
5 | ]). | |
6 | ||
7 | -export( | |
8 | [ unique_preserve_order/1 | |
c66ddf80 | 9 | , map_rev/2 |
2a81fbac | 10 | , map_slow/2 |
a6244ba2 SK |
11 | ]). |
12 | ||
13 | ||
14 | -type t(A) :: | |
15 | [A]. | |
16 | ||
17 | ||
2a81fbac SK |
18 | %% @doc lists:reverse(map_rev(L, F)) |
19 | %% @end | |
20 | -spec map_slow([A], fun((A) -> (B))) -> | |
21 | [B]. | |
22 | map_slow(Xs, F) -> | |
23 | lists:reverse(map_rev(Xs, F)). | |
24 | ||
25 | ||
c66ddf80 SK |
26 | %% @doc O(N), tail-recursive equivalent to lists:rev(lists:map(F, L)) |
27 | %% @end | |
28 | -spec map_rev([A], fun((A) -> (B))) -> | |
29 | [B]. | |
30 | map_rev(Xs, F) -> | |
31 | map_rev_acc(Xs, F, []). | |
32 | ||
33 | -spec map_rev_acc([A], fun((A) -> (B)), [B]) -> | |
34 | [B]. | |
35 | map_rev_acc([], _, Ys) -> | |
36 | Ys; | |
37 | map_rev_acc([X|Xs], F, Ys) -> | |
38 | Y = F(X), | |
39 | map_rev_acc(Xs, F, [Y|Ys]). | |
40 | ||
41 | ||
a6244ba2 SK |
42 | -spec unique_preserve_order(t(A)) -> |
43 | t(A). | |
44 | unique_preserve_order(L) -> | |
17b5d686 | 45 | PrependIfNew = |
a6244ba2 SK |
46 | fun (X, Xs) -> |
47 | case lists:member(X, Xs) | |
17b5d686 SK |
48 | of true -> Xs |
49 | ; false -> [X | Xs] | |
a6244ba2 SK |
50 | end |
51 | end, | |
17b5d686 | 52 | lists:reverse(lists:foldl(PrependIfNew, [], L)). |