Implement function composition. 3.2.0
authorSiraaj Khandkar <siraaj@khandkar.net>
Fri, 1 May 2015 19:59:31 +0000 (15:59 -0400)
committerSiraaj Khandkar <siraaj@khandkar.net>
Wed, 6 May 2015 17:38:12 +0000 (13:38 -0400)
src/hope.app.src
src/hope_fun.erl
test/hope_fun_SUITE.erl

index 1ac246a..197db7c 100644 (file)
@@ -1,7 +1,7 @@
 {application, hope,
  [
   {description, "Higher Order Programming in Erlang"},
 {application, hope,
  [
   {description, "Higher Order Programming in Erlang"},
-  {vsn, "3.1.1"},
+  {vsn, "3.2.0"},
   {registered, []},
   {applications, [
                   kernel,
   {registered, []},
   {applications, [
                   kernel,
index c2443ce..96a39cd 100644 (file)
@@ -3,6 +3,9 @@
 -export(
     [ id/1
     , curry/1
 -export(
     [ id/1
     , curry/1
+    , compose/1  % alias for compose_right/1
+    , compose_right/1
+    , compose_left/1
     ]).
 
 -spec id(A) ->
     ]).
 
 -spec id(A) ->
@@ -22,3 +25,26 @@ curry(F, Args, 0) ->
     apply(F, lists:reverse(Args));
 curry(F, Args, Arity) ->
     fun (X) -> curry(F, [X | Args], Arity - 1) end.
     apply(F, lists:reverse(Args));
 curry(F, Args, Arity) ->
     fun (X) -> curry(F, [X | Args], Arity - 1) end.
+
+-spec compose([fun((A) -> B)]) ->
+    fun((A) -> B).
+compose(Fs) ->
+    compose_right(Fs).
+
+-spec compose_right([fun((A) -> B)]) ->
+    fun((A) -> B).
+compose_right(Fs) ->
+    compose_given_fold(Fs, fun lists:foldr/3).
+
+-spec compose_left([fun((A) -> B)]) ->
+    fun((A) -> B).
+compose_left(Fs) ->
+    compose_given_fold(Fs, fun lists:foldl/3).
+
+
+%% ============================================================================
+
+-spec compose_given_fold([fun((A) -> B)], fun((fun((A, B) -> C), B, [A]) -> C)) ->
+    fun((A) -> C).
+compose_given_fold(Fs, Fold) ->
+    fun (X) -> Fold(fun (F, Y) -> F(Y) end, X, Fs) end.
index 910cc49..7b5051b 100644 (file)
@@ -8,8 +8,10 @@
 
 %% Test cases
 -export(
 
 %% Test cases
 -export(
-    [ t_id/1
+    [ t_specs/1
+    , t_id/1
     , t_curry/1
     , t_curry/1
+    , t_compose/1
     ]).
 
 
     ]).
 
 
@@ -26,8 +28,10 @@ all() ->
 
 groups() ->
     Tests =
 
 groups() ->
     Tests =
-        [ t_id
+        [ t_specs
+        , t_id
         , t_curry
         , t_curry
+        , t_compose
         ],
     Properties = [parallel],
     [ {?GROUP, Properties, Tests}
         ],
     Properties = [parallel],
     [ {?GROUP, Properties, Tests}
@@ -38,6 +42,9 @@ groups() ->
 %%  Test cases
 %% =============================================================================
 
 %%  Test cases
 %% =============================================================================
 
+t_specs(_) ->
+    [] = proper:check_specs(hope_fun).
+
 t_id(_Cfg) ->
     X = foo,
     X = hope_fun:id(X).
 t_id(_Cfg) ->
     X = foo,
     X = hope_fun:id(X).
@@ -58,3 +65,12 @@ t_curry(_Cfg) ->
     H2 = H1(a),
     H  = H2(b),
     {a, b, c} = H(c).
     H2 = H1(a),
     H  = H2(b),
     {a, b, c} = H(c).
+
+t_compose(_Cfg) ->
+    A2B = fun (a) -> b end,
+    B2C = fun (b) -> c end,
+    C2D = fun (c) -> d end,
+    Fs = [C2D, B2C, A2B],
+    d = (hope_fun:compose       (              Fs  ))(a),
+    d = (hope_fun:compose_right (              Fs  ))(a),
+    d = (hope_fun:compose_left  (lists:reverse(Fs) ))(a).
This page took 0.026858 seconds and 4 git commands to generate.