Created
March 19, 2017 01:21
-
-
Save mjstrasser/440cbcf7294e1ca0718cfc8ab897d97f to your computer and use it in GitHub Desktop.
Higher-order functions in practice from Functional Programming in Erlang MOOC
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
-module(zipper). | |
-compile(compile_all). | |
-include_lib("eunit/include/eunit.hrl"). | |
%% Tail-recursive implementation of zip/2 | |
%% that combines items into 2-tuples. | |
zip(Xs, Ys) -> lists:reverse(zip(Xs, Ys, [])). | |
% Stop when either list finishes. | |
zip([], _, Zs) -> Zs; | |
zip(_, [], Zs) -> Zs; | |
zip([X|Xs], [Y|Ys], Zs) -> | |
zip(Xs, Ys, [{X,Y} | Zs]). | |
% Simple tests. | |
zip_test() -> | |
?assertEqual([], zip([], [3,4])), | |
?assertEqual([], zip([1,2], [])), | |
?assertEqual([{1,3},{2,4}], zip([1,2],[3,4])). | |
%% Tail-recursive implementation of zip_with/3. | |
zip_with(F, Xs, Ys) -> | |
lists:reverse(zip_with(F, Xs, Ys, [])). | |
% Stop when either list finishes. | |
zip_with(_, _, [], Zs) -> Zs; | |
zip_with(_, [], _, Zs) -> Zs; | |
zip_with(F, [X|Xs], [Y|Ys], Zs) -> | |
zip_with(F, Xs, Ys, [F(X,Y) | Zs]). | |
% Simple tests. | |
tup2(X,Y) -> {X,Y}. | |
sum(X,Y) -> X+Y. | |
zip_with_test() -> | |
?assertEqual([{1,3},{2,4}], zip_with(fun tup2/2, [1,2], [3,4])), | |
?assertEqual([4,6], zip_with(fun sum/2, [1,2], [3,4])). | |
%% Implement zip/2 using zip_with/3. | |
zip2(Xs, Ys) -> zip_with(fun (X,Y) -> {X,Y} end, Xs, Ys). | |
% One test. | |
zip2_test() -> | |
?assertEqual([{1,3},{2,4}], zip2([1,2],[3,4])). | |
% Implement zip_with/3 using zip/2 and lists:map | |
zip_with2(F, Xs, Ys) -> | |
Fun = fun({X,Y}) -> F(X,Y) end, | |
Zipped = zip(Xs, Ys), | |
lists:map(Fun, Zipped). | |
% Tests. | |
zip_with2_test() -> | |
?assertEqual([], zip_with2(fun tup2/2, [], [3,4])), | |
?assertEqual([{1,3},{2,4}], zip_with2(fun tup2/2, [1,2], [3,4])), | |
?assertEqual([4,6], zip_with2(fun sum/2, [1,2], [3,4])). |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment