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 | ||
5e20a667 SK |
26 | %% @doc Tail-recursive alternative to lists:map/2, which accumulates and |
27 | %% returns list in reverse order. | |
c66ddf80 SK |
28 | %% @end |
29 | -spec map_rev([A], fun((A) -> (B))) -> | |
30 | [B]. | |
31 | map_rev(Xs, F) -> | |
32 | map_rev_acc(Xs, F, []). | |
33 | ||
34 | -spec map_rev_acc([A], fun((A) -> (B)), [B]) -> | |
35 | [B]. | |
36 | map_rev_acc([], _, Ys) -> | |
37 | Ys; | |
38 | map_rev_acc([X|Xs], F, Ys) -> | |
39 | Y = F(X), | |
40 | map_rev_acc(Xs, F, [Y|Ys]). | |
41 | ||
42 | ||
a6244ba2 SK |
43 | -spec unique_preserve_order(t(A)) -> |
44 | t(A). | |
45 | unique_preserve_order(L) -> | |
17b5d686 | 46 | PrependIfNew = |
a6244ba2 SK |
47 | fun (X, Xs) -> |
48 | case lists:member(X, Xs) | |
17b5d686 SK |
49 | of true -> Xs |
50 | ; false -> [X | Xs] | |
a6244ba2 SK |
51 | end |
52 | end, | |
17b5d686 | 53 | lists:reverse(lists:foldl(PrependIfNew, [], L)). |