aboutsummaryrefslogtreecommitdiffstats
path: root/lua/nvim-lsp-installer/core/functional/function.lua
blob: 0d70aa92b8d47d01b42feae7f9bc5e4392027c77 (plain) (blame)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
local data = require "nvim-lsp-installer.core.functional.data"

local _ = {}

---@generic T : fun(...)
---@param fn T
---@param arity integer
---@return T
_.curryN = function(fn, arity)
    return function(...)
        local args = data.table_pack(...)
        if args.n >= arity then
            return fn(unpack(args, 1, arity))
        else
            return _.curryN(_.partial(fn, unpack(args, 1, args.n)), arity - args.n)
        end
    end
end

_.compose = function(...)
    local functions = data.table_pack(...)
    assert(functions.n > 0, "compose requires at least one function")
    return function(...)
        local result = data.table_pack(...)
        for i = functions.n, 1, -1 do
            result = data.table_pack(functions[i](unpack(result, 1, result.n)))
        end
        return unpack(result, 1, result.n)
    end
end

---@generic T
---@param fn fun(...): T
---@return fun(...): T
_.partial = function(fn, ...)
    local bound_args = data.table_pack(...)
    return function(...)
        local args = data.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

_.identity = function(a)
    return a
end

_.always = function(a)
    return function()
        return a
    end
end

_.T = _.always(true)
_.F = _.always(false)

---@generic T : fun(...)
---@param fn T
---@param cache_key_generator (fun(...): string | nil)|nil
---@return T
_.memoize = function(fn, cache_key_generator)
    cache_key_generator = cache_key_generator or _.identity
    local cache = {}
    return function(...)
        local key = cache_key_generator(...)
        if not cache[key] then
            cache[key] = data.table_pack(fn(...))
        end
        return unpack(cache[key], 1, cache[key].n)
    end
end

---@generic T
---@param fn fun(): T
---@return fun(): T
_.lazy = function(fn)
    local memoized = _.memoize(fn, _.always "lazyval")
    return function()
        return memoized()
    end
end

return _