Skip to content

Instantly share code, notes, and snippets.

@fjpse
Created May 28, 2020 21:34
Show Gist options
  • Save fjpse/66db33acfb5739e8d29f8dee5cc52d1a to your computer and use it in GitHub Desktop.
Save fjpse/66db33acfb5739e8d29f8dee5cc52d1a to your computer and use it in GitHub Desktop.
-module(hof).
-export([compose/1, twice/1, add/1, times/1, compose/2, id/1, iterate/1]).
-include_lib("eunit/include/eunit.hrl").
%%
%% compose
%%
-spec compose([function()]) -> function().
compose(Fs) ->
lists:foldr(fun compose/2, fun id/1, Fs).
compose_test() ->
?assert((compose(add(3), times(4)))(2) == (compose([add(3), times(4)]))(2)).
%%
%% twice
%%
-spec twice(function()) -> function().
twice(F) ->
compose(F,F).
twice_test() ->
?assert((twice(add(3)))(5) == 11).
twice_twice_test() ->
?assert((twice(twice(add(3))))(5) == 17).
%%
%% iterate
%%
-spec iterate(non_neg_integer()) -> function().
iterate(0) ->
fun(_, X) ->
id(X) end;
iterate(N) ->
fun(F, X) ->
F( (iterate(N-1))(F,X) ) end.
iterate_zero_test() ->
?assert((iterate(0))(times(3), 2) == 2).
iterate_other_test() ->
?assert((iterate(3))(times(3), 2) == 54).
%%
%% auxiliary functions
%%
add(X) ->
fun(Y) -> X+Y end.
times(X) ->
fun(Y) ->
X*Y end.
compose(F,G) ->
fun(X) ->
G(F(X)) end.
id(X) ->
X.
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment