EinsDreiDreiSieben/mods/futil/util/functional.lua

159 lines
2.3 KiB
Lua

local functional = {}
local t_iterate = futil.table.iterate
local t_insert = table.insert
function functional.noop()
-- the NOTHING function does nothing.
end
function functional.identity(x)
return x
end
function functional.izip(...)
local is = { ... }
if #is == 0 then
return functional.noop
end
return function()
local t = {}
for i in t_iterate(is) do
local v = i()
if v ~= nil then
t_insert(t, v)
else
return
end
end
return t
end
end
function functional.zip(...)
local is = {}
for t in t_iterate({ ... }) do
t_insert(is, t_iterate(t))
end
return functional.izip(unpack(is))
end
function functional.imap(func, ...)
local zipper = functional.izip(...)
return function()
local args = zipper()
if args then
return func(unpack(args))
end
end
end
function functional.map(func, ...)
local zipper = functional.zip(...)
return function()
local args = zipper()
if args then
return func(unpack(args))
end
end
end
function functional.apply(func, t)
local t2 = {}
for k, v in pairs(t) do
t2[k] = func(v)
end
return t2
end
function functional.reduce(func, t, initial)
local i = t_iterate(t)
if not initial then
initial = i()
end
local next = i()
while next do
initial = func(initial, next)
next = i()
end
return initial
end
function functional.partial(func, ...)
local args = { ... }
return function(...)
return func(unpack(args), ...)
end
end
function functional.compose(a, b)
return function(...)
return a(b(...))
end
end
function functional.ifilter(pred, i)
local v
return function()
v = i()
while v ~= nil and not pred(v) do
v = i()
end
return v
end
end
function functional.filter(pred, t)
return functional.ifilter(pred, t_iterate(t))
end
function functional.iall(i)
while true do
local v = i()
if v == false then
return false
elseif v == nil then
return true
end
end
end
function functional.all(t)
for i = 1, #t do
if not t[i] then
return false
end
end
return true
end
function functional.iany(i)
while true do
local v = i()
if v == nil then
return false
elseif v then
return true
end
end
end
function functional.any(t)
for i = 1, #t do
if t[i] then
return true
end
end
return false
end
function functional.wrap(f)
return function(...)
return f(...)
end
end
futil.functional = functional