X-Git-Url: https://git.xandkar.net/?a=blobdiff_plain;f=src%2Fhope_fun.erl;h=df0d786e18799a50c74a3a815f50cd7dd75a78ef;hb=797ff79bcd48da49fcb82b00013224c0831203a4;hp=61babe9c808e549d4af64906a730a2d4078c417c;hpb=64617423d513e37494369d637bee5ff357de791b;p=hope.git diff --git a/src/hope_fun.erl b/src/hope_fun.erl index 61babe9..df0d786 100644 --- a/src/hope_fun.erl +++ b/src/hope_fun.erl @@ -2,9 +2,56 @@ -export( [ id/1 + , curry/1 + , compose/1 % alias for compose_right/1 + , compose_right/1 + , compose_left/1 + , thread/2 ]). -spec id(A) -> A. id(X) -> X. + +-spec curry(fun()) -> + fun(). +curry(F) -> + {arity, Arity} = erlang:fun_info(F, arity), + curry(F, [], Arity). + +-spec curry(fun(), list(), integer()) -> + fun(). +curry(F, Args, 0) -> + 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 thread([fun((A) -> B)], A) -> + B. +thread(Fs, X) -> + F = compose_left(Fs), + F(X). + + +%% ============================================================================ + +-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.