Skip to content

Instantly share code, notes, and snippets.

@Rapptz
Last active August 29, 2015 14:01
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save Rapptz/a18adf811935bc18cc50 to your computer and use it in GitHub Desktop.
Save Rapptz/a18adf811935bc18cc50 to your computer and use it in GitHub Desktop.
local tuple = require("tuple")
function test(x, y, z)
print(x, y, z)
end
function get()
return 10, 11
end
test(tuple.new(get()):insert(12):unpack())
local tuple = {}
tuple.__index = tuple
function tuple.new(...)
return setmetatable({ data = { ... }}, tuple)
end
local function is_tuple(t)
return getmetatable(t) == tuple
end
function tuple:length()
return #self.data
end
function tuple:append(arg)
self.data[#self.data + 1] = arg
end
function tuple:insert(arg)
local t = self:clone()
t:append(arg)
return t
end
function tuple:get(index)
assert(index <= #self.data, "Index out of bounds")
return self.data[index]
end
function tuple:unpack()
return table.unpack(self.data)
end
-- creates a copy
function tuple:clone()
return tuple.new(self:unpack())
end
-- applies a function to an argument and returns the
-- result to the position the argument is at
function tuple:transform(f)
assert(type(f) == "function", "Type passed must be a function")
for i = 1, #self.data do
self.data[i] = f(self.data[i])
end
end
-- Same as transform but returns a new tuple
function tuple:map(f)
assert(type(f) == "function", "Type passed must be a function")
local data = {}
for i = 1, #self.data do
data[i] = f(self.data[i])
end
return tuple.new(table.unpack(data))
end
function tuple:type()
return "tuple"
end
-- overloaded operator shortcuts for apply
function tuple.__add(lhs, rhs)
assert(is_tuple(lhs), "left hand side must be a tuple")
return lhs:map(function(arg) return arg + rhs end)
end
function tuple.__sub(lhs, rhs)
assert(is_tuple(lhs), "left hand side must be a tuple")
return lhs:map(function(arg) return arg - rhs end)
end
function tuple.__mul(lhs, rhs)
assert(is_tuple(lhs), "left hand side must be a tuple")
return lhs:map(function(arg) return arg * rhs end)
end
function tuple.__div(lhs, rhs)
assert(is_tuple(lhs), "left hand side must be a tuple")
return lhs:map(function(arg) return arg / rhs end)
end
function tuple.__mod(lhs, rhs)
assert(is_tuple(lhs), "left hand side must be a tuple")
return lhs:map(function(arg) return arg % rhs end)
end
function tuple.__pow(lhs, rhs)
assert(is_tuple(lhs), "left hand side must be a tuple")
return lhs:map(function(arg) return arg ^ rhs end)
end
-- shortcut for insertion
function tuple.__concat(lhs, rhs)
assert(is_tuple(lhs), "left hand side must be a tuple")
return lhs:insert(rhs)
end
return tuple
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment