Skip to content

Instantly share code, notes, and snippets.

@jcmoyer
Last active May 12, 2017 14:33
Show Gist options
  • Save jcmoyer/5571987 to your computer and use it in GitHub Desktop.
Save jcmoyer/5571987 to your computer and use it in GitHub Desktop.
Proper function currying in Lua 5.2
-- shallowly clones an array table
function clone(t)
local r = {}
for i = 1, #t do
r[#r + 1] = t[i]
end
return r
end
-- for any function 'f', the following is true:
-- curry(f)(x)(y)(z) == f(x, y, z)
--
-- if 'f' is some function of arity 3,
-- curry(f) == function(x) return function(y) return function(z) return f(x, y, z) end end end
--
-- for convenience, functions returned by curry do not *require* you to apply only one parameter
-- at a time (partial application):
-- curry(f)(x, y)(z) == f(x, y, z)
-- perhaps this function would be better named 'partial'
function curry(f)
local info = debug.getinfo(f, 'u')
local function docurry(s, left, ...)
local ptbl = clone(s)
local vargs = {...}
for i = 1, #vargs do
ptbl[#ptbl + 1] = vargs[i]
end
left = left - #vargs
if left > 0 then
return function(...)
return docurry(ptbl, left, ...)
end
else
return f(unpack(ptbl))
end
end
return function(...)
return docurry({}, info.nparams, ...)
end
end
function add(x, y)
return x + y
end
function foldl(f, s, t)
for i = 1, #t do
s = f(s, t[i])
end
return s
end
local sum = curry(foldl)(add, 0)
print(sum{1,2,3,4,5})
print(sum{5,3,1,10,15})
print(sum{2,1,55,1,22})
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment