1 |
|
-module(klsn_maybe). |
2 |
|
|
3 |
|
-export([ |
4 |
|
get_value/1 |
5 |
|
, get_value/2 |
6 |
|
, filtermap/2 |
7 |
|
]). |
8 |
|
|
9 |
|
%% A small helper module for working with the *Maybe* pattern |
10 |
|
%% ({value, V} | none) that is defined in the klsn module itself. The functions |
11 |
|
%% mirror common operations from the Haskell Maybe / Rust Option |
12 |
|
%% family while keeping the interface idiomatic Erlang. |
13 |
|
|
14 |
|
-export_type([ |
15 |
|
]). |
16 |
|
|
17 |
|
%% @doc |
18 |
|
%% Extract the wrapped value or raise badarg when *None* is supplied. |
19 |
|
-spec get_value({value, Value}) -> Value. |
20 |
|
get_value({value, Value}) -> |
21 |
1 |
Value; |
22 |
|
get_value(None) -> |
23 |
1 |
erlang:error(badarg, [None]). |
24 |
|
|
25 |
|
%% @doc |
26 |
|
%% Return the contained value when present, otherwise return *Default*. |
27 |
|
-spec get_value |
28 |
|
({value, Value}, Default::any()) -> Value; |
29 |
|
(none, Default) -> Default. |
30 |
|
get_value({value, Value}, _Default) -> |
31 |
3 |
Value; |
32 |
|
get_value(none, Default) -> |
33 |
3 |
Default; |
34 |
|
get_value(Arg1, Arg2) -> |
35 |
1 |
erlang:error(badarg, [Arg1, Arg2]). |
36 |
|
|
37 |
|
|
38 |
|
%% @doc |
39 |
|
%% Combine filtering and mapping in one pass. When the callback returns |
40 |
|
%% {value, V} the element is kept (and V becomes the new value); |
41 |
|
%% returning none discards the element. |
42 |
|
-spec filtermap(fun((any())->klsn:'maybe'(any())), list()) -> list(); |
43 |
|
(fun((any(), any())->klsn:'maybe'(any())), map()) -> map(). |
44 |
|
filtermap(Fun, List) when is_list(List) -> |
45 |
1 |
lists:filtermap(fun(Val) -> |
46 |
9 |
case Fun(Val) of |
47 |
|
{value, Value} -> |
48 |
4 |
{true, Value}; |
49 |
|
none -> |
50 |
5 |
false |
51 |
|
end |
52 |
|
end, List); |
53 |
|
filtermap(Fun, Map) when is_map(Map) -> |
54 |
1 |
maps:filtermap(fun(Key, Val) -> |
55 |
9 |
case Fun(Key, Val) of |
56 |
|
{value, Value} -> |
57 |
4 |
{true, Value}; |
58 |
|
none -> |
59 |
5 |
false |
60 |
|
end |
61 |
|
end, Map). |