Skip to content

Instantly share code, notes, and snippets.

@yamasushi
Last active July 15, 2019 21:48
Show Gist options
  • Select an option

  • Save yamasushi/b051d2ee88cfaa04dddc0fd2e05db01b to your computer and use it in GitHub Desktop.

Select an option

Save yamasushi/b051d2ee88cfaa04dddc0fd2e05db01b to your computer and use it in GitHub Desktop.
%% Erlang Programming(Francesco, Cesarini & Simon Thompson)
%% p.212, Exercise 9-5: Existing High-Order Functions
%% https://gist.github.com/yamasushi/b051d2ee88cfaa04dddc0fd2e05db01b
-module(hof).
-compile(export_all).
all(_P, []) -> true;
all(P, [H|T]) -> P(H) and all(P, T).
any(_P, []) -> false;
any(P, [H|T]) -> P(H) or any(P, T).
dropwhile(_P, []) -> [];
dropwhile(P, [H|T]=L) ->
case P(H) of
true -> dropwhile(P, T);
_ -> L
end.
filter(_P, []) -> [];
filter(P, [X|Xs]) ->
case P(X) of
true ->
[X|filter(P,Xs)];
_ ->
filter(P,Xs)
end.
filtermap(_P, []) -> [];
filtermap(P, [H|T]) ->
case P(H) of
false -> filtermap(P, T);
true -> [H|filtermap(P, T)];
{true, V} -> [V|filtermap(P, T)]
end.
flatmap(_F, []) -> [];
flatmap(F, [H|T]) ->
lists:append( F(H) , flatmap(F, T) ).
foldl(_F, A, []) -> A;
foldl(F, A, [H|T]) ->
foldl(F, F(H, A), T).
foldr(_F, A, []) -> A;
foldr(F, A, [H|T]) ->
F(H, foldr(F, A, T)).
foreach(_F, []) ->
ok;
foreach(F, [X|Xs]) ->
F(X),
foreach(F, Xs).
keymap(_F, _N, [] ) -> [];
keymap(F, N, [H|T] ) when is_tuple(H) ->
K = element(N, H),
[ setelement(N, H, F(K)) | keymap(F, N, T)].
map(_F, []) -> [];
map(F, [X|Xs]) ->
[F(X)|map(F,Xs)].
mapfoldl(Fun, Acc, List)->
mapfoldl_acc(Fun, List, [], Acc).
mapfoldl_acc(_F ,[] ,L ,A)-> {lists:reverse(L), A};
mapfoldl_acc(F, [H|T], L, A) ->
{MappedH, NewA} = F(H, A),
mapfoldl_acc(F, T, [MappedH|L], NewA).
mapfoldr(Fun, Acc, List) ->
mapfoldr_acc(Fun, lists:reverse(List), [], Acc).
mapfoldr_acc(_F ,[] ,L ,A) -> {L, A};
mapfoldr_acc(F, [H|T], L, A) ->
{MappedH, NewA} = F(H, A),
mapfoldr_acc(F, T, [MappedH|L], NewA).
partition(P, L) -> partition_acc(P, L, [], []).
partition_acc(_P, [], L,K) ->
{lists:reverse(L), lists:reverse(K)};
partition_acc(P, [H|T], L, K) ->
case P(H) of
true -> partition_acc(P, T, [H|L], K);
_ -> partition_acc(P, T, L, [H|K])
end.
search(_P, []) -> false;
search(P, [H|T]) ->
case P(H) of
true -> {value, H};
_ -> search(P, T)
end.
splitwith(P, L)-> splitwith_acc(P, [], L).
splitwith_acc(_P ,Left ,[]) -> {lists:reverse(Left),[]};
splitwith_acc(P, Left, [H|T]=Right) ->
case P(H) of
true ->
splitwith_acc(P, [H|Left], T);
_ -> {lists:reverse(Left), Right}
end.
takewhile(_P, []) -> [];
takewhile(P, [H|T]) ->
case P(H) of
true ->
[H|takewhile(P, T)];
_ -> []
end.
zipwith(_F, [], [] ) ->[];
zipwith(F, [X|Xs], [Y|Ys]) -> [F(X, Y) | zipwith(F, Xs, Ys)].
zipwith3(_F, [], [], []) ->[];
zipwith3(F, [X|Xs], [Y|Ys], [Z|Zs]) -> [F(X, Y, Z) | zipwith3(F, Xs, Ys, Zs)].
%% --------
sort(Fun, List) ->
qsort(Fun, List).
qsort(_F, []) -> [];
qsort(F, [H|T]) ->
qsort(F, [X|| X <- T, F(X, H)]) ++
[H] ++ qsort(F, [X|| X <- T, F(H, X)]).
usort(Fun, List) ->
uqsort(Fun, List).
uqsort(_F, []) -> [];
uqsort(F, [H|T]) ->
uqsort(F, [X|| X <- T, F(X, H), X=/=H] ) ++
[H] ++ uqsort(F, [X|| X <- T, F(H, X) , X=/=H ]).
merge(F, L1, L2) -> merge_acc(F, L1, L2, []).
merge_acc(_F, [], L2, A) -> lists:append( lists:reverse(A), L2);
merge_acc(_F, L1, [], A) -> lists:append( lists:reverse(A), L1);
merge_acc(F, [H1|T1]=L1, [H2|T2]=L2, A) ->
case F(H1, H2) of
true -> merge_acc(F, T1, L2, [H1|A]);
_ -> merge_acc(F, L1, T2, [H2|A])
end.
umerge(F, L1, L2) -> umerge_acc(F, L1, L2, []).
umerge_acc(_F, [], L2, A) -> lists:append( lists:reverse(A), L2);
umerge_acc(_F, L1, [], A) -> lists:append( lists:reverse(A), L1);
umerge_acc(F, [H1|T1]=L1, [H2|T2]=L2, A) ->
if
H1 == H2 ->
umerge_acc(F, T1, T2 ,[H1|A]);
true ->
case F(H1, H2) of
true -> umerge_acc(F, T1, L2, [H1|A]);
_ -> umerge_acc(F, L1, T2, [H2|A])
end
end.
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment