[erlang-questions] Automatic currying

Siraaj Khandkar siraaj@REDACTED
Thu Apr 30 22:42:47 CEST 2015


One of the things I often wish for, when using Erlang, is staged 
application of any function without having to manually wrap it in stage 
funs (which you get in languages that feature curried-by-default functions).

The other day it occurred to me that the ability to get fun arity info 
and to apply arguments as a list was all that was needed to get very, 
very close to the behavior I wanted. Voila:

     -module(function).
     -export([curry/1]).

     curry(F) ->
         Info = erlang:fun_info(F),
         {value, {arity, Arity}} = lists:keysearch(arity, 1, Info),
         curry(F, [], Arity).

     curry(F, Args, 0) ->
         apply(F, lists:reverse(Args));
     curry(F, Args, Arity) ->
         fun (X) -> curry(F, [X | Args], Arity - 1) end.

In action:

     $ erl
     1>
     1> Nums = lists:seq(1, 10).
     [1,2,3,4,5,6,7,8,9,10]
     2>
     2> Plus = function:curry(fun (X, Y) -> X + Y end).
     #Fun<function.0.4634292>
     3>
     3> lists:map(Plus(1), Nums).
     [2,3,4,5,6,7,8,9,10,11]
     4>
     4> lists:map(Plus(3), Nums).
     [4,5,6,7,8,9,10,11,12,13]
     5>
     5> lists:map(Plus(5), Nums).
     [6,7,8,9,10,11,12,13,14,15]
     6>
     6> Fold = function:curry(fun lists:foldl/3).
     #Fun<function.0.4634292>
     7>
     7> AddTo = Fold(fun (X, Y) -> X + Y end).
     #Fun<function.0.4634292>
     8>
     8> AddTo0 = AddTo(0).
     #Fun<function.0.4634292>
     9>
     9> AddTo100 = AddTo(100).
     #Fun<function.0.4634292>
     10>
     10> AddTo0(Nums).
     55
     11> AddTo100(Nums).
     155
     12>
     12> AddTo100(lists:seq(4, 78)).
     3175
     13>



More information about the erlang-questions mailing list