diff --git a/.github/workflows/haskell-ci.yml b/.github/workflows/haskell-ci.yml index ac2fcfb..936def0 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.20240608 +# version: 0.19.20240708 # -# REGENDATA ("0.19.20240608",["github","timeline.cabal"]) +# REGENDATA ("0.19.20240708",["github","timeline.cabal"]) # 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 @@ -65,10 +65,10 @@ jobs: apt-get update apt-get install -y --no-install-recommends gnupg ca-certificates dirmngr curl git software-properties-common libtinfo5 mkdir -p "$HOME/.ghcup/bin" - curl -sL https://downloads.haskell.org/ghcup/0.1.20.0/x86_64-linux-ghcup-0.1.20.0 > "$HOME/.ghcup/bin/ghcup" + curl -sL https://downloads.haskell.org/ghcup/0.1.30.0/x86_64-linux-ghcup-0.1.30.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 }} @@ -86,7 +86,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" diff --git a/.gitignore b/.gitignore index eac54bf..7aa9209 100644 --- a/.gitignore +++ b/.gitignore @@ -1,6 +1,8 @@ .vscode/ .direnv/ .envrc +.pre-commit-config.yaml +dist/ result dist-newstyle -cabal.project.local \ No newline at end of file +cabal.project.local diff --git a/CHANGELOG.md b/CHANGELOG.md index a5ee1bd..9da4f36 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -1,4 +1,9 @@ # Changelog +## 0.1.1.0 -- 2024-08-22 + +- Depend on `foldable1-classes-compat` (when required) instead of + `semigroupoids`. + ## 0.1.0.0 - Open source the timeline library we use internally at Bellroy diff --git a/flake.lock b/flake.lock index 21fc4f0..e9368b2 100644 --- a/flake.lock +++ b/flake.lock @@ -2,16 +2,17 @@ "nodes": { "bellroy-nix-foss": { "inputs": { - "flake-compat": "flake-compat", "flake-utils": "flake-utils", - "nixpkgs": "nixpkgs" + "haskell-ci": "haskell-ci", + "nixpkgs": "nixpkgs", + "pre-commit-hooks": "pre-commit-hooks" }, "locked": { - "lastModified": 1719540486, - "narHash": "sha256-9Pw2PSOhLLr+M2pwd04RuYvem7l88g/Mh9kJNyKhyno=", + "lastModified": 1724294608, + "narHash": "sha256-08ckkY81cvEbRM6Fvog0leRVvF2yzqFLnEWCDmE1LQM=", "owner": "bellroy", "repo": "bellroy-nix-foss", - "rev": "e0c388f67e4821a3a3526e0a8547711c1de772f0", + "rev": "0966286b1f39ae7601bd6be79dd0405e7267a493", "type": "github" }, "original": { @@ -54,13 +55,51 @@ "type": "github" } }, + "gitignore": { + "inputs": { + "nixpkgs": [ + "bellroy-nix-foss", + "pre-commit-hooks", + "nixpkgs" + ] + }, + "locked": { + "lastModified": 1709087332, + "narHash": "sha256-HG2cCnktfHsKV0s4XW83gU3F57gaTljL9KNSuG6bnQs=", + "owner": "hercules-ci", + "repo": "gitignore.nix", + "rev": "637db329424fd7e46cf4185293b9cc8c88c95394", + "type": "github" + }, + "original": { + "owner": "hercules-ci", + "repo": "gitignore.nix", + "type": "github" + } + }, + "haskell-ci": { + "flake": false, + "locked": { + "lastModified": 1720460048, + "narHash": "sha256-k3YCC4RIVxocXYbNHkmGYvlsoFlv5XZmk1DYfVQMaPs=", + "owner": "haskell-ci", + "repo": "haskell-ci", + "rev": "5e5b27d74f90e73905c4f56f4aefe521f97879f0", + "type": "github" + }, + "original": { + "owner": "haskell-ci", + "repo": "haskell-ci", + "type": "github" + } + }, "nixpkgs": { "locked": { - "lastModified": 1719082008, - "narHash": "sha256-jHJSUH619zBQ6WdC21fFAlDxHErKVDJ5fpN0Hgx4sjs=", + "lastModified": 1724177844, + "narHash": "sha256-G7Mf9uN9m8FimeP3eMHu/dOC4QS8QAzo0h4ZIlDHcCA=", "owner": "NixOS", "repo": "nixpkgs", - "rev": "9693852a2070b398ee123a329e68f0dab5526681", + "rev": "d13fa5a45a34e7c8be33474f58003914430bdc5a", "type": "github" }, "original": { @@ -69,6 +108,46 @@ "type": "indirect" } }, + "nixpkgs-stable": { + "locked": { + "lastModified": 1720386169, + "narHash": "sha256-NGKVY4PjzwAa4upkGtAMz1npHGoRzWotlSnVlqI40mo=", + "owner": "NixOS", + "repo": "nixpkgs", + "rev": "194846768975b7ad2c4988bdb82572c00222c0d7", + "type": "github" + }, + "original": { + "owner": "NixOS", + "ref": "nixos-24.05", + "repo": "nixpkgs", + "type": "github" + } + }, + "pre-commit-hooks": { + "inputs": { + "flake-compat": "flake-compat", + "gitignore": "gitignore", + "nixpkgs": [ + "bellroy-nix-foss", + "nixpkgs" + ], + "nixpkgs-stable": "nixpkgs-stable" + }, + "locked": { + "lastModified": 1724159077, + "narHash": "sha256-AddE0u6WbA5R7uxumw1Ka0oG5dv3cTtN0ppO/M/e0cg=", + "owner": "cachix", + "repo": "pre-commit-hooks.nix", + "rev": "1064a45e81a4e19cda98741b71219d9f4f136900", + "type": "github" + }, + "original": { + "owner": "cachix", + "repo": "pre-commit-hooks.nix", + "type": "github" + } + }, "root": { "inputs": { "bellroy-nix-foss": "bellroy-nix-foss" diff --git a/flake.nix b/flake.nix index 93edef5..7c74cb1 100644 --- a/flake.nix +++ b/flake.nix @@ -6,6 +6,7 @@ }; outputs = inputs: inputs.bellroy-nix-foss.lib.haskellProject { + src = ./.; supportedCompilers = [ "ghc92" "ghc94" "ghc96" "ghc98" "ghc910" ]; defaultCompiler = "ghc96"; }; diff --git a/src/Data/Timeline.hs b/src/Data/Timeline.hs index 445a17c..18d7211 100644 --- a/src/Data/Timeline.hs +++ b/src/Data/Timeline.hs @@ -50,6 +50,7 @@ module Data.Timeline where import Data.Foldable.WithIndex (FoldableWithIndex (..)) +import Data.Foldable1 (fold1) import Data.Functor.Contravariant (Contravariant, contramap) import Data.Functor.WithIndex (FunctorWithIndex (..)) import Data.List (intercalate, sortOn) @@ -59,7 +60,6 @@ import Data.Map.Merge.Strict qualified as Map import Data.Map.Strict (Map) import Data.Map.Strict qualified as Map import Data.Maybe (mapMaybe, maybeToList) -import Data.Semigroup.Foldable.Class (fold1) import Data.Set (Set) import Data.Text (Text) import Data.Text qualified as T @@ -93,7 +93,7 @@ data Timeline t a = Timeline } deriving stock (Show, Eq, Generic, Functor, Foldable, Traversable) -instance Ord t => Applicative (Timeline t) where +instance (Ord t) => Applicative (Timeline t) where pure :: a -> Timeline t a pure a = Timeline {initialValue = a, values = mempty} @@ -113,7 +113,7 @@ instance Ord t => Applicative (Timeline t) where funcs values -tshow :: Show a => a -> Text +tshow :: (Show a) => a -> Text tshow = T.pack . show -- | Pretty-print @'Timeline' a@. It's provided so that you can investigate the @@ -133,7 +133,7 @@ prettyTimeline Timeline {initialValue, values} = -- | Extract a single value from the timeline peek :: - Ord t => + (Ord t) => Timeline t a -> -- | the time to peek t -> @@ -150,10 +150,10 @@ data TimeRange t = TimeRange deriving stock (Show, Eq, Ord, Generic) -- | If all time in 'TimeRange' is less than the given time -isTimeAfterRange :: Ord t => t -> TimeRange t -> Bool +isTimeAfterRange :: (Ord t) => t -> TimeRange t -> Bool isTimeAfterRange t TimeRange {to} = maybe False (t >=) to -instance Ord t => FunctorWithIndex (TimeRange t) (Timeline t) where +instance (Ord t) => FunctorWithIndex (TimeRange t) (Timeline t) where imap :: (TimeRange t -> a -> b) -> Timeline t a -> Timeline t b imap f Timeline {..} = Timeline @@ -165,9 +165,9 @@ instance Ord t => FunctorWithIndex (TimeRange t) (Timeline t) where where initialRange = TimeRange Nothing $ fst <$> Map.lookupMin values -instance Ord t => FoldableWithIndex (TimeRange t) (Timeline t) +instance (Ord t) => FoldableWithIndex (TimeRange t) (Timeline t) -instance Ord t => TraversableWithIndex (TimeRange t) (Timeline t) where +instance (Ord t) => TraversableWithIndex (TimeRange t) (Timeline t) where itraverse :: (Applicative f) => (TimeRange t -> a -> f b) -> Timeline t a -> f (Timeline t b) itraverse f = sequenceA . imap f @@ -203,7 +203,7 @@ recordValue = value -- | A smart constructor for @'Record' a@. -- Returns 'Nothing' if @effectiveTo@ is not greater than @effectiveFrom@ makeRecord :: - Ord t => + (Ord t) => -- | effective from t -> -- | optional effective to @@ -297,7 +297,7 @@ unpackOverlapGroup (OverlapGroup r1 r2 records) = r1 : r2 : records -- by wrapping the result in 'Maybe', so the only possible error is 'Overlaps'. -- The 'Traversable' instance of @'Timeline' a@ can be used to convert -- @'Timeline' ('Maybe' a)@ to @'Maybe' ('Timeline' a)@ -fromRecords :: forall t a. Ord t => [Record t a] -> Either (Overlaps t a) (Timeline t (Maybe a)) +fromRecords :: forall t a. (Ord t) => [Record t a] -> Either (Overlaps t a) (Timeline t (Maybe a)) fromRecords records = maybe (Right timeline) Left overlaps where diff --git a/timeline.cabal b/timeline.cabal index 063f2ed..16d5726 100644 --- a/timeline.cabal +++ b/timeline.cabal @@ -1,6 +1,6 @@ cabal-version: 2.2 name: timeline -version: 0.1.0.0 +version: 0.1.1.0 synopsis: Data type representing a piecewise-constant function over time @@ -15,7 +15,14 @@ author: Bellroy Tech Team maintainer: Bellroy Tech Team category: Development build-type: Simple -tested-with: GHC ==8.10.7 || ==9.2.8 || ==9.4.8 || ==9.6.5 || ==9.8.2 || ==9.10.1 +tested-with: + GHC ==8.10.7 + || ==9.2.8 + || ==9.4.8 + || ==9.6.6 + || ==9.8.2 + || ==9.10.1 + extra-source-files: CHANGELOG.md README.md @@ -29,9 +36,9 @@ common deps build-depends: , base >=4.14.3 && <4.21 , containers >=0.6.5 && <0.7.1 - , hedgehog >=1.1 && <1.5 + , hedgehog >=1.1 && <1.6 , indexed-traversable >=0.1.2 && <0.2 - , text ^>=1.2.4.1 || >=2.0 && <2.2 + , text ^>=1.2.4.1 || ^>=2.0 || ^>=2.1 , time >=1.9.3 && <1.15 library @@ -44,10 +51,12 @@ library default-language: Haskell2010 ghc-options: -Wall -fno-warn-unused-do-bind -fno-warn-unused-imports build-depends: - , semigroupoids >=5.3.7 && <6.1 , template-haskell >=2.16.0 && <2.23 , th-compat >=0.1.4 && <0.2 + if impl(ghc <9.6) + build-depends: foldable1-classes-compat ^>=0.1 + test-suite tests import: deps type: exitcode-stdio-1.0 @@ -58,8 +67,8 @@ test-suite tests build-tool-depends: tasty-discover:tasty-discover >=4.2 && <5.1 build-depends: , bytestring >=0.10 && <0.13 - , hashable ^>=1.4.2.0 - , tasty >=1.4.3 && <1.6 + , hashable ^>=1.4.2.0 || ^>=1.5 + , tasty >=1.4.3 && <1.6 , tasty-golden ^>=2.3.5 , tasty-hedgehog >=1.2.0.0 , tasty-hunit ^>=0.10.0.3