Currying is a general feature in functional programming languages. It means that any function can be used by receiving an argument and evaluated as a partial-evaluated function. In Erlang, by using the following a function curry/2, currying is ready for use.
curry(F) when is_function(F, 2) -> fun(X) -> fun(Y) -> F(X, Y) end end.
I made another version of carrying function that it accepts zero or many arguments.
curry(F, N) -> curry(F, N, ). curry(F, 0, Args) -> apply(F, lists:reverse(Args)); curry(F, N, Args) when N > 0 -> fun(X) -> curry(F, N-1, [X|Args]) end.
These currying functions are eager. I would like them being as lazy as possible for ease purpose. Laziness in Erlang should be used by describing it explicitly. Then I made a one-step lazy function by defining macros. (Thanking for John Hughes: http://erlang.org/pipermail/erlang-questions/2008-September/038378.html )
-define(DELAY(E), fun()-> E end). -define(FORCE(F), F()). curryl(F, N) -> curryl(F, N, ). curryl(F, N, Args) -> ?DELAY(curry(F, N, Args)).
It’s no problem that once calling curryl/2 or curryl/3 it is slightly lazy. However what I want is a lazy and lazy currying function because most functions are recursive. Thus I wrote a really lazy version: curryll/2.
curryll(F, N) -> curryll(F, N, ). curryll(F, 0, Args) -> fun() -> apply(F, lists:reverse(Args)) end; curryll(F, N, Args) when N > 0 -> fun() -> fun(X) -> curryll(F, N-1, [X|Args]) end end.
Then usage seems that troublesome.
> G1 = stdlib:curryll(fun lists:append/2, 2). #Fun<stdlib.4.59664587> > G2 = (G1())([a,b]). #Fun<stdlib.4.59664587> > G3 = (G2())([c]). #Fun<stdlib.3.22456195> > G3(). [a,b,c] >
It’s too lazy that I need force it work step-by-step. I’m not yet sure if it helps automation. I will use this lazy currying to write a parser, which will contain many recursive and recursive grammar that laziness is strongly recommended to be used, and partial evaluation is also important for it that most parsing combinators receives some arguments and are still functions waiting for more arguments.