From 7cd150912fc9300ad703224dc874b2fe7696d103 Mon Sep 17 00:00:00 2001 From: Yura Lazarev Date: Sun, 14 Jun 2026 23:21:23 +0200 Subject: [PATCH] chore: add treefmt formatting (nix fmt) and format the tree Wire treefmt via treefmt-nix: nixfmt, dhall format, purs-tidy (.tidyrc.json) and LuaFormatter for the FFI (.lua-format, kept over StyLua because it preserves the parentheses pslua's parser needs). `nix fmt` formats; the dev shell installs a content-based pre-commit hook and CI runs `nix fmt && git diff --exit-code` (content-based, since the in-place formatters bump mtime and would trip treefmt --fail-on-change). Lua lines budget 130 cols, matching the raised `luacheck --max-line-length`. The bulk of the diff is the first format pass. --- .github/workflows/ci.yml | 5 +- .gitignore | 2 + .lua-format | 10 ++ .tidyrc.json | 10 ++ AGENTS.md | 16 ++- flake.lock | 23 ++- flake.nix | 43 +++++- spago.dhall | 2 +- src/Control/Apply.purs | 24 +++- src/Control/Bind.purs | 3 +- src/Data/BooleanAlgebra.purs | 15 +- src/Data/Bounded.purs | 5 +- src/Data/Bounded/Generic.purs | 20 ++- src/Data/CommutativeRing.purs | 12 +- src/Data/Eq.purs | 3 +- src/Data/Eq/Generic.purs | 9 +- src/Data/Generic/Rep.purs | 6 +- src/Data/HeytingAlgebra.purs | 9 +- src/Data/HeytingAlgebra/Generic.purs | 42 ++++-- src/Data/Monoid.purs | 11 +- src/Data/Monoid/Generic.purs | 10 +- src/Data/Monoid/Multiplicative.purs | 4 +- src/Data/Ord.purs | 3 +- src/Data/Ord/Generic.purs | 13 +- src/Data/Reflectable.purs | 7 +- src/Data/Ring.purs | 11 +- src/Data/Ring/Generic.purs | 18 ++- src/Data/Semigroup.lua | 8 +- src/Data/Semigroup.purs | 6 +- src/Data/Semigroup/Generic.purs | 20 ++- src/Data/Semiring.purs | 6 +- src/Data/Semiring/Generic.purs | 22 ++- src/Data/Show.purs | 6 +- src/Data/Show/Generic.purs | 6 +- src/Data/Symbol.purs | 3 +- src/Record/Unsafe.purs | 3 +- test/Data/Generic/Rep.purs | 44 ++++-- test/Test/Main.purs | 204 +++++++++++++++------------ treefmt.nix | 43 ++++++ 39 files changed, 519 insertions(+), 188 deletions(-) create mode 100644 .lua-format create mode 100644 .tidyrc.json create mode 100644 treefmt.nix diff --git a/.github/workflows/ci.yml b/.github/workflows/ci.yml index d624d2e5..4dc2d200 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 db67e9ad..e0705282 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 00000000..2945014e --- /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 00000000..8636af8f --- /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 dde531ae..a312901a 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 6b6c4177..c47b792e 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 51988659..4d86c4b0 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 9b25c8ac..49d35bda 100644 --- a/spago.dhall +++ b/spago.dhall @@ -1,5 +1,5 @@ { name = "purescript-lua-prelude" -, dependencies = [ ] : List Text +, dependencies = [] : List Text , packages = ./packages.dhall , sources = [ "src/**/*.purs" ] } diff --git a/src/Control/Apply.purs b/src/Control/Apply.purs index 6cde1c85..db17784e 100644 --- a/src/Control/Apply.purs +++ b/src/Control/Apply.purs @@ -90,15 +90,33 @@ lift2 f a b = f <$> a <*> b -- | Lift a function of three arguments to a function which accepts and returns -- | values wrapped with the type constructor `f`. -lift3 :: forall a b c d f. Apply f => (a -> b -> c -> d) -> f a -> f b -> f c -> f d +lift3 + :: forall a b c d f. Apply f => (a -> b -> c -> d) -> f a -> f b -> f c -> f d lift3 f a b c = f <$> a <*> b <*> c -- | Lift a function of four arguments to a function which accepts and returns -- | values wrapped with the type constructor `f`. -lift4 :: forall a b c d e f. Apply f => (a -> b -> c -> d -> e) -> f a -> f b -> f c -> f d -> f e +lift4 + :: forall a b c d e f + . Apply f + => (a -> b -> c -> d -> e) + -> f a + -> f b + -> f c + -> f d + -> f e lift4 f a b c d = f <$> a <*> b <*> c <*> d -- | Lift a function of five arguments to a function which accepts and returns -- | values wrapped with the type constructor `f`. -lift5 :: forall a b c d e f g. Apply f => (a -> b -> c -> d -> e -> g) -> f a -> f b -> f c -> f d -> f e -> f g +lift5 + :: forall a b c d e f g + . Apply f + => (a -> b -> c -> d -> e -> g) + -> f a + -> f b + -> f c + -> f d + -> f e + -> f g lift5 f a b c d e = f <$> a <*> b <*> c <*> d <*> e diff --git a/src/Control/Bind.purs b/src/Control/Bind.purs index c6d8a6ae..f0311838 100644 --- a/src/Control/Bind.purs +++ b/src/Control/Bind.purs @@ -132,7 +132,8 @@ composeKleisli f g a = f a >>= g infixr 1 composeKleisli as >=> -- | Backwards Kleisli composition. -composeKleisliFlipped :: forall a b c m. Bind m => (b -> m c) -> (a -> m b) -> a -> m c +composeKleisliFlipped + :: forall a b c m. Bind m => (b -> m c) -> (a -> m b) -> a -> m c composeKleisliFlipped f g a = f =<< g a infixr 1 composeKleisliFlipped as <=< diff --git a/src/Data/BooleanAlgebra.purs b/src/Data/BooleanAlgebra.purs index 622caee5..96e8650d 100644 --- a/src/Data/BooleanAlgebra.purs +++ b/src/Data/BooleanAlgebra.purs @@ -24,13 +24,22 @@ class HeytingAlgebra a <= BooleanAlgebra a instance booleanAlgebraBoolean :: BooleanAlgebra Boolean instance booleanAlgebraUnit :: BooleanAlgebra Unit instance booleanAlgebraFn :: BooleanAlgebra b => BooleanAlgebra (a -> b) -instance booleanAlgebraRecord :: (RL.RowToList row list, BooleanAlgebraRecord list row row) => BooleanAlgebra (Record row) +instance booleanAlgebraRecord :: + ( RL.RowToList row list + , BooleanAlgebraRecord list row row + ) => + BooleanAlgebra (Record row) + instance booleanAlgebraProxy :: BooleanAlgebra (Proxy a) -- | A class for records where all fields have `BooleanAlgebra` instances, used -- | to implement the `BooleanAlgebra` instance for records. -class BooleanAlgebraRecord :: RL.RowList Type -> Row Type -> Row Type -> Constraint -class HeytingAlgebraRecord rowlist row subrow <= BooleanAlgebraRecord rowlist row subrow | rowlist -> subrow +class BooleanAlgebraRecord + :: RL.RowList Type -> Row Type -> Row Type -> Constraint +class + HeytingAlgebraRecord rowlist row subrow <= + BooleanAlgebraRecord rowlist row subrow + | rowlist -> subrow instance booleanAlgebraRecordNil :: BooleanAlgebraRecord RL.Nil row () diff --git a/src/Data/Bounded.purs b/src/Data/Bounded.purs index 91fec94d..19d3488b 100644 --- a/src/Data/Bounded.purs +++ b/src/Data/Bounded.purs @@ -68,7 +68,10 @@ instance boundedProxy :: Bounded (Proxy a) where top = Proxy class BoundedRecord :: RL.RowList Type -> Row Type -> Row Type -> Constraint -class OrdRecord rowlist row <= BoundedRecord rowlist row subrow | rowlist -> subrow where +class + OrdRecord rowlist row <= + BoundedRecord rowlist row subrow + | rowlist -> subrow where topRecord :: Proxy rowlist -> Proxy row -> Record subrow bottomRecord :: Proxy rowlist -> Proxy row -> Record subrow diff --git a/src/Data/Bounded/Generic.purs b/src/Data/Bounded/Generic.purs index c7e2e2ed..415088ab 100644 --- a/src/Data/Bounded/Generic.purs +++ b/src/Data/Bounded/Generic.purs @@ -23,10 +23,16 @@ instance genericBottomArgument :: Bounded a => GenericBottom (Argument a) where instance genericBottomSum :: GenericBottom a => GenericBottom (Sum a b) where genericBottom' = Inl genericBottom' -instance genericBottomProduct :: (GenericBottom a, GenericBottom b) => GenericBottom (Product a b) where +instance genericBottomProduct :: + ( GenericBottom a + , GenericBottom b + ) => + GenericBottom (Product a b) where genericBottom' = Product genericBottom' genericBottom' -instance genericBottomConstructor :: GenericBottom a => GenericBottom (Constructor name a) where +instance genericBottomConstructor :: + GenericBottom a => + GenericBottom (Constructor name a) where genericBottom' = Constructor genericBottom' class GenericTop a where @@ -41,10 +47,16 @@ instance genericTopArgument :: Bounded a => GenericTop (Argument a) where instance genericTopSum :: GenericTop b => GenericTop (Sum a b) where genericTop' = Inr genericTop' -instance genericTopProduct :: (GenericTop a, GenericTop b) => GenericTop (Product a b) where +instance genericTopProduct :: + ( GenericTop a + , GenericTop b + ) => + GenericTop (Product a b) where genericTop' = Product genericTop' genericTop' -instance genericTopConstructor :: GenericTop a => GenericTop (Constructor name a) where +instance genericTopConstructor :: + GenericTop a => + GenericTop (Constructor name a) where genericTop' = Constructor genericTop' -- | A `Generic` implementation of the `bottom` member from the `Bounded` type class. diff --git a/src/Data/CommutativeRing.purs b/src/Data/CommutativeRing.purs index 38e6e27e..b8eaaedd 100644 --- a/src/Data/CommutativeRing.purs +++ b/src/Data/CommutativeRing.purs @@ -26,12 +26,20 @@ instance commutativeRingInt :: CommutativeRing Int instance commutativeRingNumber :: CommutativeRing Number instance commutativeRingUnit :: CommutativeRing Unit instance commutativeRingFn :: CommutativeRing b => CommutativeRing (a -> b) -instance commutativeRingRecord :: (RL.RowToList row list, CommutativeRingRecord list row row) => CommutativeRing (Record row) +instance commutativeRingRecord :: + ( RL.RowToList row list + , CommutativeRingRecord list row row + ) => + CommutativeRing (Record row) + instance commutativeRingProxy :: CommutativeRing (Proxy a) -- | A class for records where all fields have `CommutativeRing` instances, used -- | to implement the `CommutativeRing` instance for records. -class RingRecord rowlist row subrow <= CommutativeRingRecord rowlist row subrow | rowlist -> subrow +class + RingRecord rowlist row subrow <= + CommutativeRingRecord rowlist row subrow + | rowlist -> subrow instance commutativeRingRecordNil :: CommutativeRingRecord RL.Nil row () diff --git a/src/Data/Eq.purs b/src/Data/Eq.purs index c39893e6..49ca0138 100644 --- a/src/Data/Eq.purs +++ b/src/Data/Eq.purs @@ -82,7 +82,8 @@ foreign import eqNumberImpl :: Number -> Number -> Boolean foreign import eqCharImpl :: Char -> Char -> Boolean foreign import eqStringImpl :: String -> String -> Boolean -foreign import eqArrayImpl :: forall a. (a -> a -> Boolean) -> Array a -> Array a -> Boolean +foreign import eqArrayImpl + :: forall a. (a -> a -> Boolean) -> Array a -> Array a -> Boolean -- | The `Eq1` type class represents type constructors with decidable equality. class Eq1 f where diff --git a/src/Data/Eq/Generic.purs b/src/Data/Eq/Generic.purs index 1c9e1386..b1badd06 100644 --- a/src/Data/Eq/Generic.purs +++ b/src/Data/Eq/Generic.purs @@ -21,8 +21,13 @@ instance genericEqSum :: (GenericEq a, GenericEq b) => GenericEq (Sum a b) where genericEq' (Inr b1) (Inr b2) = genericEq' b1 b2 genericEq' _ _ = false -instance genericEqProduct :: (GenericEq a, GenericEq b) => GenericEq (Product a b) where - genericEq' (Product a1 b1) (Product a2 b2) = genericEq' a1 a2 && genericEq' b1 b2 +instance genericEqProduct :: + ( GenericEq a + , GenericEq b + ) => + GenericEq (Product a b) where + genericEq' (Product a1 b1) (Product a2 b2) = genericEq' a1 a2 && genericEq' b1 + b2 instance genericEqConstructor :: GenericEq a => GenericEq (Constructor name a) where genericEq' (Constructor a1) (Constructor a2) = genericEq' a1 a2 diff --git a/src/Data/Generic/Rep.purs b/src/Data/Generic/Rep.purs index c3de434a..dee2496c 100644 --- a/src/Data/Generic/Rep.purs +++ b/src/Data/Generic/Rep.purs @@ -44,7 +44,11 @@ instance showProduct :: (Show a, Show b) => Show (Product a b) where newtype Constructor (name :: Symbol) a = Constructor a instance showConstructor :: (IsSymbol name, Show a) => Show (Constructor name a) where - show (Constructor a) = "(Constructor @" <> show (reflectSymbol (Proxy :: Proxy name)) <> " " <> show a <> ")" + show (Constructor a) = "(Constructor @" + <> show (reflectSymbol (Proxy :: Proxy name)) + <> " " + <> show a + <> ")" -- | A representation for an argument in a data constructor. newtype Argument a = Argument a diff --git a/src/Data/HeytingAlgebra.purs b/src/Data/HeytingAlgebra.purs index 26387398..e8f1d6d2 100644 --- a/src/Data/HeytingAlgebra.purs +++ b/src/Data/HeytingAlgebra.purs @@ -92,7 +92,11 @@ instance heytingAlgebraProxy :: HeytingAlgebra (Proxy a) where not _ = Proxy tt = Proxy -instance heytingAlgebraRecord :: (RL.RowToList row list, HeytingAlgebraRecord list row row) => HeytingAlgebra (Record row) where +instance heytingAlgebraRecord :: + ( RL.RowToList row list + , HeytingAlgebraRecord list row row + ) => + HeytingAlgebra (Record row) where ff = ffRecord (Proxy :: Proxy list) (Proxy :: Proxy row) tt = ttRecord (Proxy :: Proxy list) (Proxy :: Proxy row) conj = conjRecord (Proxy :: Proxy list) @@ -106,7 +110,8 @@ foreign import boolNot :: Boolean -> Boolean -- | A class for records where all fields have `HeytingAlgebra` instances, used -- | to implement the `HeytingAlgebra` instance for records. -class HeytingAlgebraRecord :: RL.RowList Type -> Row Type -> Row Type -> Constraint +class HeytingAlgebraRecord + :: RL.RowList Type -> Row Type -> Row Type -> Constraint class HeytingAlgebraRecord rowlist row subrow | rowlist -> subrow where ffRecord :: Proxy rowlist -> Proxy row -> Record subrow ttRecord :: Proxy rowlist -> Proxy row -> Record subrow diff --git a/src/Data/HeytingAlgebra/Generic.purs b/src/Data/HeytingAlgebra/Generic.purs index d42e0b65..78c64746 100644 --- a/src/Data/HeytingAlgebra/Generic.purs +++ b/src/Data/HeytingAlgebra/Generic.purs @@ -21,7 +21,9 @@ instance genericHeytingAlgebraNoArguments :: GenericHeytingAlgebra NoArguments w genericDisj' _ _ = NoArguments genericNot' _ = NoArguments -instance genericHeytingAlgebraArgument :: HeytingAlgebra a => GenericHeytingAlgebra (Argument a) where +instance genericHeytingAlgebraArgument :: + HeytingAlgebra a => + GenericHeytingAlgebra (Argument a) where genericFF' = Argument ff genericTT' = Argument tt genericImplies' (Argument x) (Argument y) = Argument (implies x y) @@ -29,20 +31,33 @@ instance genericHeytingAlgebraArgument :: HeytingAlgebra a => GenericHeytingAlge genericDisj' (Argument x) (Argument y) = Argument (disj x y) genericNot' (Argument x) = Argument (not x) -instance genericHeytingAlgebraProduct :: (GenericHeytingAlgebra a, GenericHeytingAlgebra b) => GenericHeytingAlgebra (Product a b) where +instance genericHeytingAlgebraProduct :: + ( GenericHeytingAlgebra a + , GenericHeytingAlgebra b + ) => + GenericHeytingAlgebra (Product a b) where genericFF' = Product genericFF' genericFF' genericTT' = Product genericTT' genericTT' - genericImplies' (Product a1 b1) (Product a2 b2) = Product (genericImplies' a1 a2) (genericImplies' b1 b2) - genericConj' (Product a1 b1) (Product a2 b2) = Product (genericConj' a1 a2) (genericConj' b1 b2) - genericDisj' (Product a1 b1) (Product a2 b2) = Product (genericDisj' a1 a2) (genericDisj' b1 b2) + genericImplies' (Product a1 b1) (Product a2 b2) = Product + (genericImplies' a1 a2) + (genericImplies' b1 b2) + genericConj' (Product a1 b1) (Product a2 b2) = Product (genericConj' a1 a2) + (genericConj' b1 b2) + genericDisj' (Product a1 b1) (Product a2 b2) = Product (genericDisj' a1 a2) + (genericDisj' b1 b2) genericNot' (Product a b) = Product (genericNot' a) (genericNot' b) -instance genericHeytingAlgebraConstructor :: GenericHeytingAlgebra a => GenericHeytingAlgebra (Constructor name a) where +instance genericHeytingAlgebraConstructor :: + GenericHeytingAlgebra a => + GenericHeytingAlgebra (Constructor name a) where genericFF' = Constructor genericFF' genericTT' = Constructor genericTT' - genericImplies' (Constructor a1) (Constructor a2) = Constructor (genericImplies' a1 a2) - genericConj' (Constructor a1) (Constructor a2) = Constructor (genericConj' a1 a2) - genericDisj' (Constructor a1) (Constructor a2) = Constructor (genericDisj' a1 a2) + genericImplies' (Constructor a1) (Constructor a2) = Constructor + (genericImplies' a1 a2) + genericConj' (Constructor a1) (Constructor a2) = Constructor + (genericConj' a1 a2) + genericDisj' (Constructor a1) (Constructor a2) = Constructor + (genericDisj' a1 a2) genericNot' (Constructor a) = Constructor (genericNot' a) -- | A `Generic` implementation of the `ff` member from the `HeytingAlgebra` type class. @@ -54,15 +69,18 @@ genericTT :: forall a rep. Generic a rep => GenericHeytingAlgebra rep => a genericTT = to genericTT' -- | A `Generic` implementation of the `implies` member from the `HeytingAlgebra` type class. -genericImplies :: forall a rep. Generic a rep => GenericHeytingAlgebra rep => a -> a -> a +genericImplies + :: forall a rep. Generic a rep => GenericHeytingAlgebra rep => a -> a -> a genericImplies x y = to $ from x `genericImplies'` from y -- | A `Generic` implementation of the `conj` member from the `HeytingAlgebra` type class. -genericConj :: forall a rep. Generic a rep => GenericHeytingAlgebra rep => a -> a -> a +genericConj + :: forall a rep. Generic a rep => GenericHeytingAlgebra rep => a -> a -> a genericConj x y = to $ from x `genericConj'` from y -- | A `Generic` implementation of the `disj` member from the `HeytingAlgebra` type class. -genericDisj :: forall a rep. Generic a rep => GenericHeytingAlgebra rep => a -> a -> a +genericDisj + :: forall a rep. Generic a rep => GenericHeytingAlgebra rep => a -> a -> a genericDisj x y = to $ from x `genericDisj'` from y -- | A `Generic` implementation of the `not` member from the `HeytingAlgebra` type class. diff --git a/src/Data/Monoid.purs b/src/Data/Monoid.purs index a0c008bc..ce78fc8a 100644 --- a/src/Data/Monoid.purs +++ b/src/Data/Monoid.purs @@ -62,7 +62,11 @@ instance monoidString :: Monoid String where instance monoidArray :: Monoid (Array a) where mempty = [] -instance monoidRecord :: (RL.RowToList row list, MonoidRecord list row row) => Monoid (Record row) where +instance monoidRecord :: + ( RL.RowToList row list + , MonoidRecord list row row + ) => + Monoid (Record row) where mempty = memptyRecord (Proxy :: Proxy list) -- | Append a value to itself a certain number of times. For the @@ -101,7 +105,10 @@ guard false _ = mempty -- | A class for records where all fields have `Monoid` instances, used to -- | implement the `Monoid` instance for records. class MonoidRecord :: RL.RowList Type -> Row Type -> Row Type -> Constraint -class SemigroupRecord rowlist row subrow <= MonoidRecord rowlist row subrow | rowlist -> row subrow where +class + SemigroupRecord rowlist row subrow <= + MonoidRecord rowlist row subrow + | rowlist -> row subrow where memptyRecord :: Proxy rowlist -> Record subrow instance monoidRecordNil :: MonoidRecord RL.Nil row () where diff --git a/src/Data/Monoid/Generic.purs b/src/Data/Monoid/Generic.purs index a73232df..370d7207 100644 --- a/src/Data/Monoid/Generic.purs +++ b/src/Data/Monoid/Generic.purs @@ -13,10 +13,16 @@ class GenericMonoid a where instance genericMonoidNoArguments :: GenericMonoid NoArguments where genericMempty' = NoArguments -instance genericMonoidProduct :: (GenericMonoid a, GenericMonoid b) => GenericMonoid (Product a b) where +instance genericMonoidProduct :: + ( GenericMonoid a + , GenericMonoid b + ) => + GenericMonoid (Product a b) where genericMempty' = Product genericMempty' genericMempty' -instance genericMonoidConstructor :: GenericMonoid a => GenericMonoid (Constructor name a) where +instance genericMonoidConstructor :: + GenericMonoid a => + GenericMonoid (Constructor name a) where genericMempty' = Constructor genericMempty' instance genericMonoidArgument :: Monoid a => GenericMonoid (Argument a) where diff --git a/src/Data/Monoid/Multiplicative.purs b/src/Data/Monoid/Multiplicative.purs index c0552a0f..b9e8b8fb 100644 --- a/src/Data/Monoid/Multiplicative.purs +++ b/src/Data/Monoid/Multiplicative.purs @@ -19,7 +19,9 @@ derive instance eq1Multiplicative :: Eq1 Multiplicative derive newtype instance ordMultiplicative :: Ord a => Ord (Multiplicative a) derive instance ord1Multiplicative :: Ord1 Multiplicative -derive newtype instance boundedMultiplicative :: Bounded a => Bounded (Multiplicative a) +derive newtype instance boundedMultiplicative :: + Bounded a => + Bounded (Multiplicative a) instance showMultiplicative :: Show a => Show (Multiplicative a) where show (Multiplicative a) = "(Multiplicative " <> show a <> ")" diff --git a/src/Data/Ord.purs b/src/Data/Ord.purs index 3890ada5..91660955 100644 --- a/src/Data/Ord.purs +++ b/src/Data/Ord.purs @@ -123,7 +123,8 @@ foreign import ordCharImpl -> Char -> Ordering -foreign import ordArrayImpl :: forall a. (a -> a -> Int) -> Array a -> Array a -> Int +foreign import ordArrayImpl + :: forall a. (a -> a -> Int) -> Array a -> Array a -> Int instance ordOrdering :: Ord Ordering where compare LT LT = EQ diff --git a/src/Data/Ord/Generic.purs b/src/Data/Ord/Generic.purs index b1e2129c..6bb577a4 100644 --- a/src/Data/Ord/Generic.purs +++ b/src/Data/Ord/Generic.purs @@ -22,18 +22,25 @@ instance genericOrdSum :: (GenericOrd a, GenericOrd b) => GenericOrd (Sum a b) w genericCompare' (Inl _) (Inr _) = LT genericCompare' (Inr _) (Inl _) = GT -instance genericOrdProduct :: (GenericOrd a, GenericOrd b) => GenericOrd (Product a b) where +instance genericOrdProduct :: + ( GenericOrd a + , GenericOrd b + ) => + GenericOrd (Product a b) where genericCompare' (Product a1 b1) (Product a2 b2) = case genericCompare' a1 a2 of EQ -> genericCompare' b1 b2 other -> other -instance genericOrdConstructor :: GenericOrd a => GenericOrd (Constructor name a) where +instance genericOrdConstructor :: + GenericOrd a => + GenericOrd (Constructor name a) where genericCompare' (Constructor a1) (Constructor a2) = genericCompare' a1 a2 instance genericOrdArgument :: Ord a => GenericOrd (Argument a) where genericCompare' (Argument a1) (Argument a2) = compare a1 a2 -- | A `Generic` implementation of the `compare` member from the `Ord` type class. -genericCompare :: forall a rep. Generic a rep => GenericOrd rep => a -> a -> Ordering +genericCompare + :: forall a rep. Generic a rep => GenericOrd rep => a -> a -> Ordering genericCompare x y = genericCompare' (from x) (from y) diff --git a/src/Data/Reflectable.purs b/src/Data/Reflectable.purs index fafe5278..d8278ad8 100644 --- a/src/Data/Reflectable.purs +++ b/src/Data/Reflectable.purs @@ -46,7 +46,12 @@ foreign import unsafeCoerce :: forall a b. a -> b -- | twiceOfTerm :: Int -- | twiceOfTerm = reifyType 21 twiceFromType -- | ``` -reifyType :: forall t r. Reifiable t => t -> (forall v. Reflectable v t => Proxy v -> r) -> r +reifyType + :: forall t r + . Reifiable t + => t + -> (forall v. Reflectable v t => Proxy v -> r) + -> r reifyType s f = coerce f { reflectType: \_ -> s } Proxy where coerce diff --git a/src/Data/Ring.purs b/src/Data/Ring.purs index 592f2fff..438a74a4 100644 --- a/src/Data/Ring.purs +++ b/src/Data/Ring.purs @@ -45,7 +45,11 @@ instance ringFn :: Ring b => Ring (a -> b) where instance ringProxy :: Ring (Proxy a) where sub _ _ = Proxy -instance ringRecord :: (RL.RowToList row list, RingRecord list row row) => Ring (Record row) where +instance ringRecord :: + ( RL.RowToList row list + , RingRecord list row row + ) => + Ring (Record row) where sub = subRecord (Proxy :: Proxy list) -- | `negate x` can be used as a shorthand for `zero - x`. @@ -58,7 +62,10 @@ foreign import numSub :: Number -> Number -> Number -- | A class for records where all fields have `Ring` instances, used to -- | implement the `Ring` instance for records. class RingRecord :: RL.RowList Type -> Row Type -> Row Type -> Constraint -class SemiringRecord rowlist row subrow <= RingRecord rowlist row subrow | rowlist -> subrow where +class + SemiringRecord rowlist row subrow <= + RingRecord rowlist row subrow + | rowlist -> subrow where subRecord :: Proxy rowlist -> Record row -> Record row -> Record subrow instance ringRecordNil :: RingRecord RL.Nil row () where diff --git a/src/Data/Ring/Generic.purs b/src/Data/Ring/Generic.purs index 27c38fd6..81ed3e9f 100644 --- a/src/Data/Ring/Generic.purs +++ b/src/Data/Ring/Generic.purs @@ -13,11 +13,19 @@ instance genericRingNoArguments :: GenericRing NoArguments where instance genericRingArgument :: Ring a => GenericRing (Argument a) where genericSub' (Argument x) (Argument y) = Argument (sub x y) -instance genericRingProduct :: (GenericRing a, GenericRing b) => GenericRing (Product a b) where - genericSub' (Product a1 b1) (Product a2 b2) = Product (genericSub' a1 a2) (genericSub' b1 b2) - -instance genericRingConstructor :: GenericRing a => GenericRing (Constructor name a) where - genericSub' (Constructor a1) (Constructor a2) = Constructor (genericSub' a1 a2) +instance genericRingProduct :: + ( GenericRing a + , GenericRing b + ) => + GenericRing (Product a b) where + genericSub' (Product a1 b1) (Product a2 b2) = Product (genericSub' a1 a2) + (genericSub' b1 b2) + +instance genericRingConstructor :: + GenericRing a => + GenericRing (Constructor name a) where + genericSub' (Constructor a1) (Constructor a2) = Constructor + (genericSub' a1 a2) -- | A `Generic` implementation of the `sub` member from the `Ring` type class. genericSub :: forall a rep. Generic a rep => GenericRing rep => a -> a -> a diff --git a/src/Data/Semigroup.lua b/src/Data/Semigroup.lua index 6949b09a..506444d9 100644 --- a/src/Data/Semigroup.lua +++ b/src/Data/Semigroup.lua @@ -5,13 +5,9 @@ return { if #xs == 0 then return ys end if #ys == 0 then return xs end local result = {} - for index, value in ipairs(xs) do - result[index] = value - end + for index, value in ipairs(xs) do result[index] = value end local offset = #result - for index, value in ipairs(ys) do - result[index + offset] = value - end + for index, value in ipairs(ys) do result[index + offset] = value end return result end end) diff --git a/src/Data/Semigroup.purs b/src/Data/Semigroup.purs index 28032270..efac1a93 100644 --- a/src/Data/Semigroup.purs +++ b/src/Data/Semigroup.purs @@ -54,7 +54,11 @@ instance semigroupArray :: Semigroup (Array a) where instance semigroupProxy :: Semigroup (Proxy a) where append _ _ = Proxy -instance semigroupRecord :: (RL.RowToList row list, SemigroupRecord list row row) => Semigroup (Record row) where +instance semigroupRecord :: + ( RL.RowToList row list + , SemigroupRecord list row row + ) => + Semigroup (Record row) where append = appendRecord (Proxy :: Proxy list) foreign import concatString :: String -> String -> String diff --git a/src/Data/Semigroup/Generic.purs b/src/Data/Semigroup/Generic.purs index 5591903d..9e188c31 100644 --- a/src/Data/Semigroup/Generic.purs +++ b/src/Data/Semigroup/Generic.purs @@ -16,16 +16,26 @@ instance genericSemigroupNoConstructors :: GenericSemigroup NoConstructors where instance genericSemigroupNoArguments :: GenericSemigroup NoArguments where genericAppend' a _ = a -instance genericSemigroupProduct :: (GenericSemigroup a, GenericSemigroup b) => GenericSemigroup (Product a b) where +instance genericSemigroupProduct :: + ( GenericSemigroup a + , GenericSemigroup b + ) => + GenericSemigroup (Product a b) where genericAppend' (Product a1 b1) (Product a2 b2) = Product (genericAppend' a1 a2) (genericAppend' b1 b2) -instance genericSemigroupConstructor :: GenericSemigroup a => GenericSemigroup (Constructor name a) where - genericAppend' (Constructor a1) (Constructor a2) = Constructor (genericAppend' a1 a2) +instance genericSemigroupConstructor :: + GenericSemigroup a => + GenericSemigroup (Constructor name a) where + genericAppend' (Constructor a1) (Constructor a2) = Constructor + (genericAppend' a1 a2) -instance genericSemigroupArgument :: Semigroup a => GenericSemigroup (Argument a) where +instance genericSemigroupArgument :: + Semigroup a => + GenericSemigroup (Argument a) where genericAppend' (Argument a1) (Argument a2) = Argument (append a1 a2) -- | A `Generic` implementation of the `append` member from the `Semigroup` type class. -genericAppend :: forall a rep. Generic a rep => GenericSemigroup rep => a -> a -> a +genericAppend + :: forall a rep. Generic a rep => GenericSemigroup rep => a -> a -> a genericAppend x y = to (genericAppend' (from x) (from y)) diff --git a/src/Data/Semiring.purs b/src/Data/Semiring.purs index b764425c..2798870a 100644 --- a/src/Data/Semiring.purs +++ b/src/Data/Semiring.purs @@ -80,7 +80,11 @@ instance semiringProxy :: Semiring (Proxy a) where one = Proxy zero = Proxy -instance semiringRecord :: (RL.RowToList row list, SemiringRecord list row row) => Semiring (Record row) where +instance semiringRecord :: + ( RL.RowToList row list + , SemiringRecord list row row + ) => + Semiring (Record row) where add = addRecord (Proxy :: Proxy list) mul = mulRecord (Proxy :: Proxy list) one = oneRecord (Proxy :: Proxy list) (Proxy :: Proxy row) diff --git a/src/Data/Semiring/Generic.purs b/src/Data/Semiring/Generic.purs index 6bf60d17..e4bb0378 100644 --- a/src/Data/Semiring/Generic.purs +++ b/src/Data/Semiring/Generic.purs @@ -22,16 +22,26 @@ instance genericSemiringArgument :: Semiring a => GenericSemiring (Argument a) w genericMul' (Argument x) (Argument y) = Argument (mul x y) genericOne' = Argument one -instance genericSemiringProduct :: (GenericSemiring a, GenericSemiring b) => GenericSemiring (Product a b) where - genericAdd' (Product a1 b1) (Product a2 b2) = Product (genericAdd' a1 a2) (genericAdd' b1 b2) +instance genericSemiringProduct :: + ( GenericSemiring a + , GenericSemiring b + ) => + GenericSemiring (Product a b) where + genericAdd' (Product a1 b1) (Product a2 b2) = Product (genericAdd' a1 a2) + (genericAdd' b1 b2) genericZero' = Product genericZero' genericZero' - genericMul' (Product a1 b1) (Product a2 b2) = Product (genericMul' a1 a2) (genericMul' b1 b2) + genericMul' (Product a1 b1) (Product a2 b2) = Product (genericMul' a1 a2) + (genericMul' b1 b2) genericOne' = Product genericOne' genericOne' -instance genericSemiringConstructor :: GenericSemiring a => GenericSemiring (Constructor name a) where - genericAdd' (Constructor a1) (Constructor a2) = Constructor (genericAdd' a1 a2) +instance genericSemiringConstructor :: + GenericSemiring a => + GenericSemiring (Constructor name a) where + genericAdd' (Constructor a1) (Constructor a2) = Constructor + (genericAdd' a1 a2) genericZero' = Constructor genericZero' - genericMul' (Constructor a1) (Constructor a2) = Constructor (genericMul' a1 a2) + genericMul' (Constructor a1) (Constructor a2) = Constructor + (genericMul' a1 a2) genericOne' = Constructor genericOne' -- | A `Generic` implementation of the `zero` member from the `Semiring` type class. diff --git a/src/Data/Show.purs b/src/Data/Show.purs index 93c62076..9991f342 100644 --- a/src/Data/Show.purs +++ b/src/Data/Show.purs @@ -67,8 +67,7 @@ class ShowRecordFields rowlist row where instance showRecordFieldsNil :: ShowRecordFields RL.Nil row where showRecordFields _ _ = "" -else -instance showRecordFieldsConsNil :: +else instance showRecordFieldsConsNil :: ( IsSymbol key , Show focus ) => @@ -77,8 +76,7 @@ instance showRecordFieldsConsNil :: where key = reflectSymbol (Proxy :: Proxy key) focus = unsafeGet key record :: focus -else -instance showRecordFieldsCons :: +else instance showRecordFieldsCons :: ( IsSymbol key , ShowRecordFields rowlistTail row , Show focus diff --git a/src/Data/Show/Generic.purs b/src/Data/Show/Generic.purs index 297986a4..7b02b5f1 100644 --- a/src/Data/Show/Generic.purs +++ b/src/Data/Show/Generic.purs @@ -23,7 +23,11 @@ instance genericShowNoConstructors :: GenericShow NoConstructors where instance genericShowArgsNoArguments :: GenericShowArgs NoArguments where genericShowArgs _ = [] -instance genericShowSum :: (GenericShow a, GenericShow b) => GenericShow (Sum a b) where +instance genericShowSum :: + ( GenericShow a + , GenericShow b + ) => + GenericShow (Sum a b) where genericShow' (Inl a) = genericShow' a genericShow' (Inr b) = genericShow' b diff --git a/src/Data/Symbol.purs b/src/Data/Symbol.purs index 80f289e3..e09e5f03 100644 --- a/src/Data/Symbol.purs +++ b/src/Data/Symbol.purs @@ -13,7 +13,8 @@ class IsSymbol (sym :: Symbol) where -- local definition for use in `reifySymbol` foreign import unsafeCoerce :: forall a b. a -> b -reifySymbol :: forall r. String -> (forall sym. IsSymbol sym => Proxy sym -> r) -> r +reifySymbol + :: forall r. String -> (forall sym. IsSymbol sym => Proxy sym -> r) -> r reifySymbol s f = coerce f { reflectSymbol: \_ -> s } Proxy where coerce diff --git a/src/Record/Unsafe.purs b/src/Record/Unsafe.purs index adeaade7..d35d3cf6 100644 --- a/src/Record/Unsafe.purs +++ b/src/Record/Unsafe.purs @@ -18,7 +18,8 @@ foreign import unsafeGet :: forall r a. String -> Record r -> a -- | -- | The output record's row is unspecified so can be coerced to any row. If the -- | output type is incorrect it will cause a runtime error elsewhere. -foreign import unsafeSet :: forall r1 r2 a. String -> a -> Record r1 -> Record r2 +foreign import unsafeSet + :: forall r1 r2 a. String -> a -> Record r1 -> Record r2 -- | Unsafely removes a value on a record, using a string for the key. -- | diff --git a/test/Data/Generic/Rep.purs b/test/Data/Generic/Rep.purs index 45c4c1e3..d127c3dc 100644 --- a/test/Data/Generic/Rep.purs +++ b/test/Data/Generic/Rep.purs @@ -99,7 +99,11 @@ instance semiringPair :: (Semiring a, Semiring b) => Semiring (Pair a b) where instance ringPair :: (Ring a, Ring b) => Ring (Pair a b) where sub (Pair x1 y1) (Pair x2 y2) = Pair (sub x1 x2) (sub y1 y2) -instance heytingAlgebraPair :: (HeytingAlgebra a, HeytingAlgebra b) => HeytingAlgebra (Pair a b) where +instance heytingAlgebraPair :: + ( HeytingAlgebra a + , HeytingAlgebra b + ) => + HeytingAlgebra (Pair a b) where tt = Pair tt tt ff = Pair ff ff implies (Pair x1 y1) (Pair x2 y2) = Pair (x1 `implies` x2) (y1 `implies` y2) @@ -147,16 +151,21 @@ instance booleanAlgebraB1 :: BooleanAlgebra B1 testGenericRep :: AlmostEff testGenericRep = do assert "Checking show" $ - show (cons 1 (cons 2 Nil)) == "(Cons { head: 1, tail: (Cons { head: 2, tail: Nil }) })" + show (cons 1 (cons 2 Nil)) == + "(Cons { head: 1, tail: (Cons { head: 2, tail: Nil }) })" assert "Checking show for generic types: Inl, NoArguments" $ - show (G.from (Nil :: List Int)) == "(Inl (Constructor @\"Nil\" NoArguments))" + show (G.from (Nil :: List Int)) == + "(Inl (Constructor @\"Nil\" NoArguments))" - assert "Checking show for generic types: Inr, Constructor, and Single Argument" $ - show (G.from $ cons 1 Nil) == "(Inr (Constructor @\"Cons\" (Argument { head: 1, tail: Nil })))" + assert + "Checking show for generic types: Inr, Constructor, and Single Argument" $ + show (G.from $ cons 1 Nil) == + "(Inr (Constructor @\"Cons\" (Argument { head: 1, tail: Nil })))" assert "Checking show for generic types: Product" $ - show (G.from $ Pair 1 2) == "(Constructor @\"Pair\" (Product (Argument 1) (Argument 2)))" + show (G.from $ Pair 1 2) == + "(Constructor @\"Pair\" (Product (Argument 1) (Argument 2)))" assert "Checking equality" $ cons 1 (cons 2 Nil) == cons 1 (cons 2 Nil) @@ -198,13 +207,19 @@ testGenericRep = do (one :: A1) == A1 (Pair (Pair 1 { a: 1 }) { a: 1 }) assert "Checking add" $ - A1 (Pair (Pair 100 { a: 10 }) { a: 20 }) + A1 (Pair (Pair 50 { a: 30 }) { a: 40 }) == A1 (Pair (Pair 150 { a: 40 }) { a: 60 }) + A1 (Pair (Pair 100 { a: 10 }) { a: 20 }) + A1 + (Pair (Pair 50 { a: 30 }) { a: 40 }) == A1 + (Pair (Pair 150 { a: 40 }) { a: 60 }) assert "Checking mul" $ - A1 (Pair (Pair 100 { a: 10 }) { a: 20 }) * A1 (Pair (Pair 50 { a: 30 }) { a: 40 }) == A1 (Pair (Pair 5000 { a: 300 }) { a: 800 }) + A1 (Pair (Pair 100 { a: 10 }) { a: 20 }) * A1 + (Pair (Pair 50 { a: 30 }) { a: 40 }) == A1 + (Pair (Pair 5000 { a: 300 }) { a: 800 }) assert "Checking sub" $ - A1 (Pair (Pair 100 { a: 10 }) { a: 20 }) - A1 (Pair (Pair 50 { a: 30 }) { a: 40 }) == A1 (Pair (Pair 50 { a: -20 }) { a: -20 }) + A1 (Pair (Pair 100 { a: 10 }) { a: 20 }) - A1 + (Pair (Pair 50 { a: 30 }) { a: 40 }) == A1 + (Pair (Pair 50 { a: -20 }) { a: -20 }) assert "Checking ff" $ (ff :: B1) == B1 (Pair (Pair false { a: false }) { a: false }) @@ -213,10 +228,15 @@ testGenericRep = do (tt :: B1) == B1 (Pair (Pair true { a: true }) { a: true }) assert "Checking conj" $ - (B1 (Pair (Pair true { a: false }) { a: true }) && B1 (Pair (Pair false { a: false }) { a: true })) == B1 (Pair (Pair false { a: false }) { a: true }) + ( B1 (Pair (Pair true { a: false }) { a: true }) && B1 + (Pair (Pair false { a: false }) { a: true }) + ) == B1 (Pair (Pair false { a: false }) { a: true }) assert "Checking disj" $ - (B1 (Pair (Pair true { a: false }) { a: true }) || B1 (Pair (Pair false { a: false }) { a: true })) == B1 (Pair (Pair true { a: false }) { a: true }) + ( B1 (Pair (Pair true { a: false }) { a: true }) || B1 + (Pair (Pair false { a: false }) { a: true }) + ) == B1 (Pair (Pair true { a: false }) { a: true }) assert "Checking not" $ - not B1 (Pair (Pair true { a: false }) { a: true }) == B1 (Pair (Pair false { a: true }) { a: false }) + not B1 (Pair (Pair true { a: false }) { a: true }) == B1 + (Pair (Pair false { a: true }) { a: false }) diff --git a/test/Test/Main.purs b/test/Test/Main.purs index 13ea2cce..49880338 100644 --- a/test/Test/Main.purs +++ b/test/Test/Main.purs @@ -12,70 +12,72 @@ import Type.Proxy (Proxy(..)) main :: AlmostEff main = do - testNumberShow show - testOrderings - testOrdUtils - testIntDivMod - testIntDegree - testRecordInstances - testGenericRep - testReflectType - testReifyType - testSignum + testNumberShow show + testOrderings + testOrdUtils + testIntDivMod + testIntDegree + testRecordInstances + testGenericRep + testReflectType + testReifyType + testSignum foreign import testNumberShow :: (Number -> String) -> AlmostEff testOrd :: forall a. Ord a => Show a => a -> a -> Ordering -> AlmostEff testOrd x y ord = - assert - ("(compare " <> show x <> " " <> show y <> " ) is not equal to " <> show ord) - $ (compare x y) == ord + assert + ( "(compare " <> show x <> " " <> show y <> " ) is not equal to " <> show + ord + ) + $ (compare x y) == ord nan :: Number -nan = 0.0/0.0 +nan = 0.0 / 0.0 plusInfinity :: Number -plusInfinity = 1.0/0.0 +plusInfinity = 1.0 / 0.0 minusInfinity :: Number -minusInfinity = -1.0/0.0 +minusInfinity = -1.0 / 0.0 testOrderings :: AlmostEff testOrderings = do - assert "NaN shouldn't be equal to itself" $ nan /= nan - assert "NaN shouldn't be equal to itself" $ (compare nan nan) /= EQ - testOrd 1.0 2.0 LT - testOrd 2.0 1.0 GT - testOrd 1.0 (-2.0) GT - testOrd (-2.0) 1.0 LT - testOrd minusInfinity plusInfinity LT - testOrd minusInfinity 0.0 LT - testOrd plusInfinity 0.0 GT - testOrd plusInfinity minusInfinity GT - testOrd 1.0 nan GT - testOrd nan 1.0 GT - testOrd nan plusInfinity GT - testOrd plusInfinity nan GT - assert "1 > NaN should be false" $ (1.0 > nan) == false - assert "1 < NaN should be false" $ (1.0 < nan) == false - assert "NaN > 1 should be false" $ (nan > 1.0) == false - assert "NaN < 1 should be false" $ (nan < 1.0) == false - assert "NaN == 1 should be false" $ nan /= 1.0 - testOrd (1 / 0) 0 EQ - testOrd (mod 1 0) 0 EQ - testOrd 'a' 'b' LT - testOrd 'b' 'A' GT - testOrd "10" "0" GT - testOrd "10" "2" LT - testOrd true true EQ - testOrd false false EQ - testOrd false true LT - testOrd true false GT - testOrd ([] :: Array Int) [] EQ - testOrd [1, 0] [1] GT - testOrd [1] [1, 0] LT - testOrd [1, 1] [1, 0] GT - testOrd [1, -1] [1, 0] LT + assert "NaN shouldn't be equal to itself" $ nan /= nan + assert "NaN shouldn't be equal to itself" $ (compare nan nan) /= EQ + testOrd 1.0 2.0 LT + testOrd 2.0 1.0 GT + testOrd 1.0 (-2.0) GT + testOrd (-2.0) 1.0 LT + testOrd minusInfinity plusInfinity LT + testOrd minusInfinity 0.0 LT + testOrd plusInfinity 0.0 GT + testOrd plusInfinity minusInfinity GT + testOrd 1.0 nan GT + testOrd nan 1.0 GT + testOrd nan plusInfinity GT + testOrd plusInfinity nan GT + assert "1 > NaN should be false" $ (1.0 > nan) == false + assert "1 < NaN should be false" $ (1.0 < nan) == false + assert "NaN > 1 should be false" $ (nan > 1.0) == false + assert "NaN < 1 should be false" $ (nan < 1.0) == false + assert "NaN == 1 should be false" $ nan /= 1.0 + testOrd (1 / 0) 0 EQ + testOrd (mod 1 0) 0 EQ + testOrd 'a' 'b' LT + testOrd 'b' 'A' GT + testOrd "10" "0" GT + testOrd "10" "2" LT + testOrd true true EQ + testOrd false false EQ + testOrd false true LT + testOrd true false GT + testOrd ([] :: Array Int) [] EQ + testOrd [ 1, 0 ] [ 1 ] GT + testOrd [ 1 ] [ 1, 0 ] LT + testOrd [ 1, 1 ] [ 1, 0 ] GT + testOrd [ 1, -1 ] [ 1, 0 ] LT testOrdUtils :: AlmostEff testOrdUtils = do @@ -106,49 +108,58 @@ testIntDivMod = do q = a / b r = a `mod` b msg = show a <> " / " <> show b <> ": " - in do - assert (msg <> "Quotient/remainder law") $ - q * b + r == a - assert (msg <> "Remainder should be between 0 and `abs b`, got: " <> show r) $ - 0 <= r && r < abs b + in + do + assert (msg <> "Quotient/remainder law") $ + q * b + r == a + assert + (msg <> "Remainder should be between 0 and `abs b`, got: " <> show r) + $ + 0 <= r && r < abs b testIntDegree :: AlmostEff testIntDegree = do - let bot = bottom :: Int - assert "degree returns absolute integers" $ degree (-4) == 4 - assert "degree returns absolute integers" $ degree 4 == 4 - assert "degree returns absolute integers" $ degree bot >= 0 - assert "degree does not return out-of-bounds integers" $ degree bot <= top + let bot = bottom :: Int + assert "degree returns absolute integers" $ degree (-4) == 4 + assert "degree returns absolute integers" $ degree 4 == 4 + assert "degree returns absolute integers" $ degree bot >= 0 + assert "degree does not return out-of-bounds integers" $ degree bot <= top testRecordInstances :: AlmostEff testRecordInstances = do assert "Record equality" $ { a: 1 } == { a: 1 } assert "Record inequality" $ { a: 2 } /= { a: 1 } - assert "Record show nil" $ show { } == "{}" + assert "Record show nil" $ show {} == "{}" assert "Record show one" $ show { a: 1 } == "{ a: 1 }" assert "Record show more" $ show { a: 1, b: 2 } == "{ a: 1, b: 2 }" - assert "Record +" $ ({ a: 1, b: 2.0 } + { a: 0, b: (-2.0) }) == { a: 1, b: 0.0 } - assert "Record *" $ ({ a: 1, b: 2.0 } * { a: 0, b: (-2.0) }) == { a: 0, b: -4.0 } + assert "Record +" $ ({ a: 1, b: 2.0 } + { a: 0, b: (-2.0) }) == + { a: 1, b: 0.0 } + assert "Record *" $ ({ a: 1, b: 2.0 } * { a: 0, b: (-2.0) }) == + { a: 0, b: -4.0 } assert "Record one" $ one == { a: 1, b: 1.0 } assert "Record zero" $ zero == { a: 0, b: 0.0 } assert "Record sub" $ { a: 2, b: 2.0 } - { a: 1, b: 1.0 } == { a: 1, b: 1.0 } - assert "Record append" $ { a: [], b: "T" } <> { a: [1], b: "OM" } == { a: [1], b: "TOM" } + assert "Record append" $ { a: [], b: "T" } <> { a: [ 1 ], b: "OM" } == + { a: [ 1 ], b: "TOM" } assert "Record mempty" $ mempty == { a: [] :: Array Int, b: "" } assert "Record ff" $ ff == { a: false, b: false } assert "Record tt" $ tt == { a: true, b: true } assert "Record not" $ not { a: true, b: false } == { a: false, b: true } - assert "Record conj" $ conj - { a: true, b: false, c: true, d: false } - { a: true, b: true, c: false, d: false } - == { a: true, b: false, c: false, d: false } - assert "Record disj" $ disj - { a: true, b: false, c: true, d: false } - { a: true, b: true, c: false, d: false } - == { a: true, b: true, c: true, d: false } - assert "Record implies" $ implies - { a: true, b: false, c: true, d: false } - { a: true, b: true, c: false, d: false } - == { a: true, b: true, c: false, d: true } + assert "Record conj" $ + conj + { a: true, b: false, c: true, d: false } + { a: true, b: true, c: false, d: false } + == { a: true, b: false, c: false, d: false } + assert "Record disj" $ + disj + { a: true, b: false, c: true, d: false } + { a: true, b: true, c: false, d: false } + == { a: true, b: true, c: true, d: false } + assert "Record implies" $ + implies + { a: true, b: false, c: true, d: false } + { a: true, b: true, c: false, d: false } + == { a: true, b: true, c: false, d: true } testOrd { a: 0, b: "hello" } { a: 42, b: "hello" } LT testOrd { a: 42, b: "hello" } { a: 0, b: "hello" } GT testOrd { a: 42, b: "hello" } { a: 42, b: "hello" } EQ @@ -156,27 +167,36 @@ testRecordInstances = do testOrd { a: 42, b: "hello" } { a: 42, b: "hell" } GT assert "Record bottom" $ (bottom :: { a :: Boolean }).a - == bottom + == bottom assert "Record top" $ (top :: { a :: Boolean }).a - == top + == top testReflectType :: AlmostEff testReflectType = do - assert "reflectType: Symbol -> String" $ reflectType (Proxy :: _ "erin!") == "erin!" - assert "reflectType: Boolean -> Boolean, True" $ reflectType (Proxy :: _ True) == true - assert "reflectType: Boolean -> Boolean, False" $ reflectType (Proxy :: _ False) == false - assert "reflectType: Ordering -> Ordering, LT" $ reflectType (Proxy :: _ LT) == LT - assert "reflectType: Ordering -> Ordering, GT" $ reflectType (Proxy :: _ GT) == GT - assert "reflectType: Ordering -> Ordering, EQ" $ reflectType (Proxy :: _ EQ) == EQ + assert "reflectType: Symbol -> String" $ reflectType (Proxy :: _ "erin!") == + "erin!" + assert "reflectType: Boolean -> Boolean, True" $ reflectType (Proxy :: _ True) + == true + assert "reflectType: Boolean -> Boolean, False" $ + reflectType (Proxy :: _ False) == false + assert "reflectType: Ordering -> Ordering, LT" $ reflectType (Proxy :: _ LT) + == LT + assert "reflectType: Ordering -> Ordering, GT" $ reflectType (Proxy :: _ GT) + == GT + assert "reflectType: Ordering -> Ordering, EQ" $ reflectType (Proxy :: _ EQ) + == EQ assert "reflectType: Int -> Int, 42" $ reflectType (Proxy :: _ 42) == 42 assert "reflectType: Int -> Int, -42" $ reflectType (Proxy :: _ (-42)) == -42 testReifyType :: AlmostEff testReifyType = do - assert "reifyType: String -> Symbol" $ reifyType "erin!" reflectType == "erin!" - assert "reifyType: Boolean -> Boolean, true" $ reifyType true reflectType == true - assert "reifyType: Boolean -> Boolean, false" $ reifyType false reflectType == false + assert "reifyType: String -> Symbol" $ reifyType "erin!" reflectType == + "erin!" + assert "reifyType: Boolean -> Boolean, true" $ reifyType true reflectType == + true + assert "reifyType: Boolean -> Boolean, false" $ reifyType false reflectType == + false assert "reifyType: Ordering -> Ordering, LT" $ reifyType LT reflectType == LT assert "reifyType: Ordering -> Ordering, GT" $ reifyType GT reflectType == GT assert "reifyType: Ordering -> Ordering, EQ" $ reifyType EQ reflectType == EQ @@ -185,7 +205,9 @@ testReifyType = do testSignum :: AlmostEff testSignum = do - assert "Clarifies what 'signum positive zero' test is doing" $ show (1.0/0.0) == "Infinity" - assert "signum positive zero" $ show (1.0/(signum 0.0)) == "Infinity" - assert "Clarifies what 'signum negative zero' test is doing" $ show (1.0/(-0.0)) == "-Infinity" - assert "signum negative zero" $ show (1.0/(signum (-0.0))) == "-Infinity" + assert "Clarifies what 'signum positive zero' test is doing" $ + show (1.0 / 0.0) == "Infinity" + assert "signum positive zero" $ show (1.0 / (signum 0.0)) == "Infinity" + assert "Clarifies what 'signum negative zero' test is doing" $ + show (1.0 / (-0.0)) == "-Infinity" + assert "signum negative zero" $ show (1.0 / (signum (-0.0))) == "-Infinity" diff --git a/treefmt.nix b/treefmt.nix new file mode 100644 index 00000000..0f575736 --- /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" + ]; +}