diff --git a/.github/workflows/ci.yml b/.github/workflows/ci.yml index d624d2e..4dc2d20 100644 --- a/.github/workflows/ci.yml +++ b/.github/workflows/ci.yml @@ -24,4 +24,7 @@ jobs: run: if [ -f scripts/test ]; then nix develop -c bash ./scripts/test; fi - name: Luacheck - run: nix develop -c luacheck --quiet --std lua51 --no-unused-args src/ + run: nix develop -c luacheck --quiet --std lua51 --no-unused-args --max-line-length 130 src/ + + - name: Format check + run: nix fmt && git diff --exit-code diff --git a/.gitignore b/.gitignore index db67e9a..e070528 100644 --- a/.gitignore +++ b/.gitignore @@ -1,4 +1,6 @@ /.* !/.gitignore !/.github/ +!/.tidyrc.json +!/.lua-format /output/ diff --git a/.lua-format b/.lua-format new file mode 100644 index 0000000..2945014 --- /dev/null +++ b/.lua-format @@ -0,0 +1,10 @@ +# LuaFormatter config for the hand-written FFI under src/. +# 2-space indent. Keep simple functions on one line; column_limit sits a few +# columns under luacheck's 130 limit because lua-format under-counts the leading +# indent and trailing comma, so this keeps every emitted line within 130. +indent_width: 2 +use_tab: false +column_limit: 126 +continuation_indent_width: 2 +keep_simple_function_one_line: true +keep_simple_control_block_one_line: true diff --git a/.tidyrc.json b/.tidyrc.json new file mode 100644 index 0000000..8636af8 --- /dev/null +++ b/.tidyrc.json @@ -0,0 +1,10 @@ +{ + "importSort": "source", + "importWrap": "source", + "indent": 2, + "operatorsFile": null, + "ribbon": 1, + "typeArrowPlacement": "first", + "unicode": "source", + "width": 80 +} diff --git a/AGENTS.md b/AGENTS.md index dde531a..a312901 100644 --- a/AGENTS.md +++ b/AGENTS.md @@ -4,11 +4,21 @@ A PureScript→Lua FFI fork in the [`purescript-lua`](https://github.com/purescr ## Commands -All commands run inside the nix dev shell: - - Build: `nix develop -c ./scripts/build` - Test (only if the fork has `scripts/test`): `nix develop -c bash ./scripts/test` -- Lint: `nix develop -c luacheck --quiet --std lua51 --no-unused-args src/` +- Lint: `nix develop -c luacheck --quiet --std lua51 --no-unused-args --max-line-length 130 src/` +- Format: `nix fmt` (check: `nix fmt && git diff --exit-code`) + +## Formatting + +`nix fmt` runs treefmt (`treefmt.nix`): nixfmt for Nix, `dhall format`, purs-tidy +for `*.purs` (config in `.tidyrc.json`), and LuaFormatter for the `*.lua` FFI +(config in `.lua-format`). LuaFormatter is used over StyLua because it keeps the +parentheses pslua's foreign-file parser requires. The Lua line budget is 130 +columns, matching the `luacheck --max-line-length` above. The check is +content-based (`nix fmt && git diff --exit-code`) rather than `treefmt --ci`, +since the in-place formatters bump mtime even when content is unchanged, which +trips treefmt's `--fail-on-change`. CI and the pre-commit hook use it. ## Lua 5.1 target diff --git a/flake.lock b/flake.lock index 6b6c417..c47b792 100644 --- a/flake.lock +++ b/flake.lock @@ -740,7 +740,8 @@ "flake-utils": "flake-utils", "nixpkgs": "nixpkgs", "pslua": "pslua", - "purescript-overlay": "purescript-overlay" + "purescript-overlay": "purescript-overlay", + "treefmt-nix": "treefmt-nix" } }, "stackage": { @@ -803,6 +804,26 @@ "repo": "default", "type": "github" } + }, + "treefmt-nix": { + "inputs": { + "nixpkgs": [ + "nixpkgs" + ] + }, + "locked": { + "lastModified": 1780220602, + "narHash": "sha256-eynAfOmbmxJnkp7YewvCEbShNnnYJ9gLLqkzsYtBPeM=", + "owner": "numtide", + "repo": "treefmt-nix", + "rev": "db947814a175b7ca6ded66e21383d938df01c227", + "type": "github" + }, + "original": { + "owner": "numtide", + "repo": "treefmt-nix", + "type": "github" + } } }, "root": "root", diff --git a/flake.nix b/flake.nix index 5198865..4d86c4b 100644 --- a/flake.nix +++ b/flake.nix @@ -9,16 +9,33 @@ inputs.nixpkgs.follows = "nixpkgs"; }; pslua.url = "github:purescript-lua/purescript-lua"; + treefmt-nix = { + url = "github:numtide/treefmt-nix"; + inputs.nixpkgs.follows = "nixpkgs"; + }; }; - outputs = { self, nixpkgs, flake-utils, purescript-overlay, pslua }: - flake-utils.lib.eachDefaultSystem (system: + outputs = + { + self, + nixpkgs, + flake-utils, + purescript-overlay, + pslua, + treefmt-nix, + }: + flake-utils.lib.eachDefaultSystem ( + system: let pkgs = import nixpkgs { inherit system; overlays = [ purescript-overlay.overlays.default ]; }; - in { + treefmtEval = treefmt-nix.lib.evalModule pkgs ./treefmt.nix; + in + { + formatter = treefmtEval.config.build.wrapper; + checks.formatting = treefmtEval.config.build.check self; devShell = pkgs.mkShell { buildInputs = with pkgs; [ dhall @@ -31,8 +48,26 @@ spago-bin.spago-0_21_0 treefmt ]; + # Install a content-based pre-commit hook. It compares the working + # tree diff before and after `nix fmt`, so it only objects to changes + # the formatter itself introduces (not the developer's existing + # unstaged work) and is not fooled by formatters that only bump mtime. + # Rewritten each shell entry to stay in sync with this flake. + shellHook = '' + hook=.git/hooks/pre-commit + if [ -d .git ]; then + printf '%s\n' \ + '#!/usr/bin/env bash' \ + 'before=$(git diff)' \ + 'nix fmt >/dev/null 2>&1 || exit 0' \ + '[ "$before" = "$(git diff)" ] || { echo "nix fmt changed files; re-stage them, then commit." >&2; exit 1; }' \ + > "$hook" + chmod +x "$hook" + fi + ''; }; - }); + } + ); # --- Flake Local Nix Configuration ---------------------------- nixConfig = { diff --git a/spago.dhall b/spago.dhall index 63bbe49..454a951 100644 --- a/spago.dhall +++ b/spago.dhall @@ -1,5 +1,5 @@ { name = "purescript-lua-effect" -, dependencies = [ "prelude" ] +, dependencies = [ "prelude" ] , packages = ./packages.dhall , sources = [ "src/**/*.purs" ] , backend = diff --git a/src/Effect.lua b/src/Effect.lua index 3f06cf7..9d2736a 100644 --- a/src/Effect.lua +++ b/src/Effect.lua @@ -1,49 +1,8 @@ return { - pureE = (function(a) - return function() - return a - end - end), - bindE = (function(a) - return function(f) - return function() - return f(a())() - end - end - end), - untilE = (function(f) - return function() - while not f() do - end - end - end), - whileE = (function(f) - return function(a) - return function() - while f() do - a() - end - end - end - end), - forE = (function(lo) - return function(hi) - return function(f) - return function() - for i = lo, hi do - f(i)() - end - end - end - end - end), - foreachE = (function(as) - return function(f) - return function() - for i = 1, #as do - f(as[i])() - end - end - end - end) + pureE = (function(a) return function() return a end end), + bindE = (function(a) return function(f) return function() return f(a())() end end end), + untilE = (function(f) return function() while not f() do end end end), + whileE = (function(f) return function(a) return function() while f() do a() end end end end), + forE = (function(lo) return function(hi) return function(f) return function() for i = lo, hi do f(i)() end end end end end), + foreachE = (function(as) return function(f) return function() for i = 1, #as do f(as[i])() end end end end) } diff --git a/src/Effect.purs b/src/Effect.purs index 32ea342..cbae24c 100644 --- a/src/Effect.purs +++ b/src/Effect.purs @@ -3,7 +3,10 @@ -- | computations, while at the same time generating efficient JavaScript. module Effect ( Effect - , untilE, whileE, forE, foreachE + , untilE + , whileE + , forE + , foreachE ) where import Prelude @@ -69,4 +72,5 @@ foreign import forE :: Int -> Int -> (Int -> Effect Unit) -> Effect Unit -- | -- | `foreachE xs f` runs the computation returned by the function `f` for each -- | of the inputs `xs`. -foreign import foreachE :: forall a. Array a -> (a -> Effect Unit) -> Effect Unit +foreign import foreachE + :: forall a. Array a -> (a -> Effect Unit) -> Effect Unit diff --git a/src/Effect/Uncurried.lua b/src/Effect/Uncurried.lua index 01acec5..b1cf78b 100644 --- a/src/Effect/Uncurried.lua +++ b/src/Effect/Uncurried.lua @@ -1,106 +1,28 @@ return { - mkEffectFn1 = (function(fn) - return function(a) - return fn(a)() - end - end), - mkEffectFn2 = (function(fn) - return function(a, b) - return fn(a)(b)() - end - end), - mkEffectFn3 = (function(fn) - return function(a, b, c) - return fn(a)(b)(c)() - end - end), - mkEffectFn4 = (function(fn) - return function(a, b, c, d) - return fn(a)(b)(c)(d)() - end - end), - mkEffectFn5 = (function(fn) - return function(a, b, c, d, e) - return fn(a)(b)(c)(d)(e)() - end - end), - mkEffectFn6 = (function(fn) - return function(a, b, c, d, e, f) - return fn(a)(b)(c)(d)(e)(f)() - end - end), - mkEffectFn7 = (function(fn) - return function(a, b, c, d, e, f, g) - return fn(a)(b)(c)(d)(e)(f)(g)() - end - end), - mkEffectFn8 = (function(fn) - return function(a, b, c, d, e, f, g, h) - return fn(a)(b)(c)(d)(e)(f)(g)(h)() - end - end), - mkEffectFn9 = (function(fn) - return function(a, b, c, d, e, f, g, h, i) - return fn(a)(b)(c)(d)(e)(f)(g)(h)(i)() - end - end), - mkEffectFn10 = (function(fn) - return function(a, b, c, d, e, f, g, h, i, j) - return fn(a)(b)(c)(d)(e)(f)(g)(h)(i)(j)() - end - end), - runEffectFn1 = (function(fn) - return function(a) - return function() - return fn(a) - end - end - end), - runEffectFn2 = (function(fn) - return function(a) - return function(b) - return function() - return fn(a, b) - end - end - end - end), + mkEffectFn1 = (function(fn) return function(a) return fn(a)() end end), + mkEffectFn2 = (function(fn) return function(a, b) return fn(a)(b)() end end), + mkEffectFn3 = (function(fn) return function(a, b, c) return fn(a)(b)(c)() end end), + mkEffectFn4 = (function(fn) return function(a, b, c, d) return fn(a)(b)(c)(d)() end end), + mkEffectFn5 = (function(fn) return function(a, b, c, d, e) return fn(a)(b)(c)(d)(e)() end end), + mkEffectFn6 = (function(fn) return function(a, b, c, d, e, f) return fn(a)(b)(c)(d)(e)(f)() end end), + mkEffectFn7 = (function(fn) return function(a, b, c, d, e, f, g) return fn(a)(b)(c)(d)(e)(f)(g)() end end), + mkEffectFn8 = (function(fn) return function(a, b, c, d, e, f, g, h) return fn(a)(b)(c)(d)(e)(f)(g)(h)() end end), + mkEffectFn9 = (function(fn) return function(a, b, c, d, e, f, g, h, i) return fn(a)(b)(c)(d)(e)(f)(g)(h)(i)() end end), + mkEffectFn10 = (function(fn) return function(a, b, c, d, e, f, g, h, i, j) return fn(a)(b)(c)(d)(e)(f)(g)(h)(i)(j)() end end), + runEffectFn1 = (function(fn) return function(a) return function() return fn(a) end end end), + runEffectFn2 = (function(fn) return function(a) return function(b) return function() return fn(a, b) end end end end), runEffectFn3 = (function(fn) - return function(a) - return function(b) - return function(c) - return function() - return fn(a, b, c) - end - end - end - end + return function(a) return function(b) return function(c) return function() return fn(a, b, c) end end end end end), runEffectFn4 = (function(fn) return function(a) - return function(b) - return function(c) - return function(d) - return function() - return fn(a, b, c, d) - end - end - end - end + return function(b) return function(c) return function(d) return function() return fn(a, b, c, d) end end end end end end), runEffectFn5 = (function(fn) return function(a) return function(b) - return function(c) - return function(d) - return function(e) - return function() - return fn(a, b, c, d, e) - end - end - end - end + return function(c) return function(d) return function(e) return function() return fn(a, b, c, d, e) end end end end end end end), @@ -109,13 +31,7 @@ return { return function(b) return function(c) return function(d) - return function(e) - return function(f) - return function() - return fn(a, b, c, d, e, f) - end - end - end + return function(e) return function(f) return function() return fn(a, b, c, d, e, f) end end end end end end @@ -127,13 +43,7 @@ return { return function(c) return function(d) return function(e) - return function(f) - return function(g) - return function() - return fn(a, b, c, d, e, f, g) - end - end - end + return function(f) return function(g) return function() return fn(a, b, c, d, e, f, g) end end end end end end @@ -148,11 +58,7 @@ return { return function(e) return function(f) return function(g) - return function(h) - return function() - return fn(a, b, c, d, e, f, g, h) - end - end + return function(h) return function() return fn(a, b, c, d, e, f, g, h) end end end end end @@ -170,11 +76,7 @@ return { return function(f) return function(g) return function(h) - return function(i) - return function() - return fn(a, b, c, d, e, f, g, h, i) - end - end + return function(i) return function() return fn(a, b, c, d, e, f, g, h, i) end end end end end @@ -194,11 +96,7 @@ return { return function(g) return function(h) return function(i) - return function(j) - return function() - return fn(a, b, c, d, e, f, g, h, i, j) - end - end + return function(j) return function() return fn(a, b, c, d, e, f, g, h, i, j) end end end end end diff --git a/src/Effect/Uncurried.purs b/src/Effect/Uncurried.purs index 7ed42e8..3f1ee27 100644 --- a/src/Effect/Uncurried.purs +++ b/src/Effect/Uncurried.purs @@ -151,71 +151,220 @@ foreign import data EffectFn4 :: Type -> Type -> Type -> Type -> Type -> Type type role EffectFn4 representational representational representational representational representational -foreign import data EffectFn5 :: Type -> Type -> Type -> Type -> Type -> Type -> Type +foreign import data EffectFn5 + :: Type -> Type -> Type -> Type -> Type -> Type -> Type type role EffectFn5 representational representational representational representational representational representational -foreign import data EffectFn6 :: Type -> Type -> Type -> Type -> Type -> Type -> Type -> Type +foreign import data EffectFn6 + :: Type -> Type -> Type -> Type -> Type -> Type -> Type -> Type type role EffectFn6 representational representational representational representational representational representational representational -foreign import data EffectFn7 :: Type -> Type -> Type -> Type -> Type -> Type -> Type -> Type -> Type +foreign import data EffectFn7 + :: Type -> Type -> Type -> Type -> Type -> Type -> Type -> Type -> Type type role EffectFn7 representational representational representational representational representational representational representational representational -foreign import data EffectFn8 :: Type -> Type -> Type -> Type -> Type -> Type -> Type -> Type -> Type -> Type +foreign import data EffectFn8 + :: Type + -> Type + -> Type + -> Type + -> Type + -> Type + -> Type + -> Type + -> Type + -> Type type role EffectFn8 representational representational representational representational representational representational representational representational representational -foreign import data EffectFn9 :: Type -> Type -> Type -> Type -> Type -> Type -> Type -> Type -> Type -> Type -> Type +foreign import data EffectFn9 + :: Type + -> Type + -> Type + -> Type + -> Type + -> Type + -> Type + -> Type + -> Type + -> Type + -> Type type role EffectFn9 representational representational representational representational representational representational representational representational representational representational -foreign import data EffectFn10 :: Type -> Type -> Type -> Type -> Type -> Type -> Type -> Type -> Type -> Type -> Type -> Type +foreign import data EffectFn10 + :: Type + -> Type + -> Type + -> Type + -> Type + -> Type + -> Type + -> Type + -> Type + -> Type + -> Type + -> Type type role EffectFn10 representational representational representational representational representational representational representational representational representational representational representational -foreign import mkEffectFn1 :: forall a r. - (a -> Effect r) -> EffectFn1 a r -foreign import mkEffectFn2 :: forall a b r. - (a -> b -> Effect r) -> EffectFn2 a b r -foreign import mkEffectFn3 :: forall a b c r. - (a -> b -> c -> Effect r) -> EffectFn3 a b c r -foreign import mkEffectFn4 :: forall a b c d r. - (a -> b -> c -> d -> Effect r) -> EffectFn4 a b c d r -foreign import mkEffectFn5 :: forall a b c d e r. - (a -> b -> c -> d -> e -> Effect r) -> EffectFn5 a b c d e r -foreign import mkEffectFn6 :: forall a b c d e f r. - (a -> b -> c -> d -> e -> f -> Effect r) -> EffectFn6 a b c d e f r -foreign import mkEffectFn7 :: forall a b c d e f g r. - (a -> b -> c -> d -> e -> f -> g -> Effect r) -> EffectFn7 a b c d e f g r -foreign import mkEffectFn8 :: forall a b c d e f g h r. - (a -> b -> c -> d -> e -> f -> g -> h -> Effect r) -> EffectFn8 a b c d e f g h r -foreign import mkEffectFn9 :: forall a b c d e f g h i r. - (a -> b -> c -> d -> e -> f -> g -> h -> i -> Effect r) -> EffectFn9 a b c d e f g h i r -foreign import mkEffectFn10 :: forall a b c d e f g h i j r. - (a -> b -> c -> d -> e -> f -> g -> h -> i -> j -> Effect r) -> EffectFn10 a b c d e f g h i j r - -foreign import runEffectFn1 :: forall a r. - EffectFn1 a r -> a -> Effect r -foreign import runEffectFn2 :: forall a b r. - EffectFn2 a b r -> a -> b -> Effect r -foreign import runEffectFn3 :: forall a b c r. - EffectFn3 a b c r -> a -> b -> c -> Effect r -foreign import runEffectFn4 :: forall a b c d r. - EffectFn4 a b c d r -> a -> b -> c -> d -> Effect r -foreign import runEffectFn5 :: forall a b c d e r. - EffectFn5 a b c d e r -> a -> b -> c -> d -> e -> Effect r -foreign import runEffectFn6 :: forall a b c d e f r. - EffectFn6 a b c d e f r -> a -> b -> c -> d -> e -> f -> Effect r -foreign import runEffectFn7 :: forall a b c d e f g r. - EffectFn7 a b c d e f g r -> a -> b -> c -> d -> e -> f -> g -> Effect r -foreign import runEffectFn8 :: forall a b c d e f g h r. - EffectFn8 a b c d e f g h r -> a -> b -> c -> d -> e -> f -> g -> h -> Effect r -foreign import runEffectFn9 :: forall a b c d e f g h i r. - EffectFn9 a b c d e f g h i r -> a -> b -> c -> d -> e -> f -> g -> h -> i -> Effect r -foreign import runEffectFn10 :: forall a b c d e f g h i j r. - EffectFn10 a b c d e f g h i j r -> a -> b -> c -> d -> e -> f -> g -> h -> i -> j -> Effect r +foreign import mkEffectFn1 + :: forall a r + . (a -> Effect r) + -> EffectFn1 a r + +foreign import mkEffectFn2 + :: forall a b r + . (a -> b -> Effect r) + -> EffectFn2 a b r + +foreign import mkEffectFn3 + :: forall a b c r + . (a -> b -> c -> Effect r) + -> EffectFn3 a b c r + +foreign import mkEffectFn4 + :: forall a b c d r + . (a -> b -> c -> d -> Effect r) + -> EffectFn4 a b c d r + +foreign import mkEffectFn5 + :: forall a b c d e r + . (a -> b -> c -> d -> e -> Effect r) + -> EffectFn5 a b c d e r + +foreign import mkEffectFn6 + :: forall a b c d e f r + . (a -> b -> c -> d -> e -> f -> Effect r) + -> EffectFn6 a b c d e f r + +foreign import mkEffectFn7 + :: forall a b c d e f g r + . (a -> b -> c -> d -> e -> f -> g -> Effect r) + -> EffectFn7 a b c d e f g r + +foreign import mkEffectFn8 + :: forall a b c d e f g h r + . (a -> b -> c -> d -> e -> f -> g -> h -> Effect r) + -> EffectFn8 a b c d e f g h r + +foreign import mkEffectFn9 + :: forall a b c d e f g h i r + . (a -> b -> c -> d -> e -> f -> g -> h -> i -> Effect r) + -> EffectFn9 a b c d e f g h i r + +foreign import mkEffectFn10 + :: forall a b c d e f g h i j r + . (a -> b -> c -> d -> e -> f -> g -> h -> i -> j -> Effect r) + -> EffectFn10 a b c d e f g h i j r + +foreign import runEffectFn1 + :: forall a r + . EffectFn1 a r + -> a + -> Effect r + +foreign import runEffectFn2 + :: forall a b r + . EffectFn2 a b r + -> a + -> b + -> Effect r + +foreign import runEffectFn3 + :: forall a b c r + . EffectFn3 a b c r + -> a + -> b + -> c + -> Effect r + +foreign import runEffectFn4 + :: forall a b c d r + . EffectFn4 a b c d r + -> a + -> b + -> c + -> d + -> Effect r + +foreign import runEffectFn5 + :: forall a b c d e r + . EffectFn5 a b c d e r + -> a + -> b + -> c + -> d + -> e + -> Effect r + +foreign import runEffectFn6 + :: forall a b c d e f r + . EffectFn6 a b c d e f r + -> a + -> b + -> c + -> d + -> e + -> f + -> Effect r + +foreign import runEffectFn7 + :: forall a b c d e f g r + . EffectFn7 a b c d e f g r + -> a + -> b + -> c + -> d + -> e + -> f + -> g + -> Effect r + +foreign import runEffectFn8 + :: forall a b c d e f g h r + . EffectFn8 a b c d e f g h r + -> a + -> b + -> c + -> d + -> e + -> f + -> g + -> h + -> Effect r + +foreign import runEffectFn9 + :: forall a b c d e f g h i r + . EffectFn9 a b c d e f g h i r + -> a + -> b + -> c + -> d + -> e + -> f + -> g + -> h + -> i + -> Effect r + +foreign import runEffectFn10 + :: forall a b c d e f g h i j r + . EffectFn10 a b c d e f g h i j r + -> a + -> b + -> c + -> d + -> e + -> f + -> g + -> h + -> i + -> j + -> Effect r -- The reason these are written eta-expanded instead of as: -- ``` @@ -232,28 +381,52 @@ instance semigroupEffectFn2 :: Semigroup r => Semigroup (EffectFn2 a b r) where append f1 f2 = mkEffectFn2 \a b -> runEffectFn2 f1 a b <> runEffectFn2 f2 a b instance semigroupEffectFn3 :: Semigroup r => Semigroup (EffectFn3 a b c r) where - append f1 f2 = mkEffectFn3 \a b c -> runEffectFn3 f1 a b c <> runEffectFn3 f2 a b c + append f1 f2 = mkEffectFn3 \a b c -> runEffectFn3 f1 a b c <> runEffectFn3 f2 + a + b + c instance semigroupEffectFn4 :: Semigroup r => Semigroup (EffectFn4 a b c d r) where - append f1 f2 = mkEffectFn4 \a b c d -> runEffectFn4 f1 a b c d <> runEffectFn4 f2 a b c d + append f1 f2 = mkEffectFn4 \a b c d -> runEffectFn4 f1 a b c d <> runEffectFn4 + f2 + a + b + c + d instance semigroupEffectFn5 :: Semigroup r => Semigroup (EffectFn5 a b c d e r) where - append f1 f2 = mkEffectFn5 \a b c d e -> runEffectFn5 f1 a b c d e <> runEffectFn5 f2 a b c d e - -instance semigroupEffectFn6 :: Semigroup r => Semigroup (EffectFn6 a b c d e f r) where - append f1 f2 = mkEffectFn6 \a b c d e f -> runEffectFn6 f1 a b c d e f <> runEffectFn6 f2 a b c d e f - -instance semigroupEffectFn7 :: Semigroup r => Semigroup (EffectFn7 a b c d e f g r) where - append f1 f2 = mkEffectFn7 \a b c d e f g -> runEffectFn7 f1 a b c d e f g <> runEffectFn7 f2 a b c d e f g - -instance semigroupEffectFn8 :: Semigroup r => Semigroup (EffectFn8 a b c d e f g h r) where - append f1 f2 = mkEffectFn8 \a b c d e f g h -> runEffectFn8 f1 a b c d e f g h <> runEffectFn8 f2 a b c d e f g h - -instance semigroupEffectFn9 :: Semigroup r => Semigroup (EffectFn9 a b c d e f g h i r) where - append f1 f2 = mkEffectFn9 \a b c d e f g h i -> runEffectFn9 f1 a b c d e f g h i <> runEffectFn9 f2 a b c d e f g h i - -instance semigroupEffectFn10 :: Semigroup r => Semigroup (EffectFn10 a b c d e f g h i j r) where - append f1 f2 = mkEffectFn10 \a b c d e f g h i j -> runEffectFn10 f1 a b c d e f g h i j <> runEffectFn10 f2 a b c d e f g h i j + append f1 f2 = mkEffectFn5 \a b c d e -> runEffectFn5 f1 a b c d e <> + runEffectFn5 f2 a b c d e + +instance semigroupEffectFn6 :: + Semigroup r => + Semigroup (EffectFn6 a b c d e f r) where + append f1 f2 = mkEffectFn6 \a b c d e f -> runEffectFn6 f1 a b c d e f <> + runEffectFn6 f2 a b c d e f + +instance semigroupEffectFn7 :: + Semigroup r => + Semigroup (EffectFn7 a b c d e f g r) where + append f1 f2 = mkEffectFn7 \a b c d e f g -> runEffectFn7 f1 a b c d e f g <> + runEffectFn7 f2 a b c d e f g + +instance semigroupEffectFn8 :: + Semigroup r => + Semigroup (EffectFn8 a b c d e f g h r) where + append f1 f2 = mkEffectFn8 \a b c d e f g h -> runEffectFn8 f1 a b c d e f g h + <> runEffectFn8 f2 a b c d e f g h + +instance semigroupEffectFn9 :: + Semigroup r => + Semigroup (EffectFn9 a b c d e f g h i r) where + append f1 f2 = mkEffectFn9 \a b c d e f g h i -> + runEffectFn9 f1 a b c d e f g h i <> runEffectFn9 f2 a b c d e f g h i + +instance semigroupEffectFn10 :: + Semigroup r => + Semigroup (EffectFn10 a b c d e f g h i j r) where + append f1 f2 = mkEffectFn10 \a b c d e f g h i j -> + runEffectFn10 f1 a b c d e f g h i j <> runEffectFn10 f2 a b c d e f g h i j instance monoidEffectFn1 :: Monoid r => Monoid (EffectFn1 a r) where mempty = mkEffectFn1 \_ -> mempty @@ -282,5 +455,7 @@ instance monoidEffectFn8 :: Monoid r => Monoid (EffectFn8 a b c d e f g h r) whe instance monoidEffectFn9 :: Monoid r => Monoid (EffectFn9 a b c d e f g h i r) where mempty = mkEffectFn9 \_ _ _ _ _ _ _ _ _ -> mempty -instance monoidEffectFn10 :: Monoid r => Monoid (EffectFn10 a b c d e f g h i j r) where +instance monoidEffectFn10 :: + Monoid r => + Monoid (EffectFn10 a b c d e f g h i j r) where mempty = mkEffectFn10 \_ _ _ _ _ _ _ _ _ _ -> mempty diff --git a/test/regression/uncurried.lua b/test/regression/uncurried.lua index 3e0eb09..0a12ecc 100644 --- a/test/regression/uncurried.lua +++ b/test/regression/uncurried.lua @@ -3,12 +3,11 @@ -- The FFI bound ten curried parameters a..j but called the underlying -- function with only nine (a..i), silently dropping j. This loads the -- FFI table directly and checks that every argument reaches `fn`. - local M = assert(dofile("src/Effect/Uncurried.lua")) local seen local recorder = function(...) - seen = { ... } + seen = {...} return nil end @@ -17,9 +16,6 @@ M.runEffectFn10(recorder)(1)(2)(3)(4)(5)(6)(7)(8)(9)(10)() assert(seen ~= nil, "fn was never called") assert(#seen == 10, "expected 10 forwarded arguments, got " .. #seen) -for k = 1, 10 do - assert(seen[k] == k, - "argument #" .. k .. " not forwarded (got " .. tostring(seen[k]) .. ")") -end +for k = 1, 10 do assert(seen[k] == k, "argument #" .. k .. " not forwarded (got " .. tostring(seen[k]) .. ")") end print("OK runEffectFn10 forwards all ten arguments") diff --git a/treefmt.nix b/treefmt.nix new file mode 100644 index 0000000..0f57573 --- /dev/null +++ b/treefmt.nix @@ -0,0 +1,43 @@ +{ pkgs, ... }: +{ + projectRootFile = "flake.nix"; + + # Nix — RFC 166 formatter. + programs.nixfmt.enable = true; + + # Dhall — spago.dhall / packages.dhall layout. + programs.dhall.enable = true; + + # PureScript — purs-tidy is not a first-class treefmt program, so wire it via + # the generic mechanism. It picks up `.tidyrc.json` from the project root. + settings.formatter.purs-tidy = { + command = "${pkgs.purs-tidy}/bin/purs-tidy"; + options = [ "format-in-place" ]; + includes = [ "*.purs" ]; + }; + + # Lua FFI — LuaFormatter keeps the parentheses pslua's foreign-file parser + # requires (unlike StyLua, which strips them). Config in `.lua-format`. + settings.formatter.lua-format = { + command = "${pkgs.luaformatter}/bin/lua-format"; + options = [ + "-i" + "-c" + ".lua-format" + ]; + includes = [ "*.lua" ]; + }; + + # Never format generated output or vendored trees. + settings.global.excludes = [ + "dist/*" + "output/*" + ".spago/*" + "node_modules/*" + "*.lock" + "flake.lock" + "spago.lock" + ".tidyrc.json" + ".lua-format" + ]; +}