diff --git a/eslint.config.mjs b/eslint.config.mjs index 6601bc8..fae0980 100644 --- a/eslint.config.mjs +++ b/eslint.config.mjs @@ -1,9 +1,10 @@ -import path from 'node:path'; -import { fileURLToPath } from 'node:url'; -import { FlatCompat } from '@eslint/eslintrc'; -import js from '@eslint/js'; -import ts from '@typescript-eslint/eslint-plugin'; -import parser from '@typescript-eslint/parser'; +import path from 'node:path' +import { fileURLToPath } from 'node:url' +import { FlatCompat } from '@eslint/eslintrc' +import js from '@eslint/js' +import ts from '@typescript-eslint/eslint-plugin' +import stylistic from '@stylistic/eslint-plugin' +import parser from '@typescript-eslint/parser' export default [ ...new FlatCompat({ @@ -16,28 +17,33 @@ export default [ 'plugin:@typescript-eslint/eslint-recommended', 'plugin:@typescript-eslint/recommended', ), + stylistic.configs['recommended-flat'], { files: ['src/**/*.ts', 'test/**/*.ts'], languageOptions: { parser }, plugins: { '@typescript-eslint': ts, + '@stylistic': stylistic, }, rules: { 'arrow-body-style': 'error', 'no-extra-parens': ['error', 'all'], 'sort-imports': ['error', { ignoreDeclarationSort: true }], + '@stylistic/quotes': ['error', 'single'], + '@stylistic/semi': ['error', 'always'], + '@stylistic/indent': 'error', '@typescript-eslint/no-unused-vars': [ 'error', { - 'args': 'all', - 'argsIgnorePattern': '^_', - 'caughtErrors': 'all', - 'caughtErrorsIgnorePattern': '^_', - 'destructuredArrayIgnorePattern': '^_', - 'varsIgnorePattern': '^_', - 'ignoreRestSiblings': true - } + args: 'all', + argsIgnorePattern: '^_', + caughtErrors: 'all', + caughtErrorsIgnorePattern: '^_', + destructuredArrayIgnorePattern: '^_', + varsIgnorePattern: '^_', + ignoreRestSiblings: true, + }, ], - '@typescript-eslint/no-explicit-any': 'off' - } - }]; + '@typescript-eslint/no-explicit-any': 'off', + }, + }] diff --git a/jest.config.ts b/jest.config.ts index a31af38..14a7f67 100644 --- a/jest.config.ts +++ b/jest.config.ts @@ -1,8 +1,8 @@ -import type { Config } from 'jest'; +import type { Config } from 'jest' export default { - testEnvironment: "node", + testEnvironment: 'node', transform: { - "^.+.tsx?$": ["ts-jest", { tsconfig: 'test/tsconfig.json' }], + '^.+.tsx?$': ['ts-jest', { tsconfig: 'test/tsconfig.json' }], }, -} as Config; +} as Config diff --git a/package.json b/package.json index bd0c7b9..2fcac0c 100644 --- a/package.json +++ b/package.json @@ -17,6 +17,7 @@ "@eslint/eslintrc": "^3.1.0", "@eslint/js": "^9.8.0", "@jest/globals": "^29.7.0", + "@stylistic/eslint-plugin": "^2.6.1", "@typescript-eslint/eslint-plugin": "^8.0.0", "@typescript-eslint/parser": "^8.0.0", "eslint": "^9.8.0", diff --git a/src/bool.ts b/src/bool.ts index 2e2802c..427971c 100644 --- a/src/bool.ts +++ b/src/bool.ts @@ -12,7 +12,7 @@ export const iif: L<(b: Bool) => L<(t: T) => L<(f: T) => T>>> = _(b => _(t => _(f => b._(t)._(f)))); export const eq: L<(l: Bool) => L<(r: Bool) => Bool>> - = _(l => _(r => l._(r)._(not._(r)))) + = _(l => _(r => l._(r)._(not._(r)))); export const not: L<(b: Bool) => Bool> = _(b => b._(False)._(True)); diff --git a/src/char.ts b/src/char.ts index 05503e7..a34dfd6 100644 --- a/src/char.ts +++ b/src/char.ts @@ -1,4 +1,3 @@ - import { L, _ } from './core'; import { Bool } from './bool'; import { toNumber as $n, Num, Zero, fromNumber as _n, eq as eqn } from './num'; diff --git a/src/list.ts b/src/list.ts index db02c3e..477e92c 100644 --- a/src/list.ts +++ b/src/list.ts @@ -23,54 +23,46 @@ export const tail: L<(xs: List) => List> = _(xs => xs._(undef)._(_(_x => _(xs => xs)))); export const foldl: L<(f: L<(a: R) => L<(x: T) => R>>) => L<(z: R) => L<(xs: List) => R>>> - = - _((f: L<(a: R) => L<(x: T) => R>>) => + = _((f: L<(a: R) => L<(x: T) => R>>) => _((z: R) => _((xs: List) => xs._(z)._(_(x => _(xs => foldl._(f)._(f._(z)._(x))._(xs))))))); export const foldlz: L<(f: L<(a: T) => L<(x: T) => T>>) => L<(xs: List) => T>> - = - _((f: L<(a: T) => L<(x: T) => T>>) => - _((xs:List) => + = _((f: L<(a: T) => L<(x: T) => T>>) => + _((xs: List) => xs._(undef)._(_(x => _(xs => foldl._(f)._(x)._(xs)))))); export const foldr: L<(f: L<(x: T) => L<(a: R) => R>>) => L<(z: R) => L<(xs: List) => R>>> - = - _((f: L<(x: T) => L<(a: R) => R>>) => + = _((f: L<(x: T) => L<(a: R) => R>>) => _((z: R) => _((xs: List) => xs._(z)._(_(x => _(xs => f._(x)._(foldr._(f)._(z)._(xs)))))))); export const foldrz: L<(f: L<(x: T) => L<(a: T) => T>>) => L<(xs: List) => T>> = _(_f => _(_z => undef)); -export const eq: L<(e: L<(l: T) =>L <(r: T) => Bool>>) => L<(l: List)=> L<(r: List) => Bool>>> - = - _((e: L<(l: T) => L<(r: T) => Bool>>) => +export const eq: L<(e: L<(l: T) => L <(r: T) => Bool>>) => L<(l: List) => L<(r: List) => Bool>>> + = _((e: L<(l: T) => L<(r: T) => Bool>>) => _((l: List) => _((r: List) => l ._(r._(True)._(_(_x => _(_xs => False)))) ._(_(lx => _(lxs => r._(False)._(_(rx => _(rxs => and._(e._(lx)._(rx))._(eq._(e)._(lxs)._(rxs))))))))))); export const map: L<(f: L<(x: T) => R>) => L<(xs: List) => List>> - = - _((f: L<(x: T) => R>) => + = _((f: L<(x: T) => R>) => _((xs: List) => xs._(Nil)._(_(x => _(xs => Cons._(f._(x))._(map._(f)._(xs))))))); export const filter: L<(f: L<(x: T) => Bool>) => L<(xs: List) => List>> - = - _((f: L<(x: T) => Bool>) => + = _((f: L<(x: T) => Bool>) => _((xs: List) => xs._(Nil)._(_(x => _(xs => iif._(f._(x))._(Cons._(x)._(filter._(f)._(xs)))._(filter._(f)._(xs))))))); export const any: L<(f: L<(x: T) => Bool>) => L<(xs: List) => Bool>> - = - _((f: L<(x: T) => Bool>) => + = _((f: L<(x: T) => Bool>) => _((xs: List) => xs._(False)._(_(x => _(xs => or._(f._(x))._(any._(f)._(xs))))))); export const all: L<(f: L<(x: T) => Bool>) => L<(xs: List) => Bool>> - = - _((f: L<(x: T) => Bool>) => + = _((f: L<(x: T) => Bool>) => _((xs: List) => xs._(True)._(_(x => _(xs => and._(f._(x))._(all._(f)._(xs))))))); export const fromArray: (xs: T[]) => List diff --git a/src/pair.ts b/src/pair.ts index f1cccff..b744e0e 100644 --- a/src/pair.ts +++ b/src/pair.ts @@ -3,8 +3,7 @@ import { L, P, _ } from './core'; export type Pair = L<(f: L<(f: F) => L<(s: S) => R>>) => R>; export const Pair: L<(f: F) => L<(s: S) => Pair>> - = - _((f: F) => + = _((f: F) => _((s: S) => _((p: L<(f: F) => L<(s: S) => R>>) => p._(f)._(s)))); @@ -15,17 +14,14 @@ export const snd: L<(p: Pair) => S> = _(p => p._(_(_f => _(s => s)))); export const first: L<(t: L<(f: F) => FR>) => L<(p: Pair) => Pair>> - = - _((t: L<(f: F) => FR>) => + = _((t: L<(f: F) => FR>) => _((p: Pair) => p._(_(f => _(s => Pair._(t._(f))._(s)))))); export const second: L<(t: L<(s: S) => SR>) => L<(p: Pair) => Pair>> - = - _((t: L<(s: S) => SR>) => + = _((t: L<(s: S) => SR>) => _((p: Pair) => p._(_(f => _(s => Pair._(f)._(t._(s))))))); -export const both: L<(tf: L<(f: F) => FR>) => L<(ts: L<(s: S) => SR>) =>L<(p: Pair) => Pair>>> - = - _((tf: L<(f: F) => FR>) => +export const both: L<(tf: L<(f: F) => FR>) => L<(ts: L<(s: S) => SR>) => L<(p: Pair) => Pair>>> + = _((tf: L<(f: F) => FR>) => _((ts: L<(s: S) => SR>) => _((p: Pair) => p._(_(f => _(s => Pair._(tf._(f))._(ts._(s)))))))); diff --git a/test/num.spec.ts b/test/num.spec.ts index 6229f89..2c149aa 100644 --- a/test/num.spec.ts +++ b/test/num.spec.ts @@ -107,7 +107,7 @@ describe('Num', () => { it('handles infinity', () => { expect($b(eq._(_(7))._(infinity))).toBe(false); - }) + }); }); describe('sum', () => { @@ -171,8 +171,8 @@ describe('Num', () => { expect($(mul._(_(3))._(_(4)))).toBe(12); }); - it('0 mul ignores second argument', ()=>{ + it('0 mul ignores second argument', () => { expect($(mul._(_(0))._(undef))).toBe(0); - }) + }); }); }); diff --git a/test/string.spec.ts b/test/string.spec.ts index 6b42695..c5337eb 100644 --- a/test/string.spec.ts +++ b/test/string.spec.ts @@ -5,7 +5,7 @@ import { toChar as $c, fromChar as _c } from '../src/char'; import { toString as $s, Cons, Empty, String, fromString as _s, concat, eq } from '../src/string'; describe('String', () => { - const infinite: String = new L(() => Cons._(_c('a'))._(infinite).value);; + const infinite: String = new L(() => Cons._(_c('a'))._(infinite).value); ; describe('toString', () => { it('converts ""', () => { @@ -59,35 +59,35 @@ describe('String', () => { }); it('"" eq "abc" is False', () => { - expect($b(eq._(_s(''))._(_s("abc")))).toBe(false); + expect($b(eq._(_s(''))._(_s('abc')))).toBe(false); }); it('"abc" eq "" is False', () => { - expect($b(eq._(_s("abc"))._(_s('')))).toBe(false); + expect($b(eq._(_s('abc'))._(_s('')))).toBe(false); }); it('"a" eq "abc" is False', () => { - expect($b(eq._(_s('a'))._(_s("abc")))).toBe(false); + expect($b(eq._(_s('a'))._(_s('abc')))).toBe(false); }); it('"abc" eq "a" is False', () => { - expect($b(eq._(_s("abc"))._(_s('a')))).toBe(false); + expect($b(eq._(_s('abc'))._(_s('a')))).toBe(false); }); it('"bca" eq "abc" is False', () => { - expect($b(eq._(_s("bca"))._(_s("abc")))).toBe(false); + expect($b(eq._(_s('bca'))._(_s('abc')))).toBe(false); }); it('"abc" eq "bca" is False', () => { - expect($b(eq._(_s("abc"))._(_s("bca")))).toBe(false); + expect($b(eq._(_s('abc'))._(_s('bca')))).toBe(false); }); it('"abc" eq "abc" is True', () => { - expect($b(eq._(_s("abc"))._(_s("abc")))).toBe(true); + expect($b(eq._(_s('abc'))._(_s('abc')))).toBe(true); }); it('handles infinite strings', () => { - expect($b(eq._(_s("abc"))._(infinite))).toBe(false); + expect($b(eq._(_s('abc'))._(infinite))).toBe(false); }); }); }); diff --git a/yarn.lock b/yarn.lock index 6f43671..f3d282f 100644 --- a/yarn.lock +++ b/yarn.lock @@ -652,6 +652,54 @@ dependencies: "@sinonjs/commons" "^3.0.0" +"@stylistic/eslint-plugin-js@2.6.1", "@stylistic/eslint-plugin-js@^2.6.1": + version "2.6.1" + resolved "https://registry.yarnpkg.com/@stylistic/eslint-plugin-js/-/eslint-plugin-js-2.6.1.tgz#97e4f689c6bbe3661cd5fb1fd4dbb5e2e7a42cfa" + integrity sha512-iLOiVzcvqzDGD9U0EuVOX680v+XOPiPAjkxWj+Q6iV2GLOM5NB27tKVOpJY7AzBhidwpRbaLTgg3T4UzYx09jw== + dependencies: + "@types/eslint" "^9.6.0" + acorn "^8.12.1" + eslint-visitor-keys "^4.0.0" + espree "^10.1.0" + +"@stylistic/eslint-plugin-jsx@2.6.1": + version "2.6.1" + resolved "https://registry.yarnpkg.com/@stylistic/eslint-plugin-jsx/-/eslint-plugin-jsx-2.6.1.tgz#a7ba8242a27a8956455789dfcc087f5231fb4a7c" + integrity sha512-5qHLXqxfY6jubAQfDqrifv41fx7gaqA9svDaChxMI6JiHpEBfh+PXxmm3g+B8gJCYVBTC62Rjl0Ny5QabK58bw== + dependencies: + "@stylistic/eslint-plugin-js" "^2.6.1" + "@types/eslint" "^9.6.0" + estraverse "^5.3.0" + picomatch "^4.0.2" + +"@stylistic/eslint-plugin-plus@2.6.1": + version "2.6.1" + resolved "https://registry.yarnpkg.com/@stylistic/eslint-plugin-plus/-/eslint-plugin-plus-2.6.1.tgz#5b9ea3c659726835a7418d51bb818ba4dccb6b3d" + integrity sha512-z/IYu/q8ipApzNam5utSU+BrXg4pK/Gv9xNbr4eWv/bZppvTWJU62xCO4nw/6r2dHNPnqc7uCHEC7GMlBnPY0A== + dependencies: + "@types/eslint" "^9.6.0" + "@typescript-eslint/utils" "^8.0.0" + +"@stylistic/eslint-plugin-ts@2.6.1": + version "2.6.1" + resolved "https://registry.yarnpkg.com/@stylistic/eslint-plugin-ts/-/eslint-plugin-ts-2.6.1.tgz#76a90c732139b43e17c98c2c1eea1bc7a549cef6" + integrity sha512-Mxl1VMorEG1Hc6oBYPD0+KIJOWkjEF1R0liL7wWgKfwpqOkgmnh5lVdZBrYyfRKOE4RlGcwEFTNai1IW6orgVg== + dependencies: + "@stylistic/eslint-plugin-js" "2.6.1" + "@types/eslint" "^9.6.0" + "@typescript-eslint/utils" "^8.0.0" + +"@stylistic/eslint-plugin@^2.6.1": + version "2.6.1" + resolved "https://registry.yarnpkg.com/@stylistic/eslint-plugin/-/eslint-plugin-2.6.1.tgz#6ccddd1ba275cb2407d9abf546982177b872a603" + integrity sha512-UT0f4t+3sQ/GKW7875NiIIjZJ1Bh4gd7JNfoIkwIQyWqO7wGd0Pqzu0Ho30Ka8MNF5lm++SkVeqAk26vGxoUpg== + dependencies: + "@stylistic/eslint-plugin-js" "2.6.1" + "@stylistic/eslint-plugin-jsx" "2.6.1" + "@stylistic/eslint-plugin-plus" "2.6.1" + "@stylistic/eslint-plugin-ts" "2.6.1" + "@types/eslint" "^9.6.0" + "@tsconfig/node10@^1.0.7": version "1.0.11" resolved "https://registry.yarnpkg.com/@tsconfig/node10/-/node10-1.0.11.tgz#6ee46400685f130e278128c7b38b7e031ff5b2f2" @@ -705,6 +753,19 @@ dependencies: "@babel/types" "^7.20.7" +"@types/eslint@^9.6.0": + version "9.6.0" + resolved "https://registry.yarnpkg.com/@types/eslint/-/eslint-9.6.0.tgz#51d4fe4d0316da9e9f2c80884f2c20ed5fb022ff" + integrity sha512-gi6WQJ7cHRgZxtkQEoyHMppPjq9Kxo5Tjn2prSKDSmZrCz8TZ3jSRCeTJm+WoM+oB0WG37bRqLzaaU3q7JypGg== + dependencies: + "@types/estree" "*" + "@types/json-schema" "*" + +"@types/estree@*": + version "1.0.5" + resolved "https://registry.yarnpkg.com/@types/estree/-/estree-1.0.5.tgz#a6ce3e556e00fd9895dd872dd172ad0d4bd687f4" + integrity sha512-/kYRxGDLWzHOB7q+wtSUQlFrtcdUccpfy+X+9iMBpHK8QLLhx2wIPYuS5DYtR9Wa/YlZAbIovy7qVdB1Aq6Lyw== + "@types/graceful-fs@^4.1.3": version "4.1.9" resolved "https://registry.yarnpkg.com/@types/graceful-fs/-/graceful-fs-4.1.9.tgz#2a06bc0f68a20ab37b3e36aa238be6abdf49e8b4" @@ -731,6 +792,11 @@ dependencies: "@types/istanbul-lib-report" "*" +"@types/json-schema@*": + version "7.0.15" + resolved "https://registry.yarnpkg.com/@types/json-schema/-/json-schema-7.0.15.tgz#596a1747233694d50f6ad8a7869fcb6f56cf5841" + integrity sha512-5+fP8P8MFNC+AyZCDxrB2pkZFPGzqQWUzpSeuuVLvm8VMcorNYavBqoFcxK8bQz4Qsbn4oUEEem4wDLfcysGHA== + "@types/node@*": version "20.14.12" resolved "https://registry.yarnpkg.com/@types/node/-/node-20.14.12.tgz#129d7c3a822cb49fc7ff661235f19cfefd422b49" @@ -818,7 +884,7 @@ semver "^7.6.0" ts-api-utils "^1.3.0" -"@typescript-eslint/utils@8.0.0": +"@typescript-eslint/utils@8.0.0", "@typescript-eslint/utils@^8.0.0": version "8.0.0" resolved "https://registry.yarnpkg.com/@typescript-eslint/utils/-/utils-8.0.0.tgz#1794d6f4b37ec253172a173dc938ae68651b9b99" integrity sha512-k/oS/A/3QeGLRvOWCg6/9rATJL5rec7/5s1YmdS0ZU6LHveJyGFwBvLhSRBv6i9xaj7etmosp+l+ViN1I9Aj/Q== @@ -848,7 +914,7 @@ acorn-walk@^8.1.1: dependencies: acorn "^8.11.0" -acorn@^8.11.0, acorn@^8.12.0, acorn@^8.4.1: +acorn@^8.11.0, acorn@^8.12.0, acorn@^8.12.1, acorn@^8.4.1: version "8.12.1" resolved "https://registry.yarnpkg.com/acorn/-/acorn-8.12.1.tgz#71616bdccbe25e27a54439e0046e89ca76df2248" integrity sha512-tcpGyI9zbizT9JbV6oYE477V6mTlXvvi0T0G3SNIYE2apm/G5huBa1+K89VGeovbg+jycCrfhl3ADxErOuO6Jg== @@ -1363,7 +1429,7 @@ esrecurse@^4.3.0: dependencies: estraverse "^5.2.0" -estraverse@^5.1.0, estraverse@^5.2.0: +estraverse@^5.1.0, estraverse@^5.2.0, estraverse@^5.3.0: version "5.3.0" resolved "https://registry.yarnpkg.com/estraverse/-/estraverse-5.3.0.tgz#2eea5290702f26ab8fe5370370ff86c965d21123" integrity sha512-MMdARuVEQziNTeJD8DgMqmhwR11BRQ/cBP+pLtYdSTnf3MIO8fFeiINEbX36ZdNlfU/7A9f3gUw49B3oQsvwBA== @@ -2445,6 +2511,11 @@ picomatch@^2.0.4, picomatch@^2.2.3, picomatch@^2.3.1: resolved "https://registry.yarnpkg.com/picomatch/-/picomatch-2.3.1.tgz#3ba3833733646d9d3e4995946c1365a67fb07a42" integrity sha512-JU3teHTNjmE2VCGFzuY8EXzCDVwEqB2a8fsIvwaStHhAWJEeVd1o1QD80CU6+ZdEXXSLbSsuLwJjkCBWqRQUVA== +picomatch@^4.0.2: + version "4.0.2" + resolved "https://registry.yarnpkg.com/picomatch/-/picomatch-4.0.2.tgz#77c742931e8f3b8820946c76cd0c1f13730d1dab" + integrity sha512-M7BAV6Rlcy5u+m6oPhAPFgJTzAioX/6B0DxyvDlo9l8+T3nLKbrczg2WLUyzd45L8RqfUMyGPzekbMvX2Ldkwg== + pirates@^4.0.4: version "4.0.6" resolved "https://registry.yarnpkg.com/pirates/-/pirates-4.0.6.tgz#3018ae32ecfcff6c29ba2267cbf21166ac1f36b9"