Originally Posted by Casull
Hey, for giggles I was trying to write a curry function. It looked something like this
Code:
function curry(f, ...)
return function (..)
f(..., ..)
end
end
where the two dots are a different set of variable arguments from the three dots. So if I could define a channel greeting function as follows:
Code:
GreetChannel = curry(SendChatMessage, "Hello, channel!", "CHANNEL", GetDefaultLanguage("player"))
so that greets my channel 1 with "Hello, channel!". Is there any way for Lua to distinguish between differing sets of variable arguments?
I can't even seem to get this to work! I assume for the same reason
Code:
function curry(f, x, ...)
if x or select("#", ...) > 0 then
return curry(function(...) f(x, ...) end, ...)
else
return f
end
end
I read the lua-users wiki article on currying, but it's not quite as general as the form of currying I am seeking. Any insight?
|
It won't work anything like what you want it to look like, for several reasons.
Reason 1: Tuples are immutable. You cannot put them together like you want to. Take the following example:
Code:
function foo(...)
return ..., 4;
end
print(foo(1,2,3)); -- Outputs 1,4
The ... will be shortened to a single term.
Reason 2: ... is not a valid upvalue. You can only use it in the current context. take the following example:
Code:
function foo(...)
local f = function() return ... end; -- Error
return f;
end
local bar = foo(1,2,3);
print(bar());
At the location marked "Error", the following results: "cannot use '...' outside a vararg function near '...'"
It follows from reason 2 that there should never be a case where you need a "second" ... tuple. It, concurrently, follows from reason 1 that even if you did, you would not be able to operate on it in the sense that you desired to in the first place. Your only real solution is to generate a table from the tuple in the form:
Code:
function foo(...)
return {...};
end
local t1 = foo(1,2,3);
local t2 = foo(4,5,6);
-- Concatenate them
local t = {};
for _,v in ipairs(t1) do
table.insert(t, v);
end
for _,v in ipairs(t2) do
table.insert(t, v);
end
print(unpack(t)) -- Outputs 1,2,3,4,5,6
Do note, however, that this solution is not perfect. It will, for example, have flaws when iterated over if nils are present in the tuple. Concurrently, trailing nils will not be preserved. Still, it is the most efficient, effective solution to your problem.