Skip to content

Commit 99b5ae9

Browse files
authored
Merge pull request #7 from Dich0tomy/feat/luakittens
The luakittens library is an attempt to redefine the type system and type validation methods in lua. For now the plans is for it to consist of several parts: - the luaKITTENS annotation language, a type annotation is called `kitty` for short - a parser for the language - a type validator Currently only the language and parser are done and tested, mostly. Several things are lacking for now. There's no specification yet, to discover the language and it's capabilities one would have to look at the `only_parse` function and `__test()` -> `describe('`only_parse()`)` --- This implementation is incomplete and I will be rewriting it to a handwritten parser, which will allow for more fine-grained syntax control and better diagnostics.
2 parents 864a627 + f40e8aa commit 99b5ae9

File tree

5 files changed

+764
-22
lines changed

5 files changed

+764
-22
lines changed

.gitignore

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -9,6 +9,7 @@
99
!TODO.md
1010

1111
# Collaborators consistency
12+
!.luarc.json
1213
!.editorconfig
1314
!stylua.toml
1415
!.pre-commit-config.yaml

.luarc.json

Lines changed: 31 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,31 @@
1+
{
2+
"Lua": {
3+
"diagnostics": {
4+
"unusedLocalExclude": [ "_*" ]
5+
},
6+
"globals": [
7+
"vim"
8+
],
9+
"workspace": {
10+
"checkThirdParty": false,
11+
"ignoreDir": [
12+
".git",
13+
".github",
14+
".direnv",
15+
"result",
16+
"nix",
17+
"doc",
18+
"docs"
19+
],
20+
"library": [
21+
"lua",
22+
"$VIMRUNTIME",
23+
"${3rd}/busted/library",
24+
"${3rd}/luassert/library"
25+
]
26+
}
27+
},
28+
"runtime": {
29+
"version": "LuaJIT"
30+
}
31+
}

lua/cpp-tools/lib/fp/init.lua

Lines changed: 237 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,237 @@
1+
local M = {}
2+
3+
---Takes a function of two arguments and flips their parameters
4+
---@generic T, U
5+
---@param fun fun(lhs: `T`, rhs: `U`): any Function to flip
6+
---@return fun(rhs: U, lhs: `T`): any # Flipped function
7+
function M.flip(fun)
8+
return function(lhs, rhs)
9+
return fun(rhs, lhs)
10+
end
11+
end
12+
13+
---Partially applies some function arguments
14+
---@param fun fun(...: any): any Function to apply args to
15+
---@param ... any Args to apply
16+
---@return fun(...: any): any # Function with args applied
17+
function M.partial(fun, ...)
18+
local passed = { ... }
19+
return function(...)
20+
return fun(unpack(vim.list_extend(passed, { ... })))
21+
end
22+
end
23+
24+
---Partially applies some function arguments to the back
25+
---@param fun fun(...: any): any Function to apply args to
26+
---@param ... any Args to apply
27+
---@return fun(...: any): any # Function with args applied to the back
28+
function M.partial_(fun, ...)
29+
local passed = { ... }
30+
return function(...)
31+
return fun(unpack(vim.list_extend({ ... }, passed)))
32+
end
33+
end
34+
35+
---Returns the nth argument passed to this function
36+
---@param n number Which argument to return
37+
---@param ... any Args
38+
---@return any # Nth arg
39+
function M.nth(n, ...)
40+
return ({ ... })[n]
41+
end
42+
43+
---Returns the first argument passed to this function
44+
---@generic T
45+
---@param a `T` The first arg
46+
---@return T # The first argument
47+
function M.first(a)
48+
return a
49+
end
50+
51+
---Returns the second argument passed to this function
52+
---@generic T
53+
---@param _a any First arg, discarded
54+
---@param b `T` Second arg, returned
55+
---@return T # Second arg
56+
function M.second(_a, b)
57+
return b
58+
end
59+
60+
---Returns a function that compares its argument to `value`
61+
---@generic T
62+
---@param value `T` Value to compare against
63+
---@return fun(x: T): boolean
64+
function M.equal(value)
65+
return function(x)
66+
return x == value
67+
end
68+
end
69+
70+
---If it's a function, calls it, otherwise returns id
71+
---@generic R, V
72+
---@param value fun(any...): `R`|V Value to call/return
73+
---@param ... any Possible values to pass to the function
74+
---@return R|V
75+
function M.eval(value, ...)
76+
if type(value) == 'function' then
77+
return value(...)
78+
else
79+
return value
80+
end
81+
end
82+
83+
---Returns the result of a function wrapped in an array
84+
---@generic Ts
85+
---@param f fun(any...): `Ts` Function to wrap
86+
---@return fun(...): [Ts]
87+
function M.arraified(f)
88+
return function(...)
89+
return { f(...) }
90+
end
91+
end
92+
93+
---Returns the args untouched
94+
---@param ... any Args to return
95+
---@return ... any
96+
function M.id(...)
97+
return ...
98+
end
99+
100+
---Returns `id` or the passed in function
101+
---@generic Rs, Ts
102+
---@param value fun(...: `Ts`): `Rs`|nil Value to call/return
103+
---@return fun(...: Ts): `Rs`|fun(...: any): ...
104+
function M.maybe_fn(value)
105+
assert(type(value) == 'function' or value == nil)
106+
107+
if type(value) == 'function' then
108+
return value
109+
else
110+
return M.id
111+
end
112+
end
113+
114+
---Reduces the result over a function
115+
---@generic T, U, R
116+
---@param f fun(arg1: T, arg2: U): `R` The applied function
117+
---@param acc R The accumulator and initial value
118+
---@return R
119+
function M.foldl(f, acc, ...)
120+
if select('#', ...) == 0 then
121+
return acc
122+
end
123+
local l = ...
124+
return M.foldl(f, f(acc, l), select(2, ...))
125+
end
126+
127+
---Composes two functions f, g and into `g(f(...))`
128+
---@generic FirstR, SecondR
129+
---@param f fun(...: any): `FirstR`
130+
---@param g fun(...: FirstR): `SecondR`
131+
---@return fun(...: any): SecondR
132+
function M.compose(f, g)
133+
return function(...)
134+
return g(f(...))
135+
end
136+
end
137+
138+
---Chains several functions invocations together
139+
---chain(a, b, c) results in c(b(a(...)))
140+
---@param ... fun(...: any): ...
141+
---@return fun(...: any): ...
142+
function M.chain(...)
143+
return M.foldl(M.compose, M.id, ...)
144+
end
145+
146+
---Returns `not f(...)`
147+
---@param f fun(...: any): boolean func to inverse
148+
---@return fun(...: any): boolean
149+
function M.nah(f)
150+
return function(...)
151+
return not f(...)
152+
end
153+
end
154+
155+
---Formats the arguments
156+
---@param str string The format string
157+
---@return fun(...: any): string
158+
function M.fmt(str)
159+
return function(...)
160+
return str:format(...)
161+
end
162+
end
163+
164+
---@package
165+
function M.__test()
166+
describe('`flip()`', function()
167+
it('Flips a two arg function', function()
168+
local sub = function(a, b)
169+
return a - b
170+
end
171+
172+
assert.are.same(sub(5, 3), 2)
173+
assert.are.same(M.flip(sub)(5, 3), -2)
174+
end)
175+
176+
it('Makes a one arg function accept only the second argument', function()
177+
assert.are.same(M.id(5), 5)
178+
assert.are.same(M.flip(M.id)(5, 3), 3)
179+
end)
180+
end)
181+
182+
describe('`partial()`', function()
183+
it('Applies the first argument', function()
184+
local sub = function(a, b)
185+
return a - b
186+
end
187+
188+
assert.are.same(M.partial(sub, 5)(3), 2)
189+
end)
190+
191+
it('Applies all arguments', function()
192+
local sub = function(a, b)
193+
return a - b
194+
end
195+
196+
assert.are.same(M.partial(sub, 5, 3)(), 2)
197+
end)
198+
end)
199+
200+
describe('`partial_()`', function()
201+
it('Applies the last argument', function()
202+
local sub = function(a, b)
203+
return a - b
204+
end
205+
206+
assert.are.same(M.partial_(sub, 5)(3), -2)
207+
end)
208+
209+
it('Applies all arguments', function()
210+
local sub = function(a, b)
211+
return a - b
212+
end
213+
214+
assert.are.same(M.partial_(sub, 5, 3)(), 2)
215+
end)
216+
end)
217+
218+
describe('`partial_()`', function()
219+
it('Applies the last argument', function()
220+
local sub = function(a, b)
221+
return a - b
222+
end
223+
224+
assert.are.same(M.partial_(sub, 5)(3), -2)
225+
end)
226+
227+
it('Applies all arguments', function()
228+
local sub = function(a, b)
229+
return a - b
230+
end
231+
232+
assert.are.same(M.partial_(sub, 5, 3)(), 2)
233+
end)
234+
end)
235+
end
236+
237+
return M

0 commit comments

Comments
 (0)