As MATLAB has a hard maximum of 10 input arguments it's possible, but ugly, to implement a curry function in this manner:
%% turns a standard function into a curried one
% if g has 3 input arguments then you can call:
% h = curry(g)
% h(1)(2)(3) == g(1, 2, 3)
% Matlab doesn't like h(1)(2)(3), but in principle it works.
function fOut = curry(fIn)
fOut = fIn;
% can't curry a vararg function
if (nargin(fOut) < 0)
return
end
if (nargin(fOut) == 10)
fOut = @(bind)(curry(@(free1, free2, free3, free4, free5, free6, free7, free8, free9) (fIn(bind, free1, free2, free3, free4, free5, free6, free7, free8, free9))));
return
end
if (nargin(fOut) == 9)
fOut = @(bind)(curry(@(free1, free2, free3, free4, free5, free6, free7, free8) (fIn(bind, free1, free2, free3, free4, free5, free6, free7, free8))));
return
end
if (nargin(fOut) == 8)
fOut = @(bind)(curry(@(free1, free2, free3, free4, free5, free6, free7) (fIn(bind, free1, free2, free3, free4, free5, free6, free7))));
return
end
if (nargin(fOut) == 7)
fOut = @(bind)(curry(@(free1, free2, free3, free4, free5, free6) (fIn(bind, free1, free2, free3, free4, free5, free6))));
return
end
if (nargin(fOut) == 6)
fOut = @(bind)(curry(@(free1, free2, free3, free4, free5) (fIn(bind, free1, free2, free3, free4, free5))));
return
end
if (nargin(fOut) == 5)
fOut = @(bind)(curry(@(free1, free2, free3, free4) (fIn(bind, free1, free2, free3, free4))));
return
end
if (nargin(fOut) == 4)
fOut = @(bind)(curry(@(free1, free2, free3) (fIn(bind, free1, free2, free3))));
return
end
if (nargin(fOut) == 3)
fOut = @(bind)(curry(@(free1, free2) (fIn(bind, free1, free2))));
return
end
if (nargin(fOut) == 2)
fOut = @(bind)(curry(@(free1) (fIn(bind, free1))));
return
end
end
Is there a less horrible way to do this?
Initially, I tried using varargin
which is how I assume the answer will look. Here's what I had at that time:
function fOut = curry(fIn)
fOut = fIn;
% can't curry a vararg function (nargin = -1) or a function with less than
% arity of 2
if (nargin(fOut) < 2)
return
end
fOut = @(bind)(curry(@(varargin)(fIn(bind, varargin{:}))));
end