From be6e3ddca4a926edb391dc28583ccf1226d02995 Mon Sep 17 00:00:00 2001 From: Thomas Honeyman Date: Wed, 14 Oct 2026 10:56:17 +0000 Subject: [PATCH 01/11] Migrate repository tooling and CI to Spago --- .eslintrc.json | 26 -------------------------- .github/workflows/ci.yml | 33 +++++++++++---------------------- .gitignore | 7 ++++--- .oxfmtrc.json | 3 +++ .tidyrc.json | 10 ++++++++++ CHANGELOG.md | 1 + bower.json | 19 ------------------- package.json | 23 ++++++++++++++++------- spago.yaml | 13 +++++++++++++ 9 files changed, 58 insertions(+), 77 deletions(-) delete mode 100644 .eslintrc.json create mode 100644 .oxfmtrc.json create mode 100644 .tidyrc.json delete mode 100644 bower.json create mode 100644 spago.yaml diff --git a/.eslintrc.json b/.eslintrc.json deleted file mode 100644 index 81104c48..00000000 --- a/.eslintrc.json +++ /dev/null @@ -1,26 +0,0 @@ -{ - "parserOptions": { - "ecmaVersion": 6, - "sourceType": "module" - }, - "extends": "eslint:recommended", - "rules": { - "strict": [2, "global"], - "block-scoped-var": 2, - "consistent-return": 2, - "eqeqeq": [2, "smart"], - "guard-for-in": 2, - "no-caller": 2, - "no-extend-native": 2, - "no-loop-func": 2, - "no-new": 2, - "no-param-reassign": 2, - "no-return-assign": 2, - "no-unused-expressions": 2, - "no-use-before-define": 2, - "radix": [2, "always"], - "indent": [2, 2, { "SwitchCase": 1 }], - "quotes": [2, "double"], - "semi": [2, "always"] - } -} diff --git a/.github/workflows/ci.yml b/.github/workflows/ci.yml index 07fb36b9..2ea241be 100644 --- a/.github/workflows/ci.yml +++ b/.github/workflows/ci.yml @@ -5,30 +5,19 @@ on: branches: [master] pull_request: +permissions: + contents: read + jobs: build: runs-on: ubuntu-latest steps: - - uses: actions/checkout@v2 - - - uses: purescript-contrib/setup-purescript@main - with: - purescript: "unstable" - - - uses: actions/setup-node@v2 + - uses: actions/checkout@v6 + - uses: actions/setup-node@v6 with: - node-version: "14.x" - - - name: Install dependencies - run: | - npm install -g bower - npm install - bower install --production - - - name: Build source - run: npm run-script build - - - name: Run tests - run: | - bower install - npm run-script test --if-present + node-version: "24" + - run: npm install + - run: npm run build + - run: npm test + - run: npm run lint + - run: npm run format:check diff --git a/.gitignore b/.gitignore index b846b630..6c007d67 100644 --- a/.gitignore +++ b/.gitignore @@ -1,8 +1,9 @@ /.* !/.gitignore -!/.eslintrc.json +!/.oxfmtrc.json +!/.tidyrc.json !/.github/ -/bower_components/ /node_modules/ /output/ -package-lock.json +/package-lock.json +/spago.lock diff --git a/.oxfmtrc.json b/.oxfmtrc.json new file mode 100644 index 00000000..757fd64c --- /dev/null +++ b/.oxfmtrc.json @@ -0,0 +1,3 @@ +{ + "trailingComma": "es5" +} diff --git a/.tidyrc.json b/.tidyrc.json new file mode 100644 index 00000000..9e39cf11 --- /dev/null +++ b/.tidyrc.json @@ -0,0 +1,10 @@ +{ + "importSort": "ide", + "importWrap": "source", + "indent": 2, + "operatorsFile": null, + "ribbon": 1, + "typeArrowPlacement": "first", + "unicode": "never", + "width": null +} diff --git a/CHANGELOG.md b/CHANGELOG.md index 5f2f4d42..d66171f4 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -12,6 +12,7 @@ Bugfixes: - Avoid `RangeError` in `arrayBind` foreign implementation (#314 by @pete-murphy) Other improvements: +- Migrate from Bower/Pulp to Spago and modernize CI, linting, and formatting tools. ## [v6.0.1](https://github.com/purescript/purescript-prelude/releases/tag/v6.0.1) - 2022-08-18 diff --git a/bower.json b/bower.json deleted file mode 100644 index 0b233c08..00000000 --- a/bower.json +++ /dev/null @@ -1,19 +0,0 @@ -{ - "name": "purescript-prelude", - "homepage": "https://github.com/purescript/purescript-prelude", - "description": "The PureScript Prelude", - "license": "BSD-3-Clause", - "repository": { - "type": "git", - "url": "https://github.com/purescript/purescript-prelude.git" - }, - "ignore": [ - "**/.*", - "bower_components", - "node_modules", - "output", - "test", - "bower.json", - "package.json" - ] -} diff --git a/package.json b/package.json index 8382d607..a96d4d5f 100644 --- a/package.json +++ b/package.json @@ -1,14 +1,23 @@ { "private": true, + "license": "BSD-3-Clause", + "homepage": "https://github.com/purescript/purescript-prelude", + "repository": { + "type": "git", + "url": "https://github.com/purescript/purescript-prelude.git" + }, "scripts": { - "clean": "rimraf output && rimraf .pulp-cache", - "build": "eslint src && pulp build -- --censor-lib --strict", - "test": "pulp test" + "build": "spago build", + "test": "spago test", + "lint": "oxlint --deny-warnings src test", + "format": "purs-tidy format-in-place src test && oxfmt --write .", + "format:check": "purs-tidy check src test && oxfmt --check ." }, "devDependencies": { - "eslint": "^7.15.0", - "purescript-psa": "^0.8.2", - "pulp": "16.0.0-0", - "rimraf": "^3.0.2" + "oxfmt": "^0.73.0", + "oxlint": "^1.88.0", + "purescript": "^0.15.16", + "purs-tidy": "^0.11.1", + "spago": "^1.0.5" } } diff --git a/spago.yaml b/spago.yaml new file mode 100644 index 00000000..250aefb5 --- /dev/null +++ b/spago.yaml @@ -0,0 +1,13 @@ +package: + name: prelude + description: The PureScript Prelude + build: + strict: true + pedanticPackages: true + test: + main: Test.Main + strict: true + pedanticPackages: true + dependencies: [] + dependencies: [] +workspace: {} From c1032d5d8b41d92a1297968c9a4ea8b0d650ec7e Mon Sep 17 00:00:00 2001 From: Thomas Honeyman Date: Wed, 14 Oct 2026 10:56:45 +0000 Subject: [PATCH 02/11] Update lint directives and use do-let test style --- src/Control/Apply.js | 3 +++ src/Data/Functor.js | 3 +++ src/Data/Ring.js | 1 - src/Data/Semiring.js | 2 -- src/Data/Show.js | 4 +++- test/Test/Main.purs | 11 +++++------ 6 files changed, 14 insertions(+), 10 deletions(-) diff --git a/src/Control/Apply.js b/src/Control/Apply.js index 149f4385..fd89fc2a 100644 --- a/src/Control/Apply.js +++ b/src/Control/Apply.js @@ -2,6 +2,9 @@ export const arrayApply = function (fs) { return function (xs) { var l = fs.length; var k = xs.length; + // Allocate the result array at its final size; the loop below fills it, + // so initializing every slot first would do the work twice. + // oxlint-disable-next-line unicorn/no-new-array var result = new Array(l*k); var n = 0; for (var i = 0; i < l; i++) { diff --git a/src/Data/Functor.js b/src/Data/Functor.js index 095e5332..7f575726 100644 --- a/src/Data/Functor.js +++ b/src/Data/Functor.js @@ -1,6 +1,9 @@ export const arrayMap = function (f) { return function (arr) { var l = arr.length; + // Allocate the result array at its final size; the loop below fills it, + // so initializing every slot first would do the work twice. + // oxlint-disable-next-line unicorn/no-new-array var result = new Array(l); for (var i = 0; i < l; i++) { result[i] = f(arr[i]); diff --git a/src/Data/Ring.js b/src/Data/Ring.js index cceb66c8..b75ab802 100644 --- a/src/Data/Ring.js +++ b/src/Data/Ring.js @@ -1,6 +1,5 @@ export const intSub = function (x) { return function (y) { - /* jshint bitwise: false */ return x - y | 0; }; }; diff --git a/src/Data/Semiring.js b/src/Data/Semiring.js index 2d537c18..c1cd39da 100644 --- a/src/Data/Semiring.js +++ b/src/Data/Semiring.js @@ -1,13 +1,11 @@ export const intAdd = function (x) { return function (y) { - /* jshint bitwise: false */ return x + y | 0; }; }; export const intMul = function (x) { return function (y) { - /* jshint bitwise: false */ return x * y | 0; }; }; diff --git a/src/Data/Show.js b/src/Data/Show.js index 2526f706..018507d4 100644 --- a/src/Data/Show.js +++ b/src/Data/Show.js @@ -27,7 +27,9 @@ export const showCharImpl = function (c) { export const showStringImpl = function (s) { var l = s.length; return "\"" + s.replace( - /[\0-\x1F\x7F"\\]/g, // eslint-disable-line no-control-regex + // This pattern must match control characters so they can be escaped in the output. + // oxlint-disable-next-line no-control-regex + /[\0-\x1F\x7F"\\]/g, function (c, i) { switch (c) { case "\"": diff --git a/test/Test/Main.purs b/test/Test/Main.purs index ef15756d..17e04edb 100644 --- a/test/Test/Main.purs +++ b/test/Test/Main.purs @@ -88,16 +88,15 @@ testIntDivMod = do go (-2) (-3) where - go a b = + go a b = do let 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 + 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 From 75dfaac900caab78510f24310b562848710228cf Mon Sep 17 00:00:00 2001 From: Thomas Honeyman Date: Wed, 14 Oct 2026 21:09:10 +0000 Subject: [PATCH 03/11] Format repository files with purs-tidy and Oxfmt --- CHANGELOG.md | 20 ++++- package.json | 2 +- src/Control/Applicative.purs | 1 - src/Control/Apply.js | 2 +- src/Control/Apply.purs | 4 +- src/Control/Bind.js | 30 +++---- src/Control/Bind.purs | 1 - src/Control/Monad.purs | 1 - src/Data/BooleanAlgebra.purs | 2 +- src/Data/Eq/Generic.purs | 3 +- src/Data/Field.purs | 4 +- src/Data/Function.purs | 2 +- src/Data/Functor.purs | 2 +- src/Data/Monoid/Generic.purs | 3 +- src/Data/Ord.purs | 4 +- src/Data/Ord/Generic.purs | 3 +- src/Data/Ring.js | 2 +- src/Data/Semigroup/Generic.purs | 3 +- src/Data/Semiring.js | 4 +- src/Data/Show.js | 76 ++++++++++------- src/Data/Show.purs | 6 +- src/Data/Show/Generic.purs | 3 +- src/Data/Symbol.js | 1 - src/Prelude.purs | 13 ++- test/Data/Generic/Rep.purs | 4 +- test/Test/Main.js | 9 +- test/Test/Main.purs | 140 ++++++++++++++++---------------- test/Test/Utils.js | 2 +- 28 files changed, 189 insertions(+), 158 deletions(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index d66171f4..de44f952 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -9,20 +9,24 @@ Breaking changes: New features: Bugfixes: + - Avoid `RangeError` in `arrayBind` foreign implementation (#314 by @pete-murphy) Other improvements: + - Migrate from Bower/Pulp to Spago and modernize CI, linting, and formatting tools. ## [v6.0.1](https://github.com/purescript/purescript-prelude/releases/tag/v6.0.1) - 2022-08-18 Other improvements: + - Documentation: Clarify relationship between `Ord` and `Eq` (#298 by @JamieBallingall) - Remove array allocation and local array FFI from the `Show` instance for records. (#299 by @ajnsit) ## [v6.0.0](https://github.com/purescript/purescript-prelude/releases/tag/v6.0.0) - 2022-04-27 Breaking changes: + - Migrated FFI to ES Modules (#287 by @kl0tl and @JordanMartinez) - Change Generic Rep's `NoConstructors` to newtype `Void` (#282 by @JordanMartinez) - Replaced polymorphic proxies with monomorphic `Proxy` (#281, #288 by @JordanMartinez) @@ -30,11 +34,13 @@ Breaking changes: - Fix `Show` instance on records with duplicate labels by adding `Nub` constraint (#269 by @JordanMartinez) New features: + - Added the `Data.Reflectable` module for type reflection (#289 by @PureFunctor) Bugfixes: Other improvements: + - Changed `unit`'s FFI representation from `{}` to `undefined` (#267 by @JordanMartinez) - Added clearer docs for Prelude module (#270 by @JordanMartinez) - Clarify docs for `flip` (#271 by @JordanMartinez) @@ -45,28 +51,33 @@ Other improvements: ## [v5.0.1](https://github.com/purescript/purescript-prelude/releases/tag/v5.0.1) - 2021-05-11 Other improvements: + - Fix warnings revealed by `v0.14.1` PS release (#262 by @JordanMartinez) ## [v5.0.0](https://github.com/purescript/purescript-prelude/releases/tag/v5.0.0) - 2021-02-26 Breaking changes: + - Support compiler version `v0.14.0`, and drop support for previous versions (#206, #226) - `purescript-proxy` was ported to this repo (#230) - `purescript-generics-rep` was ported to this repo (#235) - Move the `Applicative` Superclass law from `Monad` to `Bind` and rename it -to the `Apply` Superclass law (#229) + to the `Apply` Superclass law (#229) - Removed `unsafeCompare` (#257) New features: + - Added `Bounded` instance for records (#208) - Added `Show` instances to `Data.Generics.Rep` types (#250) - Added `toRep` (#238) Bugfixes: + - No longer use reference equality check in `Array`'s `Eq` instance because it breaks referential transparency (#187). - Fix Ring laws (#228) Documentation improvements: + - Added `lift2` example using `Maybe` (#213) - Added `const` example (#214) - Added `power` example (#253) @@ -75,6 +86,7 @@ Documentation improvements: - Fix typo: 'ommitted' -> 'omitted' (#220) Other improvements: + - Migrated to GitHub Actions (#234) - Added a `CHANGELOG.md` file and PR template (#254) @@ -122,8 +134,8 @@ Remove unused `refIneq` function (@metaleap) ## [v3.1.0](https://github.com/purescript/purescript-prelude/releases/tag/v3.1.0) - 2017-06-27 -* Fixes for out-of-date documentation (@joneshf, @matthewleon) -* Add a new `DivisionRing` class +- Fixes for out-of-date documentation (@joneshf, @matthewleon) +- Add a new `DivisionRing` class ## [v3.0.0](https://github.com/purescript/purescript-prelude/releases/tag/v3.0.0) - 2017-03-25 @@ -158,10 +170,12 @@ Remove unused `refIneq` function (@metaleap) ## [v2.0.0](https://github.com/purescript/purescript-prelude/releases/tag/v2.0.0) - 2016-09-26 **Breaking changes** + - Fixed `=<<` to be right associative, as originally intended - Changed behaviour of `Eq` and `Ord` for `NaN` numeric value #91 (@berdario) **Enhancements** + - Updated docs to include notes about the non-law-abiding numeric instances - Semigroup `append` for `Array` will no longer shallow copy the array if either side is empty #63 (suggested by @natefaubion) diff --git a/package.json b/package.json index a96d4d5f..23129e8e 100644 --- a/package.json +++ b/package.json @@ -1,7 +1,7 @@ { "private": true, - "license": "BSD-3-Clause", "homepage": "https://github.com/purescript/purescript-prelude", + "license": "BSD-3-Clause", "repository": { "type": "git", "url": "https://github.com/purescript/purescript-prelude.git" diff --git a/src/Control/Applicative.purs b/src/Control/Applicative.purs index 6d444460..6cfed9dc 100644 --- a/src/Control/Applicative.purs +++ b/src/Control/Applicative.purs @@ -9,7 +9,6 @@ module Control.Applicative ) where import Control.Apply (class Apply, apply, (*>), (<*), (<*>)) - import Data.Functor (class Functor, map, void, ($>), (<#>), (<$), (<$>)) import Data.Unit (Unit, unit) import Type.Proxy (Proxy(..)) diff --git a/src/Control/Apply.js b/src/Control/Apply.js index fd89fc2a..f91ea31e 100644 --- a/src/Control/Apply.js +++ b/src/Control/Apply.js @@ -5,7 +5,7 @@ export const arrayApply = function (fs) { // Allocate the result array at its final size; the loop below fills it, // so initializing every slot first would do the work twice. // oxlint-disable-next-line unicorn/no-new-array - var result = new Array(l*k); + var result = new Array(l * k); var n = 0; for (var i = 0; i < l; i++) { var f = fs[i]; diff --git a/src/Control/Apply.purs b/src/Control/Apply.purs index 6cde1c85..5bbf03a3 100644 --- a/src/Control/Apply.purs +++ b/src/Control/Apply.purs @@ -13,9 +13,9 @@ module Control.Apply , module Data.Functor ) where -import Data.Functor (class Functor, map, void, ($>), (<#>), (<$), (<$>)) -import Data.Function (const) import Control.Category (identity) +import Data.Function (const) +import Data.Functor (class Functor, map, void, ($>), (<#>), (<$), (<$>)) import Type.Proxy (Proxy(..)) -- | The `Apply` class provides the `(<*>)` which is used to apply a function diff --git a/src/Control/Bind.js b/src/Control/Bind.js index bf79719f..ad082c8f 100644 --- a/src/Control/Bind.js +++ b/src/Control/Bind.js @@ -1,21 +1,21 @@ export const arrayBind = typeof Array.prototype.flatMap === "function" ? function (arr) { - return function (f) { - return arr.flatMap(f); - }; - } + return function (f) { + return arr.flatMap(f); + }; + } : function (arr) { - return function (f) { - var result = []; - var l = arr.length; - for (var i = 0; i < l; i++) { - var xs = f(arr[i]); - var k = xs.length; - for (var j = 0; j < k; j++) { - result.push(xs[j]); + return function (f) { + var result = []; + var l = arr.length; + for (var i = 0; i < l; i++) { + var xs = f(arr[i]); + var k = xs.length; + for (var j = 0; j < k; j++) { + result.push(xs[j]); + } } - } - return result; + return result; + }; }; - }; diff --git a/src/Control/Bind.purs b/src/Control/Bind.purs index c6d8a6ae..40dbcfbf 100644 --- a/src/Control/Bind.purs +++ b/src/Control/Bind.purs @@ -20,7 +20,6 @@ module Control.Bind import Control.Applicative (class Applicative, liftA1, pure, unless, when) import Control.Apply (class Apply, apply, (*>), (<*), (<*>)) import Control.Category (identity) - import Data.Function (flip) import Data.Functor (class Functor, map, void, ($>), (<#>), (<$), (<$>)) import Data.Unit (Unit) diff --git a/src/Control/Monad.purs b/src/Control/Monad.purs index 3d8400ae..b948b6e1 100644 --- a/src/Control/Monad.purs +++ b/src/Control/Monad.purs @@ -13,7 +13,6 @@ module Control.Monad import Control.Applicative (class Applicative, liftA1, pure, unless, when) import Control.Apply (class Apply, apply, (*>), (<*), (<*>)) import Control.Bind (class Bind, bind, ifM, join, (<=<), (=<<), (>=>), (>>=)) - import Data.Functor (class Functor, map, void, ($>), (<#>), (<$), (<$>)) import Data.Unit (Unit) import Type.Proxy (Proxy) diff --git a/src/Data/BooleanAlgebra.purs b/src/Data/BooleanAlgebra.purs index 622caee5..e1ca969e 100644 --- a/src/Data/BooleanAlgebra.purs +++ b/src/Data/BooleanAlgebra.purs @@ -4,7 +4,7 @@ module Data.BooleanAlgebra , class BooleanAlgebraRecord ) where -import Data.HeytingAlgebra (class HeytingAlgebra, class HeytingAlgebraRecord, ff, tt, implies, conj, disj, not, (&&), (||)) +import Data.HeytingAlgebra (class HeytingAlgebra, class HeytingAlgebraRecord, conj, disj, ff, implies, not, tt, (&&), (||)) import Data.Symbol (class IsSymbol) import Data.Unit (Unit) import Prim.Row as Row diff --git a/src/Data/Eq/Generic.purs b/src/Data/Eq/Generic.purs index 1c9e1386..de274c76 100644 --- a/src/Data/Eq/Generic.purs +++ b/src/Data/Eq/Generic.purs @@ -4,9 +4,10 @@ module Data.Eq.Generic , genericEq ) where -import Prelude (class Eq, (==), (&&)) import Data.Generic.Rep +import Prelude (class Eq, (&&), (==)) + class GenericEq a where genericEq' :: a -> a -> Boolean diff --git a/src/Data/Field.purs b/src/Data/Field.purs index 113b714d..d2b033d6 100644 --- a/src/Data/Field.purs +++ b/src/Data/Field.purs @@ -7,9 +7,9 @@ module Data.Field , module Data.Semiring ) where -import Data.DivisionRing (class DivisionRing, recip) import Data.CommutativeRing (class CommutativeRing) -import Data.EuclideanRing (class EuclideanRing, degree, div, mod, (/), gcd, lcm) +import Data.DivisionRing (class DivisionRing, recip) +import Data.EuclideanRing (class EuclideanRing, degree, div, gcd, lcm, mod, (/)) import Data.Ring (class Ring, negate, sub) import Data.Semiring (class Semiring, add, mul, one, zero, (*), (+)) diff --git a/src/Data/Function.purs b/src/Data/Function.purs index 37ff740c..94ead08b 100644 --- a/src/Data/Function.purs +++ b/src/Data/Function.purs @@ -10,7 +10,7 @@ module Data.Function , module Control.Category ) where -import Control.Category (identity, compose, (<<<), (>>>)) +import Control.Category (compose, identity, (<<<), (>>>)) import Data.Boolean (otherwise) import Data.Ord ((<=)) import Data.Ring ((-)) diff --git a/src/Data/Functor.purs b/src/Data/Functor.purs index fb97ea8d..4652fe0f 100644 --- a/src/Data/Functor.purs +++ b/src/Data/Functor.purs @@ -13,7 +13,7 @@ module Data.Functor , (<@>) ) where -import Data.Function (const, compose) +import Data.Function (compose, const) import Data.Unit (Unit, unit) import Type.Proxy (Proxy(..)) diff --git a/src/Data/Monoid/Generic.purs b/src/Data/Monoid/Generic.purs index a73232df..fdbc8d4b 100644 --- a/src/Data/Monoid/Generic.purs +++ b/src/Data/Monoid/Generic.purs @@ -4,9 +4,10 @@ module Data.Monoid.Generic , genericMempty ) where -import Data.Monoid (class Monoid, mempty) import Data.Generic.Rep +import Data.Monoid (class Monoid, mempty) + class GenericMonoid a where genericMempty' :: a diff --git a/src/Data/Ord.purs b/src/Data/Ord.purs index ed699905..a1cd4f08 100644 --- a/src/Data/Ord.purs +++ b/src/Data/Ord.purs @@ -24,9 +24,9 @@ module Data.Ord ) where import Data.Eq (class Eq, class Eq1, class EqRecord, (/=)) -import Data.Symbol (class IsSymbol, reflectSymbol) import Data.Ordering (Ordering(..)) -import Data.Ring (class Ring, zero, one, negate) +import Data.Ring (class Ring, negate, one, zero) +import Data.Symbol (class IsSymbol, reflectSymbol) import Data.Unit (Unit) import Data.Void (Void) import Prim.Row as Row diff --git a/src/Data/Ord/Generic.purs b/src/Data/Ord/Generic.purs index b1e2129c..ffc11d52 100644 --- a/src/Data/Ord/Generic.purs +++ b/src/Data/Ord/Generic.purs @@ -4,9 +4,10 @@ module Data.Ord.Generic , genericCompare ) where -import Prelude (class Ord, compare, Ordering(..)) import Data.Generic.Rep +import Prelude (class Ord, Ordering(..), compare) + class GenericOrd a where genericCompare' :: a -> a -> Ordering diff --git a/src/Data/Ring.js b/src/Data/Ring.js index b75ab802..c84d0327 100644 --- a/src/Data/Ring.js +++ b/src/Data/Ring.js @@ -1,6 +1,6 @@ export const intSub = function (x) { return function (y) { - return x - y | 0; + return (x - y) | 0; }; }; diff --git a/src/Data/Semigroup/Generic.purs b/src/Data/Semigroup/Generic.purs index 5591903d..a0b177ff 100644 --- a/src/Data/Semigroup/Generic.purs +++ b/src/Data/Semigroup/Generic.purs @@ -4,9 +4,10 @@ module Data.Semigroup.Generic , genericAppend ) where -import Prelude (class Semigroup, append) import Data.Generic.Rep +import Prelude (class Semigroup, append) + class GenericSemigroup a where genericAppend' :: a -> a -> a diff --git a/src/Data/Semiring.js b/src/Data/Semiring.js index c1cd39da..efcf4103 100644 --- a/src/Data/Semiring.js +++ b/src/Data/Semiring.js @@ -1,12 +1,12 @@ export const intAdd = function (x) { return function (y) { - return x + y | 0; + return (x + y) | 0; }; }; export const intMul = function (x) { return function (y) { - return x * y | 0; + return (x * y) | 0; }; }; diff --git a/src/Data/Show.js b/src/Data/Show.js index 018507d4..d1981ed0 100644 --- a/src/Data/Show.js +++ b/src/Data/Show.js @@ -9,15 +9,22 @@ export const showNumberImpl = function (n) { export const showCharImpl = function (c) { var code = c.charCodeAt(0); - if (code < 0x20 || code === 0x7F) { + if (code < 0x20 || code === 0x7f) { switch (c) { - case "\x07": return "'\\a'"; - case "\b": return "'\\b'"; - case "\f": return "'\\f'"; - case "\n": return "'\\n'"; - case "\r": return "'\\r'"; - case "\t": return "'\\t'"; - case "\v": return "'\\v'"; + case "\x07": + return "'\\a'"; + case "\b": + return "'\\b'"; + case "\f": + return "'\\f'"; + case "\n": + return "'\\n'"; + case "\r": + return "'\\r'"; + case "\t": + return "'\\t'"; + case "\v": + return "'\\v'"; } return "'\\" + code.toString(10) + "'"; } @@ -26,28 +33,39 @@ export const showCharImpl = function (c) { export const showStringImpl = function (s) { var l = s.length; - return "\"" + s.replace( - // This pattern must match control characters so they can be escaped in the output. - // oxlint-disable-next-line no-control-regex - /[\0-\x1F\x7F"\\]/g, - function (c, i) { - switch (c) { - case "\"": - case "\\": - return "\\" + c; - case "\x07": return "\\a"; - case "\b": return "\\b"; - case "\f": return "\\f"; - case "\n": return "\\n"; - case "\r": return "\\r"; - case "\t": return "\\t"; - case "\v": return "\\v"; + return ( + '"' + + s.replace( + // This pattern must match control characters so they can be escaped in the output. + // oxlint-disable-next-line no-control-regex + /[\0-\x1F\x7F"\\]/g, + function (c, i) { + switch (c) { + case '"': + case "\\": + return "\\" + c; + case "\x07": + return "\\a"; + case "\b": + return "\\b"; + case "\f": + return "\\f"; + case "\n": + return "\\n"; + case "\r": + return "\\r"; + case "\t": + return "\\t"; + case "\v": + return "\\v"; + } + var k = i + 1; + var empty = k < l && s[k] >= "0" && s[k] <= "9" ? "\\&" : ""; + return "\\" + c.charCodeAt(0).toString(10) + empty; } - var k = i + 1; - var empty = k < l && s[k] >= "0" && s[k] <= "9" ? "\\&" : ""; - return "\\" + c.charCodeAt(0).toString(10) + empty; - } - ) + "\""; + ) + + '"' + ); }; export const showArrayImpl = function (f) { 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..13383e5f 100644 --- a/src/Data/Show/Generic.purs +++ b/src/Data/Show/Generic.purs @@ -6,9 +6,10 @@ module Data.Show.Generic , genericShowArgs ) where -import Prelude (class Show, show, (<>)) import Data.Generic.Rep + import Data.Symbol (class IsSymbol, reflectSymbol) +import Prelude (class Show, show, (<>)) import Type.Proxy (Proxy(..)) class GenericShow a where diff --git a/src/Data/Symbol.js b/src/Data/Symbol.js index b2941408..72041597 100644 --- a/src/Data/Symbol.js +++ b/src/Data/Symbol.js @@ -3,4 +3,3 @@ export const unsafeCoerce = function (arg) { return arg; }; - diff --git a/src/Prelude.purs b/src/Prelude.purs index 6f42076b..9ab4db75 100644 --- a/src/Prelude.purs +++ b/src/Prelude.purs @@ -40,27 +40,26 @@ module Prelude , module Data.Void ) where -import Control.Applicative (class Applicative, pure, liftA1, unless, when) +import Control.Applicative (class Applicative, liftA1, pure, unless, when) import Control.Apply (class Apply, apply, (*>), (<*), (<*>)) -import Control.Bind (class Bind, bind, class Discard, discard, ifM, join, (<=<), (=<<), (>=>), (>>=)) +import Control.Bind (class Bind, class Discard, bind, discard, ifM, join, (<=<), (=<<), (>=>), (>>=)) import Control.Category (class Category, identity) -import Control.Monad (class Monad, liftM1, unlessM, whenM, ap) +import Control.Monad (class Monad, ap, liftM1, unlessM, whenM) import Control.Semigroupoid (class Semigroupoid, compose, (<<<), (>>>)) - import Data.Boolean (otherwise) import Data.BooleanAlgebra (class BooleanAlgebra) import Data.Bounded (class Bounded, bottom, top) import Data.CommutativeRing (class CommutativeRing) import Data.DivisionRing (class DivisionRing, recip) import Data.Eq (class Eq, eq, notEq, (/=), (==)) -import Data.EuclideanRing (class EuclideanRing, degree, div, mod, (/), gcd, lcm) +import Data.EuclideanRing (class EuclideanRing, degree, div, gcd, lcm, mod, (/)) import Data.Field (class Field) -import Data.Function (const, flip, ($), (#)) +import Data.Function (const, flip, (#), ($)) import Data.Functor (class Functor, flap, map, void, ($>), (<#>), (<$), (<$>), (<@>)) import Data.HeytingAlgebra (class HeytingAlgebra, conj, disj, not, (&&), (||)) import Data.Monoid (class Monoid, mempty) import Data.NaturalTransformation (type (~>)) -import Data.Ord (class Ord, compare, (<), (<=), (>), (>=), comparing, min, max, clamp, between) +import Data.Ord (class Ord, between, clamp, compare, comparing, max, min, (<), (<=), (>), (>=)) import Data.Ordering (Ordering(..)) import Data.Ring (class Ring, negate, sub, (-)) import Data.Semigroup (class Semigroup, append, (<>)) diff --git a/test/Data/Generic/Rep.purs b/test/Data/Generic/Rep.purs index 45c4c1e3..989c987b 100644 --- a/test/Data/Generic/Rep.purs +++ b/test/Data/Generic/Rep.purs @@ -2,15 +2,15 @@ module Test.Data.Generic.Rep where import Prelude -import Data.Generic.Rep as G import Data.Bounded.Generic as GBounded import Data.Eq.Generic as GEq +import Data.Generic.Rep as G +import Data.HeytingAlgebra (ff, implies, tt) import Data.HeytingAlgebra.Generic as GHeytingAlgebra import Data.Ord.Generic as GOrd import Data.Ring.Generic as GRing import Data.Semiring.Generic as GSemiring import Data.Show.Generic as GShow -import Data.HeytingAlgebra (ff, tt, implies) import Test.Utils (AlmostEff, assert) data List a = Nil | Cons { head :: a, tail :: List a } diff --git a/test/Test/Main.js b/test/Test/Main.js index 72ebcd92..2582f011 100644 --- a/test/Test/Main.js +++ b/test/Test/Main.js @@ -1,14 +1,11 @@ export function testNumberShow(showNumber) { - return function() { + return function () { function testAll(cases) { - cases.forEach(function(c) { + cases.forEach(function (c) { var expected = c[1]; var actual = showNumber(c[0]); if (expected !== actual) { - throw new Error( - "For " + c[0] + - ", expected " + expected + - ", got: " + actual + "."); + throw new Error("For " + c[0] + ", expected " + expected + ", got: " + actual + "."); } }); } diff --git a/test/Test/Main.purs b/test/Test/Main.purs index 17e04edb..dfb374b7 100644 --- a/test/Test/Main.purs +++ b/test/Test/Main.purs @@ -1,68 +1,69 @@ module Test.Main where import Prelude -import Data.HeytingAlgebra (ff, tt, implies) + +import Data.HeytingAlgebra (ff, implies, tt) import Data.Ord (abs, signum) import Data.Reflectable (reflectType, reifyType) -import Prim.Boolean (True, False) -import Prim.Ordering (LT, GT, EQ) +import Prim.Boolean (False, True) +import Prim.Ordering (EQ, GT, LT) import Test.Data.Generic.Rep (testGenericRep) import Test.Utils (AlmostEff, assert) import Type.Proxy (Proxy(..)) main :: AlmostEff main = do - testNumberShow show - testOrderings - testOrdUtils - testIntDivMod - testIntDegree - testRecordInstances - testGenericRep - testReflectType - testReifyType - testSignum - testArrayBind + testNumberShow show + testOrderings + testOrdUtils + testIntDivMod + testIntDegree + testRecordInstances + testGenericRep + testReflectType + testReifyType + testSignum + testArrayBind 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 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 - 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) 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 + 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) 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 @@ -100,17 +101,17 @@ testIntDivMod = do 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 } @@ -118,23 +119,26 @@ testRecordInstances = do 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 @@ -142,10 +146,10 @@ 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 @@ -171,10 +175,10 @@ 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" foreign import makeArray :: Int -> Array Int @@ -183,6 +187,6 @@ testArrayBind = do assert "Array bind does not cause RangeError" do let _ = do - _ <- [unit] + _ <- [ unit ] makeArray 106_000 true diff --git a/test/Test/Utils.js b/test/Test/Utils.js index ae5b410a..7314b77e 100644 --- a/test/Test/Utils.js +++ b/test/Test/Utils.js @@ -1,5 +1,5 @@ export function throwErr(msg) { - return function() { + return function () { throw new Error(msg); }; } From a75dd0476ebc5a09b5d594ac01aa06f6535603a9 Mon Sep 17 00:00:00 2001 From: Thomas Honeyman Date: Wed, 14 Oct 2026 23:50:03 +0000 Subject: [PATCH 04/11] Place package dependencies before test configuration --- spago.yaml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/spago.yaml b/spago.yaml index 250aefb5..f94fc800 100644 --- a/spago.yaml +++ b/spago.yaml @@ -4,10 +4,10 @@ package: build: strict: true pedanticPackages: true + dependencies: [] test: main: Test.Main strict: true pedanticPackages: true dependencies: [] - dependencies: [] workspace: {} From a4fb5cb605168cef703ecb4db5a7857f16bf0046 Mon Sep 17 00:00:00 2001 From: Thomas Honeyman Date: Thu, 15 Oct 2026 00:01:41 +0000 Subject: [PATCH 05/11] Configure registry publication metadata --- spago.yaml | 6 ++++++ 1 file changed, 6 insertions(+) diff --git a/spago.yaml b/spago.yaml index f94fc800..d268dc13 100644 --- a/spago.yaml +++ b/spago.yaml @@ -4,6 +4,12 @@ package: build: strict: true pedanticPackages: true + publish: + version: 6.0.3 + license: BSD-3-Clause + location: + githubOwner: purescript + githubRepo: purescript-prelude dependencies: [] test: main: Test.Main From 4707b7dece9ce5ff19df10c7b3e0fe979eb707d6 Mon Sep 17 00:00:00 2001 From: Thomas Honeyman Date: Thu, 15 Oct 2026 00:32:44 +0000 Subject: [PATCH 06/11] Credit migration pull request in changelog --- CHANGELOG.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index de44f952..090aa9fc 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -14,7 +14,7 @@ Bugfixes: Other improvements: -- Migrate from Bower/Pulp to Spago and modernize CI, linting, and formatting tools. +- Migrate from Bower/Pulp to Spago and modernize CI, linting, and formatting tools (#318 by @thomashoneyman) ## [v6.0.1](https://github.com/purescript/purescript-prelude/releases/tag/v6.0.1) - 2022-08-18 From 119390f6ab392875a42bb3e4342cbf83820bed6b Mon Sep 17 00:00:00 2001 From: Thomas Honeyman Date: Thu, 15 Oct 2026 00:44:15 +0000 Subject: [PATCH 07/11] Prepare versioned changelog for release --- CHANGELOG.md | 12 +++++------- 1 file changed, 5 insertions(+), 7 deletions(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index 090aa9fc..2b8f246e 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -2,20 +2,18 @@ Notable changes to this project are documented in this file. The format is based on [Keep a Changelog](https://keepachangelog.com/en/1.0.0/) and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0.html). -## [Unreleased] +## [v6.0.3](https://github.com/purescript/purescript-prelude/releases/tag/v6.0.3) -Breaking changes: +Other improvements: -New features: +- Migrate from Bower/Pulp to Spago and modernize CI, linting, and formatting tools (#318 by @thomashoneyman) + +## [v6.0.2](https://github.com/purescript/purescript-prelude/releases/tag/v6.0.2) - 2025-02-15 Bugfixes: - Avoid `RangeError` in `arrayBind` foreign implementation (#314 by @pete-murphy) -Other improvements: - -- Migrate from Bower/Pulp to Spago and modernize CI, linting, and formatting tools (#318 by @thomashoneyman) - ## [v6.0.1](https://github.com/purescript/purescript-prelude/releases/tag/v6.0.1) - 2022-08-18 Other improvements: From dffe5dda768a543bc68d81528daa7f9e64e04faa Mon Sep 17 00:00:00 2001 From: Thomas Honeyman Date: Thu, 15 Oct 2026 21:26:17 +0000 Subject: [PATCH 08/11] Prepare changelog release date and unreleased section --- CHANGELOG.md | 12 +++++++++++- 1 file changed, 11 insertions(+), 1 deletion(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index 2b8f246e..9c5b326e 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -2,7 +2,17 @@ Notable changes to this project are documented in this file. The format is based on [Keep a Changelog](https://keepachangelog.com/en/1.0.0/) and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0.html). -## [v6.0.3](https://github.com/purescript/purescript-prelude/releases/tag/v6.0.3) +## [Unreleased] + +Breaking changes: + +New features: + +Bugfixes: + +Other improvements: + +## [v6.0.3](https://github.com/purescript/purescript-prelude/releases/tag/v6.0.3) - 2026-10-17 Other improvements: From 8d443958ae04647a530cb590622155323fd7ff52 Mon Sep 17 00:00:00 2001 From: Thomas Honeyman Date: Fri, 16 Oct 2026 12:01:42 +0000 Subject: [PATCH 09/11] Simplify power branching with a shared recursive result --- src/Data/Monoid.purs | 18 ++++++++++++------ 1 file changed, 12 insertions(+), 6 deletions(-) diff --git a/src/Data/Monoid.purs b/src/Data/Monoid.purs index 96edcddd..00a10bbc 100644 --- a/src/Data/Monoid.purs +++ b/src/Data/Monoid.purs @@ -8,7 +8,6 @@ module Data.Monoid , memptyRecord ) where -import Data.Boolean (otherwise) import Data.Eq ((==)) import Data.EuclideanRing (mod, (/)) import Data.Ord ((<=)) @@ -86,11 +85,18 @@ power :: forall m. Monoid m => m -> Int -> m power x = go where go :: Int -> m - go p - | p <= 0 = mempty - | p == 1 = x - | p `mod` 2 == 0 = let x' = go (p / 2) in x' <> x' - | otherwise = let x' = go (p / 2) in x' <> x' <> x + go p = + if p <= 0 then + mempty + else if p == 1 then + x + else do + let x' = go (p / 2) + + if p `mod` 2 == 0 then + x' <> x' + else + x' <> x' <> x -- | Allow or "truncate" a Monoid to its `mempty` value based on a condition. guard :: forall m. Monoid m => Boolean -> m -> m From 71addb3d2cb44f7910453be417c1a1996fa7d6d3 Mon Sep 17 00:00:00 2001 From: Thomas Honeyman Date: Fri, 16 Oct 2026 12:19:48 +0000 Subject: [PATCH 10/11] Keep power guards with do-let branch bindings --- src/Data/Monoid.purs | 18 ++++++++---------- 1 file changed, 8 insertions(+), 10 deletions(-) diff --git a/src/Data/Monoid.purs b/src/Data/Monoid.purs index 00a10bbc..7e14263b 100644 --- a/src/Data/Monoid.purs +++ b/src/Data/Monoid.purs @@ -8,6 +8,7 @@ module Data.Monoid , memptyRecord ) where +import Data.Boolean (otherwise) import Data.Eq ((==)) import Data.EuclideanRing (mod, (/)) import Data.Ord ((<=)) @@ -85,17 +86,14 @@ power :: forall m. Monoid m => m -> Int -> m power x = go where go :: Int -> m - go p = - if p <= 0 then - mempty - else if p == 1 then - x - else do - let x' = go (p / 2) - - if p `mod` 2 == 0 then + go p + | p <= 0 = mempty + | p == 1 = x + | p `mod` 2 == 0 = do + let x' = go (p / 2) x' <> x' - else + | otherwise = do + let x' = go (p / 2) x' <> x' <> x -- | Allow or "truncate" a Monoid to its `mempty` value based on a condition. From 2c680c5f3d5353a3d7f6873ed1f76c7f66f5e994 Mon Sep 17 00:00:00 2001 From: Thomas Honeyman Date: Sat, 17 Oct 2026 13:46:15 +0000 Subject: [PATCH 11/11] Complete Prelude release documentation --- CHANGELOG.md | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index 9c5b326e..620ec67f 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -2,7 +2,7 @@ Notable changes to this project are documented in this file. The format is based on [Keep a Changelog](https://keepachangelog.com/en/1.0.0/) and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0.html). -## [Unreleased] +## [Unreleased](https://github.com/purescript/purescript-prelude/compare/v6.0.3...HEAD) Breaking changes: @@ -16,6 +16,7 @@ Other improvements: Other improvements: +- Remove NaN tests for `Ord` and `Eq`; library behavior is unchanged (#316) - Migrate from Bower/Pulp to Spago and modernize CI, linting, and formatting tools (#318 by @thomashoneyman) ## [v6.0.2](https://github.com/purescript/purescript-prelude/releases/tag/v6.0.2) - 2025-02-15