Skip to content

Instantly share code, notes, and snippets.

@yamasushi
Last active July 12, 2019 07:57
Show Gist options
  • Select an option

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

Select an option

Save yamasushi/65b93369fed6c056470ee6e88974be55 to your computer and use it in GitHub Desktop.
%% Erlang Programming(Francesco Cesarini & Simon Thompson)
%% P.197, Lazy Evaluation and Lists
%% https://gist.github.com/yamasushi/65b93369fed6c056470ee6e88974be55
-module(lseq).
-compile(export_all).
%% for test
dump(Lseq) ->
lseq:foreach(fun (X)->io:format("~w~n",[X]) end, Lseq).
dump(N, Lseq) -> dump(take(N, Lseq)).
fib() ->
iterate(fun({I1,I2}) ->
I3 = I1+I2,
{I3,{I2,I3}} end , {0,1}).
%%
seq(N) -> seq(N, 1).
seq(N, I) ->
fun() -> [N|seq(N+I, I)] end.
lseq_to_list(Lseq)->
lists:reverse(foldl(fun(X, A)-> [X|A] end, [], Lseq)).
list_to_lseq([])->[];
list_to_lseq([H|T])->
fun()-> [H|list_to_lseq(T)] end.
%% iterator
%% fun (State) -> {Value, NewState}
iterate(F, State) ->
%%io:format("State=~p, F(State)=~p~n",[State, F(State)]),
{Value, NewState} = F(State),
fun() -> [Value|iterate(F, NewState)] end.
%%
drop(0, Lseq) -> Lseq;
drop(N, Lseq) ->
[_|T] = Lseq(),
drop(N-1, T).
take(0, _Lseq) -> [];
take(N, Lseq) ->
[H|T] = Lseq(),
fun() ->
[H|take(N-1,T)] end.
dropwhile(_P, []) -> [];
dropwhile(P, Lseq) ->
[H|T] = Lseq(),
case P(H) of
true -> dropwhile(P, T);
_ -> fun() -> [H|T] end
end.
takewhile(_P, []) -> [];
takewhile(P, Lseq) ->
[H|T] = Lseq(),
case P(H) of
true ->
fun() -> [H|takewhile(P, T)] end;
_ -> []
end.
append([]) -> [];
append([[]|Tseqs]) -> append(Tseqs);
append([Hseq|Tseqs]) ->
[H|T] = Hseq(),
fun() -> [H|append([T|Tseqs])] end.
append([], Lseq2) -> Lseq2;
append(Lseq1, Lseq2) ->
[H|T] = Lseq1(),
fun() -> [H|append(T,Lseq2)] end.
map(_F, []) -> [];
map(F, Lseq) ->
[H|T] = Lseq(),
fun() ->
[F(H)|map(F, T)] end.
filter(_P, []) -> [];
filter(P, Lseq) ->
[H|T] = Lseq(),
case P(H) of
true -> fun() -> [H|filter(P, T)] end;
_ -> filter(P, T)
end.
zip(L1, L2) -> zipwith(fun(X, Y)-> {X, Y} end, L1, L2).
zip3(L1, L2, L3) -> zipwith3(fun(X, Y, Z)->{X, Y, Z} end, L1, L2, L3).
zipwith(_Combine,[], []) -> [];
zipwith(_Combine,_ , []) -> [];
zipwith(_Combine,[], _) -> [];
zipwith(Combine,Lseq1, Lseq2) ->
[H1|T1] = Lseq1(),
[H2|T2] = Lseq2(),
fun() ->
[Combine(H1, H2) |zipwith(Combine, T1, T2)] end.
zipwith3(_Combine,[], [], []) -> [];
zipwith3(_Combine,_ , [], []) -> [];
zipwith3(_Combine,[], _, []) -> [];
zipwith3(_Combine,_ , _, []) -> [];
zipwith3(_Combine,[], [], _) -> [];
zipwith3(_Combine,_ , [], _) -> [];
zipwith3(_Combine,[], _, _) -> [];
zipwith3(Combine,Lseq1, Lseq2, Lseq3) ->
[H1|T1] = Lseq1(),
[H2|T2] = Lseq2(),
[H3|T3] = Lseq3(),
fun() ->
[Combine(H1, H2, H3) |zipwith3(Combine, T1, T2, T3)] end.
foreach(_F, []) ->
ok;
foreach(F, Lseq) ->
[H|T] = Lseq(),
F(H),
foreach(F,T).
foldl(_F, Acc, []) -> Acc;
foldl(F, Acc, Lseq) ->
[H|T] = Lseq(),
foldl(F, F(H, Acc), T).
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment