From f53a6a8b555ebe546d332c1da77dae6f0a090a53 Mon Sep 17 00:00:00 2001 From: Oleg Grenrus Date: Wed, 24 Apr 2024 16:08:19 +0300 Subject: [PATCH] Use quanified superclass of Eq1/Ord1 to derive instance when available The laws of Eq1/Ord1, i.e. `eq1 = liftEq (==) = (==)` guarantee that this change should be non-breaking (though observable). --- .github/workflows/haskell-ci.yml | 18 ++++++++--------- CHANGELOG.md | 5 +++++ data-fix.cabal | 14 ++++++------- src/Data/Fix.hs | 34 +++++++++++++++++++++++++++++++- 4 files changed, 54 insertions(+), 17 deletions(-) diff --git a/.github/workflows/haskell-ci.yml b/.github/workflows/haskell-ci.yml index 9844fa1..ca808fa 100644 --- a/.github/workflows/haskell-ci.yml +++ b/.github/workflows/haskell-ci.yml @@ -8,9 +8,9 @@ # # For more information, see https://github.com/haskell-CI/haskell-ci # -# version: 0.19.20240512 +# version: 0.19.20240702 # -# REGENDATA ("0.19.20240512",["github","cabal.project"]) +# REGENDATA ("0.19.20240702",["github","cabal.project"]) # name: Haskell-CI on: @@ -38,9 +38,9 @@ jobs: compilerVersion: 9.8.2 setup-method: ghcup allow-failure: false - - compiler: ghc-9.6.5 + - compiler: ghc-9.6.6 compilerKind: ghc - compilerVersion: 9.6.5 + compilerVersion: 9.6.6 setup-method: ghcup allow-failure: false - compiler: ghc-9.4.8 @@ -83,7 +83,7 @@ jobs: curl -sL https://downloads.haskell.org/ghcup/0.1.20.0/x86_64-linux-ghcup-0.1.20.0 > "$HOME/.ghcup/bin/ghcup" chmod a+x "$HOME/.ghcup/bin/ghcup" "$HOME/.ghcup/bin/ghcup" install ghc "$HCVER" || (cat "$HOME"/.ghcup/logs/*.* && false) - "$HOME/.ghcup/bin/ghcup" install cabal 3.10.2.0 || (cat "$HOME"/.ghcup/logs/*.* && false) + "$HOME/.ghcup/bin/ghcup" install cabal 3.12.1.0 || (cat "$HOME"/.ghcup/logs/*.* && false) env: HCKIND: ${{ matrix.compilerKind }} HCNAME: ${{ matrix.compiler }} @@ -101,7 +101,7 @@ jobs: echo "HC=$HC" >> "$GITHUB_ENV" echo "HCPKG=$HCPKG" >> "$GITHUB_ENV" echo "HADDOCK=$HADDOCK" >> "$GITHUB_ENV" - echo "CABAL=$HOME/.ghcup/bin/cabal-3.10.2.0 -vnormal+nowrap" >> "$GITHUB_ENV" + echo "CABAL=$HOME/.ghcup/bin/cabal-3.12.1.0 -vnormal+nowrap" >> "$GITHUB_ENV" HCNUMVER=$(${HC} --numeric-version|perl -ne '/^(\d+)\.(\d+)\.(\d+)(\.(\d+))?$/; print(10000 * $1 + 100 * $2 + ($3 == 0 ? $5 != 1 : $3))') echo "HCNUMVER=$HCNUMVER" >> "$GITHUB_ENV" echo "ARG_TESTS=--enable-tests" >> "$GITHUB_ENV" @@ -160,8 +160,8 @@ jobs: - name: install cabal-docspec run: | mkdir -p $HOME/.cabal/bin - curl -sL https://github.com/phadej/cabal-extras/releases/download/cabal-docspec-0.0.0.20240414/cabal-docspec-0.0.0.20240414-x86_64-linux.xz > cabal-docspec.xz - echo '2d18a3f79619e8ec5f11870f926f6dc2616e02a6c889315b7f82044b95a1adb9 cabal-docspec.xz' | sha256sum -c - + curl -sL https://github.com/phadej/cabal-extras/releases/download/cabal-docspec-0.0.0.20240703/cabal-docspec-0.0.0.20240703-x86_64-linux.xz > cabal-docspec.xz + echo '48bf3b7fd2f7f0caa6162afee57a755be8523e7f467b694900eb420f5f9a7b76 cabal-docspec.xz' | sha256sum -c - xz -d < cabal-docspec.xz > $HOME/.cabal/bin/cabal-docspec rm -f cabal-docspec.xz chmod a+x $HOME/.cabal/bin/cabal-docspec @@ -195,7 +195,7 @@ jobs: echo " ghc-options: -Werror=missing-methods" >> cabal.project cat >> cabal.project <> cabal.project.local + $HCPKG list --simple-output --names-only | perl -ne 'for (split /\s+/) { print "constraints: any.$_ installed\n" unless /^(data-fix)$/; }' >> cabal.project.local cat cabal.project cat cabal.project.local - name: dump install plan diff --git a/CHANGELOG.md b/CHANGELOG.md index 276d09c..92e5db3 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -1,3 +1,8 @@ +## 0.3.4 + +- Use quantified constraints superclasses for `Eq`, `Ord`, `NFData` and + `Hashable Fix` instances, when available. + ## 0.3.3 - Drop support for GHCs prior 8.6.5 diff --git a/data-fix.cabal b/data-fix.cabal index ed55a7c..a0f32c0 100644 --- a/data-fix.cabal +++ b/data-fix.cabal @@ -1,7 +1,7 @@ +cabal-version: 2.2 Name: data-fix -Version: 0.3.3 -Cabal-Version: >= 1.10 -License: BSD3 +Version: 0.3.4 +License: BSD-3-Clause License-file: LICENSE Author: Anton Kholomiov, Edward Kmett, Oleg Grenrus Maintainer: @@ -26,7 +26,7 @@ Tested-With: || ==9.0.2 || ==9.2.8 || ==9.4.8 - || ==9.6.5 + || ==9.6.6 || ==9.8.2 || ==9.10.1 @@ -49,6 +49,6 @@ library -Wredundant-constraints -Widentities -Wmissing-export-lists build-depends: - base >=4.12.0.0 && <4.21 - , deepseq >=1.4.4.0 && <1.6 - , hashable >=1.4.4.0 && <1.5 + , base >=4.12.0.0 && <4.21 + , deepseq >=1.4.4.0 && <1.6 + , hashable >=1.4.4.0 && <1.6 diff --git a/src/Data/Fix.hs b/src/Data/Fix.hs index d26129b..8b943c2 100644 --- a/src/Data/Fix.hs +++ b/src/Data/Fix.hs @@ -9,6 +9,7 @@ {-# LANGUAGE UndecidableInstances #-} #define HAS_POLY_TYPEABLE MIN_VERSION_base(4,7,0) +#define HAS_QUANTIFIED_FUNCTOR_CLASSES MIN_VERSION_base(4,18,0) #if HAS_POLY_TYPEABLE {-# LANGUAGE StandaloneDeriving #-} @@ -97,7 +98,7 @@ import Prelude (const, error, undefined) import Control.Monad (liftM) import Data.Function (on) -import Data.Functor.Classes (Eq1, Ord1, Read1, Show1, compare1, eq1, readsPrec1, showsPrec1) +import Data.Functor.Classes (Eq1, Ord1, Read1, Show1, readsPrec1, showsPrec1) import Data.Hashable (Hashable (..)) import Data.Hashable.Lifted (Hashable1, hashWithSalt1) import Data.Typeable (Typeable) @@ -114,6 +115,10 @@ import Data.Data (Data) import Data.Data #endif +#if !HAS_QUANTIFIED_FUNCTOR_CLASSES +import Data.Functor.Classes (compare1, eq1) +#endif + -- $setup -- >>> :set -XDeriveFunctor -- >>> import Prelude @@ -191,10 +196,24 @@ unwrapFix = unFix ------------------------------------------------------------------------------- instance Eq1 f => Eq (Fix f) where +#if HAS_QUANTIFIED_FUNCTOR_CLASSES + Fix a == Fix b = a == b +#else Fix a == Fix b = eq1 a b +#endif instance Ord1 f => Ord (Fix f) where +#if HAS_QUANTIFIED_FUNCTOR_CLASSES + compare (Fix a) (Fix b) = compare a b + min (Fix a) (Fix b) = Fix (min a b) + max (Fix a) (Fix b) = Fix (max a b) + Fix a >= Fix b = a >= b + Fix a > Fix b = a > b + Fix a < Fix b = a < b + Fix a <= Fix b = a <= b +#else compare (Fix a) (Fix b) = compare1 a b +#endif instance Show1 f => Show (Fix f) where showsPrec d (Fix a) = @@ -214,12 +233,25 @@ instance Read1 f => Read (Fix f) where ------------------------------------------------------------------------------- instance Hashable1 f => Hashable (Fix f) where +#if MIN_VERSION_hashable(1,5,0) + hash (Fix x) = hash x + hashWithSalt salt (Fix x) = hashWithSalt salt x +#else hashWithSalt salt = hashWithSalt1 salt . unFix +#endif + +------------------------------------------------------------------------------- +-- deepseq +------------------------------------------------------------------------------- #if MIN_VERSION_deepseq(1,4,3) instance NFData1 f => NFData (Fix f) where +#if MIN_VERSION_deepseq(1,5,0) + rnf (Fix a) = rnf a +#else rnf = rnf1 . unFix #endif +#endif ------------------------------------------------------------------------------- -- Typeable and Data