diff options
| author | Ludvig Gunne Lindström <ludviggunnelindstrom@gmail.com> | 2026-07-17 11:43:24 +0200 |
|---|---|---|
| committer | Ludvig Gunne Lindström <ludviggunnelindstrom@gmail.com> | 2026-11-08 14:15:04 +0100 |
| commit | 039847a29868d335c08fe0a587260dffc71ca5c4 (patch) | |
| tree | e9d775090fef45ca51db576779fb373040d50e6a /lib/functional.lua | |
| download | melisma-modules-039847a29868d335c08fe0a587260dffc71ca5c4.tar.gz | |
Diffstat (limited to 'lib/functional.lua')
| -rw-r--r-- | lib/functional.lua | 171 |
1 files changed, 171 insertions, 0 deletions
diff --git a/lib/functional.lua b/lib/functional.lua new file mode 100644 index 0000000..9f50b7e --- /dev/null +++ b/lib/functional.lua @@ -0,0 +1,171 @@ +-- +-- melisma - extensible and scriptable audio engine +-- Copyright (C) 2026 Ludvig Gunne Lindström +-- +-- This program is free software: you can redistribute it and/or modify +-- it under the terms of the GNU General Public License as published by +-- the Free Software Foundation, either version 3 of the License, or +-- (at your option) any later version. +-- +-- This program is distributed in the hope that it will be useful, +-- but WITHOUT ANY WARRANTY; without even the implied warranty of +-- MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +-- GNU General Public License for more details. +-- +-- You should have received a copy of the GNU General Public License +-- along with this program. If not, see <https://www.gnu.org/licenses/>. +-- + +local m_util = require 'melisma.util' + +local M = {} + +function M.fmap(f,l) + local res = {} + for k,v in pairs(l) do res[k] = f(v) end + return res +end + +function M.compose(f,g,...) + local tail = table.pack(...) + if g == nil then return f end + return function(x) return f(M.compose(g,table.unpack(tail))(x)) end +end + +function M.pipeline(...) + local args = table.pack(...) + return function(x) + for _,f in ipairs(args) do x = f(x) end + return x + end +end + +function M.bind(f,...) + local bound = table.pack(...) + return function(...) + local free = table.pack(...) + local all = M.concat(bound,free) + return f(table.unpack(all)) + end +end + +function M.bind1(f,...) + local bound = table.pack(...) + return function(x) + return f(x,table.unpack(bound)) + end +end + +function M.constval(v) return function(...) return v end end + +function M.constfunc(f) return function(...) f() end end + +function M.call(f,...) return f(...) end + +function M.replicate(f,n) + local res = {} + for i=1,n do + if type(f) == 'function' then + table.insert(res,f()) + else + table.insert(res,f) + end + end + return res +end + +function M.id(...) return ... end + +function M.access(...) + local args = table.pack(...) + local x = args[#args] + args[#args] = nil + + for _,key in ipairs(args) do + x = x[key] + end + + return x +end + +function M.filter(pred,list) + local result = {} + + for _,elem in ipairs(list) do + if pred(elem) then + table.insert(result,elem) + end + end + + return result +end + +function M.void(...) end + +function M.zip(f,lhs,rhs) + local result = {} + local n = math.min(#lhs,#rhs) + + for i = 1,n do + local v = f(lhs[i],rhs[i]) + table.insert(result,v) + end + + return result +end + +function M.tap(f) + return function(...) + f(...) + return ... + end +end + +function M.fold(mempty,mappend,tbl) + local result = mempty + for i = 1,#tbl do result = mappend(result,tbl) end + return result +end + +function M.flatten(tbl) + if type(tbl) ~= 'table' then return tbl end + return M.fold({}, M.concat, fmap(M.flatten, tbl)) +end + +function M.concat(lhs,rhs) + local result = {} + for i = 1,#lhs do result[i] = lhs[i] end + for i = 1,#rhs do result[i + #lhs] = rhs[i] end + return result +end + +function M.find(list,pred) + for i = 1,#list do + if pred(list[i]) then return list[i],i end + end + return nil,nil +end + +function M.range(f,t,s) + local res = {} + for x = f,t,s or 1 do table.insert(res,x) end + return res +end + +function M.image(a,b,c,d,x) return (x - a)/(b - a)*(d - c) + c end + +function M.apply(f,...) return f(...) end + +function M.once(f) + local ret + local called = false + return function(...) + if not called then + ret = f(...) + called = true + return ret + end + end +end + +return M |
