diff options
Diffstat (limited to 'lua/nvim-lsp-installer/core/functional.lua')
| -rw-r--r-- | lua/nvim-lsp-installer/core/functional.lua | 175 |
1 files changed, 175 insertions, 0 deletions
diff --git a/lua/nvim-lsp-installer/core/functional.lua b/lua/nvim-lsp-installer/core/functional.lua new file mode 100644 index 00000000..244c3d96 --- /dev/null +++ b/lua/nvim-lsp-installer/core/functional.lua @@ -0,0 +1,175 @@ +local functional = {} + +---@generic T : string +---@param values T[] +---@return table<T, T> +function functional.enum(values) + local result = {} + for i = 1, #values do + local v = values[i] + result[v] = v + end + return result +end + +---@generic T +---@param list T[] +---@return table<T, boolean> +function functional.set_of(list) + local set = {} + for i = 1, #list do + set[list[i]] = true + end + return set +end + +---@generic T +---@param list T[] +---@return T[] +function functional.list_reverse(list) + local result = {} + for i = #list, 1, -1 do + result[#result + 1] = list[i] + end + return result +end + +---@generic T, U +---@param fn fun(item: T): U +---@param list T[] +---@return U[] +function functional.list_map(fn, list) + local result = {} + for i = 1, #list do + result[#result + 1] = fn(list[i], i) + end + return result +end + +function functional.table_pack(...) + return { n = select("#", ...), ... } +end + +function functional.list_not_nil(...) + local result = {} + local args = functional.table_pack(...) + for i = 1, args.n do + if args[i] ~= nil then + result[#result + 1] = args[i] + end + end + return result +end + +function functional.when(condition, value) + return condition and value or nil +end + +function functional.lazy_when(condition, fn) + return condition and fn() or nil +end + +function functional.coalesce(...) + local args = functional.table_pack(...) + for i = 1, args.n do + local variable = args[i] + if variable ~= nil then + return variable + end + end +end + +---@generic T +---@param list T[] +---@return T[] @A shallow copy of the list. +function functional.list_copy(list) + local result = {} + for i = 1, #list do + result[#result + 1] = list[i] + end + return result +end + +---@generic T +---@param predicate fun(item: T): boolean +---@param list T[] +---@return T | nil +function functional.list_find_first(predicate, list) + local result + for i = 1, #list do + local entry = list[i] + if predicate(entry) then + return entry + end + end + return result +end + +---@generic T +---@param predicate fun(item: T): boolean +---@param list T[] +---@return boolean +function functional.list_any(predicate, list) + for i = 1, #list do + if predicate(list[i]) then + return true + end + end + return false +end + +function functional.identity(a) + return a +end + +function functional.always(a) + return function() + return a + end +end + +---@generic T : fun(...) +---@param fn T +---@param cache_key_generator (fun(...): string | nil)|nil +---@return T +function functional.memoize(fn, cache_key_generator) + cache_key_generator = cache_key_generator or functional.identity + local cache = {} + return function(...) + local key = cache_key_generator(...) + if not cache[key] then + cache[key] = functional.table_pack(fn(...)) + end + return unpack(cache[key], 1, cache[key].n) + end +end + +---@generic T +---@param fn fun(): T +---@return fun(): T +function functional.lazy(fn) + local memoized = functional.memoize(fn, functional.always "lazyval") + return function() + return memoized() + end +end + +---@generic T +---@param fn fun(...): T +---@return fun(...): T +function functional.partial(fn, ...) + local bound_args = functional.table_pack(...) + return function(...) + local args = functional.table_pack(...) + local merged_args = {} + for i = 1, bound_args.n do + merged_args[i] = bound_args[i] + end + for i = 1, args.n do + merged_args[bound_args.n + i] = args[i] + end + return fn(unpack(merged_args, 1, bound_args.n + args.n)) + end +end + +return functional |
