-module(funs1).
-compile(export_all).
-import(lists, [reverse/1]).
%1
map(F, [H|T]) -> [F(H)|map(F, T)];
map(F, []) -> [].
%1
%2
foreach(F, [H|T]) ->
F(H),
foreach(F, T);
foreach(F, []) ->
ok.
%2
%
%3
all(Pred, [H|T]) ->
case Pred(H) of
true -> all(Pred, T);
false -> false
end;
all(Pred, []) ->
true.
%3
%4
any(Pred, [H|T]) ->
case Pred(H) of
true -> true;
false -> any(Pred, T)
end;
any(Pred, []) ->
false.
%4
%5
takewhile(Pred, [H|T]) ->
case Pred(H) of
true -> [H|takewhile(Pred, T)];
false -> []
end;
takewhile(Pred, []) ->
[].
%5
%6
dropwhile(Pred, [H|T]) ->
case Pred(H) of
true -> dropwhile(Pred, T);
false -> [H|T]
end;
dropwhile(Pred, []) ->
[].
%6
%7
splitwith(Pred, L) ->
splitwith(Pred, L, []).
splitwith(Pred, [H|T], L) ->
case Pred(H) of
true -> splitwith(Pred, T, [H|L]);
false -> {reverse(L), [H|T]}
end;
splitwith(Pred, [], L) ->
{reverse(L), []}.
%7
flatmap(F, [Hd|Tail]) ->
F(Hd) ++ flatmap(F, Tail);
flatmap(F, []) -> [].
%8
foldl(F, Accu, [Hd|Tail]) ->
foldl(F, F(Hd, Accu), Tail);
foldl(F, Accu, []) -> Accu.
%8
%
foldr(F, Accu, [Hd|Tail]) ->
F(Hd, foldr(F, Accu, Tail));
foldr(F, Accu, []) -> Accu.
%9
filter(F, [H|T]) ->
case F(H) of
true -> [H|filter(F, T)];
false -> filter(F, T)
end;
filter(F, []) -> [].
%9
%10
mapfoldl(F, Accu0, [Hd|Tail]) ->
{R,Accu1} = F(Hd, Accu0),
{Rs,Accu2} = mapfoldl(F, Accu1, Tail),
{[R|Rs], Accu2};
mapfoldl(F, Accu, []) -> {[], Accu}.
%10
mapfoldr(F, Accu0, [Hd|Tail]) ->
{Rs,Accu1} = mapfoldr(F, Accu0, Tail),
{R,Accu2} = F(Hd, Accu1),
{[R|Rs],Accu2};
mapfoldr(F, Accu, []) -> {[], Accu}.
%11
first(Pred, [H|T]) ->
case Pred(H) of
true ->
{true, H};
false ->
first(Pred, T)
end;
first(Pred, []) ->
false.
%11
%
compose(F, G) ->
fun(X) ->
F(G(X))
end.
%20
iterate(N, F) ->
iterate(N, N+1, F).
iterate(Stop, Stop, _) ->
[];
iterate(N, Stop, Fun) ->
[Fun(N)|iterate(N+1, Stop, Fun)].
%20