+
+-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.