diff --git a/.config/mustache.yaml b/.config/mustache.yaml index 801c8af..dfbb187 100644 --- a/.config/mustache.yaml +++ b/.config/mustache.yaml @@ -3,6 +3,6 @@ "name":"yaya", "repo":"sellout/yaya", "summary":"Yet another … yet another recursion scheme library for Haskell", - "version":"0.1.0"}, + "version":"0.1.0.0"}, "type":{"name":"haskell"} } diff --git a/.config/project/default.nix b/.config/project/default.nix index 8e36b3a..8849bc7 100644 --- a/.config/project/default.nix +++ b/.config/project/default.nix @@ -1,4 +1,11 @@ -{config, flaky, lib, pkgs, self, ...}: { +{ + config, + flaky, + lib, + pkgs, + self, + ... +}: { project = { name = "yaya"; summary = "Yet another … yet another recursion scheme library for Haskell"; @@ -75,30 +82,56 @@ ## CI services.garnix = { enable = true; - builds.exclude = [ - # TODO: Remove once garnix-io/garnix#285 is fixed. - "homeConfigurations.x86_64-darwin-${config.project.name}-example" - ]; + builds = { + exclude = [ + # TODO: Remove once garnix-io/garnix#285 is fixed. + "homeConfigurations.x86_64-darwin-${config.project.name}-example" + ]; + include = lib.mkForce ( + [ + "homeConfigurations.*" + "nixosConfigurations.*" + ] + ++ lib.concatLists ( + flaky.lib.garnixChecks + ( + sys: + [ + "checks.${sys}.*" + "packages.${sys}.default" + ] + ++ lib.concatMap (ghc: [ + "devShells.${sys}.${ghc}" + "packages.${sys}.${ghc}_all" + ]) + (self.lib.testedGhcVersions sys) + ) + ) + ); + }; }; ## FIXME: Shouldn’t need `mkForce` here (or to duplicate the base contexts). ## Need to improve module merging. services.github.settings.branches.main.protection.required_status_checks.contexts = lib.mkForce - (map (ghc: "CI / build (${ghc}) (pull_request)") self.lib.nonNixTestedGhcVersions - ++ lib.concatLists (lib.concatMap flaky.lib.garnixChecks [ - (sys: lib.concatMap (ghc: [ + (map (ghc: "CI / build (${ghc}) (pull_request)") self.lib.nonNixTestedGhcVersions + ++ lib.concatLists (lib.concatMap flaky.lib.garnixChecks [ + (sys: + lib.concatMap (ghc: [ "devShell ${ghc} [${sys}]" "package ${ghc}_all [${sys}]" ]) - (self.lib.testedGhcVersions sys)) - (sys: [ - "homeConfig ${sys}-${config.project.name}-example" - "package default [${sys}]" - ## FIXME: These are duplicated from the base config - "check formatter [${sys}]" - "devShell default [${sys}]" - ]) - ])); + (self.lib.testedGhcVersions sys)) + (sys: [ + "homeConfig ${sys}-${config.project.name}-example" + "package default [${sys}]" + ## FIXME: These are duplicated from the base config + "check formatter [${sys}]" + "check project-manager-files [${sys}]" + "check vale [${sys}]" + "devShell default [${sys}]" + ]) + ])); ## publishing services.flakehub.enable = true; diff --git a/.config/project/github-ci.nix b/.config/project/github-ci.nix index 5cbbef1..e30d897 100644 --- a/.config/project/github-ci.nix +++ b/.config/project/github-ci.nix @@ -1,4 +1,4 @@ -{lib, self, ...}: { +{lib, pkgs, self, ...}: { services.github.workflow."build.yml".text = lib.generators.toYAML {} { name = "CI"; on = { @@ -11,10 +11,12 @@ jobs.build = { strategy = { fail-fast = false; - matrix.os = ["macos-13" "ubuntu-22.04" "windows-2022"]; - ## TODO: Populate this as the difference between supported versions and - ## available nix package sets. - matrix.ghc = self.lib.nonNixTestedGhcVersions; + matrix = { + ## TODO: Populate this as the difference between supported versions + ## and available nix package sets. + ghc = self.lib.nonNixTestedGhcVersions; + os = ["macos-13" "ubuntu-22.04" "windows-2022"]; + }; }; runs-on = "\${{ matrix.os }}"; env.CONFIG = "--enable-tests --enable-benchmarks"; @@ -25,7 +27,7 @@ id = "setup-haskell-cabal"; "with" = { ghc-version = "\${{ matrix.ghc }}"; - cabal-version = "3.10"; + cabal-version = pkgs.cabal-install.version; }; } {run = "cabal v2-update";} @@ -40,6 +42,9 @@ key = "\${{ runner.os }}-\${{ matrix.ghc }}-\${{ hashFiles('cabal.project.freeze') }}"; }; } + ## NB: The `doctests` suites don’t seem to get built without explicitly + ## doing so before running the tests. + {run = "cabal v2-build all $CONFIG";} {run = "cabal v2-test all $CONFIG";} ]; }; diff --git a/.github/settings.yml b/.github/settings.yml index 8f788cb..18a4e46 100644 --- a/.github/settings.yml +++ b/.github/settings.yml @@ -1,2 +1,2 @@ # This file was generated by Project Manager. -{"actions":{"permissions":{"workflow":{"can_approve_pull_request_reviews":true}}},"branches":[{"name":"main","protection":{"allow_force_pushes":false,"enforce_admins":true,"required_linear_history":false,"required_pull_request_reviews":null,"required_status_checks":{"contexts":["CI / build (8.6.1) (pull_request)","CI / build (8.8.1) (pull_request)","CI / build (8.10.1) (pull_request)","CI / build (9.0.1) (pull_request)","CI / build (9.2.1) (pull_request)","CI / build (9.4.1) (pull_request)","CI / build (9.6.1) (pull_request)","devShell ghc948 [aarch64-darwin]","package ghc948_all [aarch64-darwin]","devShell ghc981 [aarch64-darwin]","package ghc981_all [aarch64-darwin]","devShell ghc948 [aarch64-linux]","package ghc948_all [aarch64-linux]","devShell ghc981 [aarch64-linux]","package ghc981_all [aarch64-linux]","devShell ghc884 [aarch64-linux]","package ghc884_all [aarch64-linux]","devShell ghc948 [i686-linux]","package ghc948_all [i686-linux]","devShell ghc981 [i686-linux]","package ghc981_all [i686-linux]","devShell ghc884 [i686-linux]","package ghc884_all [i686-linux]","devShell ghc948 [x86_64-linux]","package ghc948_all [x86_64-linux]","devShell ghc981 [x86_64-linux]","package ghc981_all [x86_64-linux]","devShell ghc884 [x86_64-linux]","package ghc884_all [x86_64-linux]","homeConfig aarch64-darwin-yaya-example","package default [aarch64-darwin]","check formatter [aarch64-darwin]","devShell default [aarch64-darwin]","homeConfig aarch64-linux-yaya-example","package default [aarch64-linux]","check formatter [aarch64-linux]","devShell default [aarch64-linux]","homeConfig i686-linux-yaya-example","package default [i686-linux]","check formatter [i686-linux]","devShell default [i686-linux]","homeConfig x86_64-linux-yaya-example","package default [x86_64-linux]","check formatter [x86_64-linux]","devShell default [x86_64-linux]"],"strict":false},"restrictions":null}}],"labels":[{"color":"","description":"Created automatically by some service or process","name":"automated"},{"color":"#d73a4a","description":"Something isn’t working","name":"bug"},{"color":"#333333","description":"Updates or other changes to dependencies","name":"dependencies"},{"color":"#0075ca","description":"Improvements or additions to documentation","name":"documentation"},{"color":"#a2eeef","description":"New feature or request","name":"enhancement"},{"color":"#7057ff","description":"Good for newcomers","name":"good first issue"},{"color":"#000000","description":"Issues you want contributors to help with.","name":"hacktoberfest"},{"color":"#ff7518","description":"Indicates acceptance for Hacktoberfest criteria, even if not merged yet.","name":"hacktoberfest-accepted"},{"color":"#008672","description":"Extra attention is needed","name":"help wanted"},{"color":"#333333","description":"Unaccepted contributions that haven’t been closed for some reason.","name":"invalid"},{"color":"#d876e3","description":"Further information is requested","name":"question"},{"color":"#ffc0cb","description":"Topic created in bad faith. Services like Hacktoberfest use this to identify bad actors.","name":"spam"},{"color":"#d4af37","description":"Work prioritized by a sponsor","name":"sponsored"}],"repository":{"allow_merge_commit":true,"allow_rebase_merge":false,"allow_squash_merge":false,"default_branch":"main","delete_branch_on_merge":true,"description":"Yet another … yet another recursion scheme library for Haskell","enable_automated_security_fixes":true,"enable_vulnerability_alerts":true,"has_downloads":false,"has_issues":true,"has_projects":true,"has_wiki":true,"merge_commit_message":"PR_BODY","merge_commit_title":"PR_TITLE","name":"yaya","private":false,"topics":"hacktoberfest, recursion-schemes"}} \ No newline at end of file +{"actions":{"permissions":{"workflow":{"can_approve_pull_request_reviews":true}}},"branches":[{"name":"main","protection":{"allow_force_pushes":false,"enforce_admins":true,"required_linear_history":false,"required_pull_request_reviews":null,"required_status_checks":{"contexts":["CI / build (8.6.1) (pull_request)","CI / build (8.8.1) (pull_request)","CI / build (8.10.1) (pull_request)","CI / build (9.0.1) (pull_request)","CI / build (9.2.1) (pull_request)","CI / build (9.4.1) (pull_request)","CI / build (9.6.1) (pull_request)","devShell ghc948 [aarch64-darwin]","package ghc948_all [aarch64-darwin]","devShell ghc981 [aarch64-darwin]","package ghc981_all [aarch64-darwin]","devShell ghc948 [aarch64-linux]","package ghc948_all [aarch64-linux]","devShell ghc981 [aarch64-linux]","package ghc981_all [aarch64-linux]","devShell ghc884 [aarch64-linux]","package ghc884_all [aarch64-linux]","devShell ghc948 [i686-linux]","package ghc948_all [i686-linux]","devShell ghc981 [i686-linux]","package ghc981_all [i686-linux]","devShell ghc884 [i686-linux]","package ghc884_all [i686-linux]","devShell ghc948 [x86_64-linux]","package ghc948_all [x86_64-linux]","devShell ghc981 [x86_64-linux]","package ghc981_all [x86_64-linux]","devShell ghc884 [x86_64-linux]","package ghc884_all [x86_64-linux]","homeConfig aarch64-darwin-yaya-example","package default [aarch64-darwin]","check formatter [aarch64-darwin]","check project-manager-files [aarch64-darwin]","check vale [aarch64-darwin]","devShell default [aarch64-darwin]","homeConfig aarch64-linux-yaya-example","package default [aarch64-linux]","check formatter [aarch64-linux]","check project-manager-files [aarch64-linux]","check vale [aarch64-linux]","devShell default [aarch64-linux]","homeConfig i686-linux-yaya-example","package default [i686-linux]","check formatter [i686-linux]","check project-manager-files [i686-linux]","check vale [i686-linux]","devShell default [i686-linux]","homeConfig x86_64-linux-yaya-example","package default [x86_64-linux]","check formatter [x86_64-linux]","check project-manager-files [x86_64-linux]","check vale [x86_64-linux]","devShell default [x86_64-linux]"],"strict":false},"restrictions":null}}],"labels":[{"color":"","description":"Created automatically by some service or process","name":"automated"},{"color":"#d73a4a","description":"Something isn’t working","name":"bug"},{"color":"#333333","description":"Updates or other changes to dependencies","name":"dependencies"},{"color":"#0075ca","description":"Improvements or additions to documentation","name":"documentation"},{"color":"#a2eeef","description":"New feature or request","name":"enhancement"},{"color":"#7057ff","description":"Good for newcomers","name":"good first issue"},{"color":"#000000","description":"Issues you want contributors to help with.","name":"hacktoberfest"},{"color":"#ff7518","description":"Indicates acceptance for Hacktoberfest criteria, even if not merged yet.","name":"hacktoberfest-accepted"},{"color":"#008672","description":"Extra attention is needed","name":"help wanted"},{"color":"#333333","description":"Unaccepted contributions that haven’t been closed for some reason.","name":"invalid"},{"color":"#d876e3","description":"Further information is requested","name":"question"},{"color":"#ffc0cb","description":"Topic created in bad faith. Services like Hacktoberfest use this to identify bad actors.","name":"spam"},{"color":"#d4af37","description":"Work prioritized by a sponsor","name":"sponsored"}],"repository":{"allow_merge_commit":true,"allow_rebase_merge":false,"allow_squash_merge":false,"default_branch":"main","delete_branch_on_merge":true,"description":"Yet another … yet another recursion scheme library for Haskell","enable_automated_security_fixes":true,"enable_vulnerability_alerts":true,"has_downloads":false,"has_issues":true,"has_projects":true,"has_wiki":true,"merge_commit_message":"PR_BODY","merge_commit_title":"PR_TITLE","name":"yaya","private":false,"topics":"hacktoberfest, recursion-schemes"}} \ No newline at end of file diff --git a/.github/workflows/build.yml b/.github/workflows/build.yml index c749f00..0ac9617 100644 --- a/.github/workflows/build.yml +++ b/.github/workflows/build.yml @@ -1 +1 @@ -{"jobs":{"build":{"env":{"CONFIG":"--enable-tests --enable-benchmarks"},"runs-on":"${{ matrix.os }}","steps":[{"uses":"actions/checkout@v4"},{"id":"setup-haskell-cabal","uses":"haskell-actions/setup@v2","with":{"cabal-version":"3.10","ghc-version":"${{ matrix.ghc }}"}},{"run":"cabal v2-update"},{"run":"cabal v2-freeze $CONFIG"},{"uses":"actions/cache@v4","with":{"key":"${{ runner.os }}-${{ matrix.ghc }}-${{ hashFiles('cabal.project.freeze') }}","path":"${{ steps.setup-haskell-cabal.outputs.cabal-store }}\ndist-newstyle\n"}},{"run":"cabal v2-test all $CONFIG"}],"strategy":{"fail-fast":false,"matrix":{"ghc":["8.6.1","8.8.1","8.10.1","9.0.1","9.2.1","9.4.1","9.6.1"],"os":["macos-13","ubuntu-22.04","windows-2022"]}}}},"name":"CI","on":{"pull_request":{"types":["opened","synchronize"]},"push":{"branches":["main"]}}} \ No newline at end of file +{"jobs":{"build":{"env":{"CONFIG":"--enable-tests --enable-benchmarks"},"runs-on":"${{ matrix.os }}","steps":[{"uses":"actions/checkout@v4"},{"id":"setup-haskell-cabal","uses":"haskell-actions/setup@v2","with":{"cabal-version":"3.10.2.1","ghc-version":"${{ matrix.ghc }}"}},{"run":"cabal v2-update"},{"run":"cabal v2-freeze $CONFIG"},{"uses":"actions/cache@v4","with":{"key":"${{ runner.os }}-${{ matrix.ghc }}-${{ hashFiles('cabal.project.freeze') }}","path":"${{ steps.setup-haskell-cabal.outputs.cabal-store }}\ndist-newstyle\n"}},{"run":"cabal v2-build all $CONFIG"},{"run":"cabal v2-test all $CONFIG"}],"strategy":{"fail-fast":false,"matrix":{"ghc":["8.6.1","8.8.1","8.10.1","9.0.1","9.2.1","9.4.1","9.6.1"],"os":["macos-13","ubuntu-22.04","windows-2022"]}}}},"name":"CI","on":{"pull_request":{"types":["opened","synchronize"]},"push":{"branches":["main"]}}} \ No newline at end of file diff --git a/README.md b/README.md index 7c026c4..c2f57e5 100644 --- a/README.md +++ b/README.md @@ -2,7 +2,7 @@ [![built with garnix](https://img.shields.io/endpoint?url=https%3A%2F%2Fgarnix.io%2Fapi%2Fbadges%2Fsellout%2Fyaya)](https://garnix.io) [![Packaging status](https://repology.org/badge/tiny-repos/haskell:yaya.svg)](https://repology.org/project/haskell:yaya/versions) -[![latest packaged version(s)](https://repology.org/badge/latest-versions/haskell:yaya.svg)](https://repology.org/project/haskell:yaya/versions) +[![latest packaged versions](https://repology.org/badge/latest-versions/haskell:yaya.svg)](https://repology.org/project/haskell:yaya/versions) Yet another … yet another recursion scheme library for Haskell @@ -33,7 +33,7 @@ To mitigate some of those issues for versioning, we assume the following usage: - modules should be imported using `PackageImports`, so that adding modules is a _minor_ change; - modules should be imported qualified, so that adding definitions is a _minor_ change; -- adding instances can't be mitigated in the same way, and it's not uncommon for downstream libraries to add orphans instances when they're omitted from upstream libraries. However, since these conflicts can only happen via direct dependencies, and represent an explicit downstream workaround, it's reasonable to expect a quick downstream update to remove or conditionalize the workaround. So, this is considered a _minor major_ change; +- adding instances can't be mitigated in the same way, and it's not uncommon for downstream libraries to add orphans instances when they're omitted from upstream libraries. However, since these conflicts can only happen via direct dependencies, and represent an explicit downstream workaround, it’s reasonable to expect a quick downstream update to remove or conditionalize the workaround. So, this is considered a _minor major_ change; - deprecation is considered a _revision_ change, however it will often be paired with _minor_ changes. `-Werror` can cause this to fail, but published libraries shouldn't be compiled with `-Werror`. ## building & development diff --git a/Setup.hs b/Setup.hs deleted file mode 100644 index e8ef27d..0000000 --- a/Setup.hs +++ /dev/null @@ -1,3 +0,0 @@ -import Distribution.Simple - -main = defaultMain diff --git a/cabal.project b/cabal.project index 84a248f..e352117 100644 --- a/cabal.project +++ b/cabal.project @@ -1,5 +1,6 @@ program-options - ghc-options: -Werror + ghc-options: + -Werror tests: True diff --git a/containers/Setup.hs b/containers/Setup.hs new file mode 100644 index 0000000..6cea120 --- /dev/null +++ b/containers/Setup.hs @@ -0,0 +1,14 @@ +-- __NB__: `custom-setup` doesn’t have any way to specify extensions, so any we +-- want need to be specified here. +{-# LANGUAGE PackageImports #-} +{-# LANGUAGE Unsafe #-} +{-# LANGUAGE NoImplicitPrelude #-} +{-# OPTIONS_GHC -Wall #-} + +module Main (main) where + +import safe "base" System.IO (IO) +import "cabal-doctest" Distribution.Extra.Doctest (defaultMainWithDoctests) + +main :: IO () +main = defaultMainWithDoctests "doctests" diff --git a/containers/src/Yaya/Containers/Pattern/IntMap.hs b/containers/src/Yaya/Containers/Pattern/IntMap.hs index b6f47ca..7757285 100644 --- a/containers/src/Yaya/Containers/Pattern/IntMap.hs +++ b/containers/src/Yaya/Containers/Pattern/IntMap.hs @@ -1,3 +1,4 @@ +{-# LANGUAGE Safe #-} {-# OPTIONS_GHC -Wno-orphans #-} module Yaya.Containers.Pattern.IntMap diff --git a/containers/src/Yaya/Containers/Pattern/IntSet.hs b/containers/src/Yaya/Containers/Pattern/IntSet.hs index 3b33cc6..509f992 100644 --- a/containers/src/Yaya/Containers/Pattern/IntSet.hs +++ b/containers/src/Yaya/Containers/Pattern/IntSet.hs @@ -1,3 +1,4 @@ +{-# LANGUAGE Safe #-} {-# OPTIONS_GHC -Wno-orphans #-} module Yaya.Containers.Pattern.IntSet diff --git a/containers/src/Yaya/Containers/Pattern/Map.hs b/containers/src/Yaya/Containers/Pattern/Map.hs index 953b6b4..8344e15 100644 --- a/containers/src/Yaya/Containers/Pattern/Map.hs +++ b/containers/src/Yaya/Containers/Pattern/Map.hs @@ -1,3 +1,4 @@ +{-# LANGUAGE Safe #-} {-# OPTIONS_GHC -Wno-orphans #-} module Yaya.Containers.Pattern.Map diff --git a/containers/src/Yaya/Containers/Pattern/Set.hs b/containers/src/Yaya/Containers/Pattern/Set.hs index f3f9ae9..cef8ec5 100644 --- a/containers/src/Yaya/Containers/Pattern/Set.hs +++ b/containers/src/Yaya/Containers/Pattern/Set.hs @@ -1,3 +1,4 @@ +{-# LANGUAGE Safe #-} {-# OPTIONS_GHC -Wno-orphans #-} module Yaya.Containers.Pattern.Set diff --git a/containers/tests/doctests.hs b/containers/tests/doctests.hs new file mode 100644 index 0000000..26008dc --- /dev/null +++ b/containers/tests/doctests.hs @@ -0,0 +1,10 @@ +module Main (main) where + +import "base" Data.Function (($)) +import "base" Data.Semigroup (Semigroup ((<>))) +import "base" System.IO (IO) +import "doctest" Test.DocTest (doctest) +import "this" Build_doctests (flags, module_sources, pkgs) + +main :: IO () +main = doctest $ flags <> pkgs <> module_sources diff --git a/containers/yaya-containers.cabal b/containers/yaya-containers.cabal index 78c9e7a..039ca99 100644 --- a/containers/yaya-containers.cabal +++ b/containers/yaya-containers.cabal @@ -1,51 +1,165 @@ -name: yaya-containers -version: 0.1.0.0 -synopsis: Pattern functors and instances for types in the containers - package. -homepage: https://github.com/sellout/yaya#readme -author: Greg Pfeil -maintainer: greg@technomadic.org -copyright: 2024 Greg Pfeil -license: AGPL-3 -license-file: LICENSE -category: Recursion -build-type: Simple -extra-source-files: CHANGELOG.md - , README.md -cabal-version: >=1.10 -tested-with: GHC == 8.6.1 - , GHC == 8.8.1, GHC == 8.8.4 - , GHC == 8.10.1 - , GHC == 9.0.1 - , GHC == 9.2.1 - , GHC == 9.4.1, GHC == 9.4.8 - , GHC == 9.6.1 - , GHC == 9.8.1 +cabal-version: 3.0 -library - hs-source-dirs: src - exposed-modules: Yaya.Containers.Pattern.IntMap - , Yaya.Containers.Pattern.IntSet - , Yaya.Containers.Pattern.Map - , Yaya.Containers.Pattern.Set - build-depends: base >= 4.7 && < 5 - , containers - , yaya >= 0.5.0 - default-extensions: ConstraintKinds - , DeriveGeneric - , DeriveTraversable - , FlexibleContexts - , FlexibleInstances - , FunctionalDependencies - , LambdaCase - , MultiParamTypeClasses - , PackageImports - , RankNTypes - , ScopedTypeVariables - , StrictData - , NoImplicitPrelude - default-language: Haskell2010 +name: yaya-containers +version: 0.1.0.1 +synopsis: Pattern functors and instances for types in the containers package. +author: Greg Pfeil +maintainer: Greg Pfeil +copyright: 2024 Greg Pfeil +homepage: https://github.com/sellout/yaya#readme +bug-reports: https://github.com/sellout/yaya/issues +category: Recursion +build-type: Custom +license: AGPL-3.0-or-later +license-files: + LICENSE +extra-source-files: + CHANGELOG.md + README.md +tested-with: + GHC == { +-- GHCup Nixpkgs + 8.6.1, + 8.8.1, 8.8.4, + 8.10.1, + 9.0.1, + 9.2.1, + 9.4.1, 9.4.8, + 9.6.1, + 9.8.1 + } source-repository head - type: git + type: git location: https://github.com/sellout/yaya + +-- This mimics the GHC2021 extension +-- (https://ghc.gitlab.haskell.org/ghc/doc/users_guide/exts/control.html?highlight=doandifthenelse#extension-GHC2021), +-- but supporting compilers back to GHC 7.10. If the oldest supported compiler +-- is GHC 9.2, then this stanza can be removed and `import: GHC2021` can be +-- replaced by `default-language: GHC2021`. +common GHC2021 + default-language: Haskell2010 + default-extensions: + BangPatterns + BinaryLiterals + ConstraintKinds + DeriveDataTypeable + DeriveGeneric + -- DeriveLift -- uncomment if the oldest supported version is GHC 8.10.1+ + DeriveTraversable + DerivingStrategies + DoAndIfThenElse + EmptyCase + ExistentialQuantification + FlexibleContexts + FlexibleInstances + GADTSyntax + GeneralizedNewtypeDeriving + HexFloatLiterals + -- ImportQualifiedPost -- uncomment if the oldest supported version is GHC 8.10.1+ + InstanceSigs + LambdaCase + MagicHash + MonadComprehensions + MonomorphismRestriction + MultiParamTypeClasses + NamedFieldPuns + NamedWildCards + NumericUnderscores + PolyKinds + PostfixOperators + RankNTypes + ScopedTypeVariables + StandaloneDeriving + -- StandaloneKindSignatures -- uncomment if the oldest supported version is GHC 8.10.1+ + TupleSections + TypeApplications + TypeOperators + UnicodeSyntax + NoExplicitNamespaces + +common defaults + import: GHC2021 + build-depends: + base ^>= {4.12.0, 4.13.0, 4.14.0, 4.15.0, 4.16.0, 4.17.0, 4.18.0, 4.19.0}, + ghc-options: + -Wall + -Wtrustworthy-safe + -fpackage-trust + if impl(ghc >= 8.10.1) + ghc-options: + -Wmissing-safe-haskell-mode + default-extensions: + DefaultSignatures + ExplicitNamespaces + FunctionalDependencies + LiberalTypeSynonyms + -- replace with `LexicalNegation` if the oldest supported version is GHC 9.0.1+ + NegativeLiterals + PackageImports + ParallelListComp + -- QualifiedDo - uncomment if the oldest supported version is GHC 9.0.1+ + RecursiveDo + -- RequiredTypeArguments - uncomment if the oldest supported version is GHC 9.10.1+ + StrictData + TemplateHaskellQuotes + TransformListComp + NoGeneralizedNewtypeDeriving + NoImplicitPrelude + NoMonomorphismRestriction + NoPatternGuards + NoTypeApplications + +custom-setup + setup-depends: + -- TODO: Remove `Cabal` dep once haskell/cabal#3751 is fixed. + Cabal ^>= {3.0.0, 3.2.0, 3.4.0, 3.6.0, 3.8.0, 3.10.0}, + base ^>= {4.12.0, 4.13.0, 4.14.0, 4.15.0, 4.16.0, 4.17.0, 4.18.0, 4.19.0}, + cabal-doctest ^>= 1.0.0 + +library + import: defaults + hs-source-dirs: src + exposed-modules: + Yaya.Containers.Pattern.IntMap + Yaya.Containers.Pattern.IntSet + Yaya.Containers.Pattern.Map + Yaya.Containers.Pattern.Set + build-depends: + containers ^>= {0.6.0, 0.7}, + yaya ^>= 0.5.0, + ghc-options: + -trust adjunctions + -trust array + -trust base + -trust base-orphans + -trust binary + -trust bytestring + -trust containers + -trust distributive + -trust exceptions + -trust ghc-prim + -trust profunctors + -trust semigroupoids + -trust stm + -trust text + -trust transformers-compat + if impl(ghc < 9.6) + ghc-options: + -trust foldable1-classes-compat + +test-suite doctests + import: defaults + type: exitcode-stdio-1.0 + hs-source-dirs: tests + main-is: doctests.hs + build-depends: + doctest ^>= {0.15.0, 0.16.0, 0.17.0, 0.18.0, 0.19.0, 0.20.0, 0.21.0, 0.22.0}, + yaya-containers, + default-extensions: + -- TODO: Other flags require each module to be compiled with a safety level. + -- Since it’s currently not possible to add `{-# LANGUAGE Safe -#}` to + -- the generated “Build_doctests.hs” and since doctests.hs is + -- `Unsafe`, this is the only safety level that can be used. + Unsafe diff --git a/core-test/test/Test/Fold.hs b/core-test/test/Test/Fold.hs index 9a36c13..f5b4be1 100644 --- a/core-test/test/Test/Fold.hs +++ b/core-test/test/Test/Fold.hs @@ -1,26 +1,28 @@ {-# LANGUAGE TemplateHaskell #-} +{-# LANGUAGE Unsafe #-} +{-# OPTIONS_GHC -Wno-unrecognised-pragmas #-} module Test.Fold where -import "base" Control.Category (Category (..)) -import "base" Control.Monad ((=<<)) -import "base" Data.Bool (Bool) -import "base" Data.Function (($)) -import "base" Data.Proxy (Proxy (..)) -import "base" System.IO (IO) -import "hedgehog" Hedgehog (Property, checkParallel, discover, forAll, property) -import qualified "hedgehog" Hedgehog.Gen as Gen -import "yaya" Yaya.Fold (Mu) -import "yaya" Yaya.Fold.Common (size) -import "yaya-hedgehog" Yaya.Hedgehog.Expr (Expr, genExpr, genMuExpr) -import "yaya-hedgehog" Yaya.Hedgehog.Fold +import safe "base" Control.Category (Category (..)) +import safe "base" Control.Monad ((=<<)) +import safe "base" Data.Bool (Bool) +import safe "base" Data.Function (($)) +import safe "base" Data.Proxy (Proxy (..)) +import safe "base" System.IO (IO) +import safe "hedgehog" Hedgehog (Property, checkParallel, discover, forAll, property) +import safe qualified "hedgehog" Hedgehog.Gen as Gen +import safe "yaya" Yaya.Fold (Mu) +import safe "yaya" Yaya.Fold.Common (size) +import safe "yaya-hedgehog" Yaya.Hedgehog.Expr (Expr, genExpr, genMuExpr) +import safe "yaya-hedgehog" Yaya.Hedgehog.Fold ( law_cataCancel, law_cataCompose, law_cataRefl, ) -- TODO: For some reason HLint is complaining that TemplateHaskell is unused. -{-# ANN module "HLint: ignore Unused LANGUAGE pragma" #-} +{-# HLINT ignore "Unused LANGUAGE pragma" #-} prop_muCataCancel :: Property prop_muCataCancel = diff --git a/core-test/test/Test/Fold/Common.hs b/core-test/test/Test/Fold/Common.hs index 2bb5b95..9692e35 100644 --- a/core-test/test/Test/Fold/Common.hs +++ b/core-test/test/Test/Fold/Common.hs @@ -1,14 +1,16 @@ {-# LANGUAGE TemplateHaskell #-} +{-# LANGUAGE Unsafe #-} +{-# OPTIONS_GHC -Wno-unrecognised-pragmas #-} module Test.Fold.Common where -import "base" Control.Category (Category (..)) -import "base" Control.Monad ((=<<)) -import "base" Data.Bool (Bool) -import "base" Data.Functor (Functor (..)) -import "base" Data.Ord (Ord (..)) -import "base" System.IO (IO) -import "hedgehog" Hedgehog +import safe "base" Control.Category (Category (..)) +import safe "base" Control.Monad ((=<<)) +import safe "base" Data.Bool (Bool) +import safe "base" Data.Functor (Functor (..)) +import safe "base" Data.Ord (Ord (..)) +import safe "base" System.IO (IO) +import safe "hedgehog" Hedgehog ( Property, assert, checkParallel, @@ -16,15 +18,15 @@ import "hedgehog" Hedgehog forAll, property, ) -import qualified "hedgehog" Hedgehog.Gen as Gen -import "yaya" Yaya.Fold (Recursive (..), zipAlgebras) -import "yaya" Yaya.Fold.Common (height, size) -import "yaya" Yaya.Pattern (uncurry) -import "yaya-hedgehog" Yaya.Hedgehog.Expr (genMuExpr) -import "base" Prelude (Integral (..)) +import safe qualified "hedgehog" Hedgehog.Gen as Gen +import safe "yaya" Yaya.Fold (Recursive (..), zipAlgebras) +import safe "yaya" Yaya.Fold.Common (height, size) +import safe "yaya" Yaya.Pattern (uncurry) +import safe "yaya-hedgehog" Yaya.Hedgehog.Expr (genMuExpr) +import safe "base" Prelude (Integral (..)) -- TODO: For some reason HLint is complaining that TemplateHaskell is unused. -{-# ANN module "HLint: ignore Unused LANGUAGE pragma" #-} +{-# HLINT ignore "Unused LANGUAGE pragma" #-} prop_heightLtSize :: Property prop_heightLtSize = diff --git a/core-test/test/Test/Fold/Native.hs b/core-test/test/Test/Fold/Native.hs index a2c08cf..0bc8d57 100644 --- a/core-test/test/Test/Fold/Native.hs +++ b/core-test/test/Test/Fold/Native.hs @@ -1,26 +1,28 @@ {-# LANGUAGE TemplateHaskell #-} +{-# LANGUAGE Unsafe #-} +{-# OPTIONS_GHC -Wno-unrecognised-pragmas #-} module Test.Fold.Native where -import "base" Control.Category (Category (id)) -import "base" Control.Monad ((=<<)) -import "base" Data.Bool (Bool) -import "base" Data.Function (($)) -import "base" Data.Proxy (Proxy (Proxy)) -import "base" System.IO (IO) -import "hedgehog" Hedgehog (Property, checkParallel, discover, forAll, property) -import qualified "hedgehog" Hedgehog.Gen as Gen -import "yaya" Yaya.Fold.Common (size) -import "yaya" Yaya.Fold.Native (Fix) -import "yaya-hedgehog" Yaya.Hedgehog.Expr (Expr, genExpr, genFixExpr) -import "yaya-hedgehog" Yaya.Hedgehog.Fold +import safe "base" Control.Category (Category (id)) +import safe "base" Control.Monad ((=<<)) +import safe "base" Data.Bool (Bool) +import safe "base" Data.Function (($)) +import safe "base" Data.Proxy (Proxy (Proxy)) +import safe "base" System.IO (IO) +import safe "hedgehog" Hedgehog (Property, checkParallel, discover, forAll, property) +import safe qualified "hedgehog" Hedgehog.Gen as Gen +import safe "yaya" Yaya.Fold.Common (size) +import safe "yaya" Yaya.Fold.Native (Fix) +import safe "yaya-hedgehog" Yaya.Hedgehog.Expr (Expr, genExpr, genFixExpr) +import safe "yaya-hedgehog" Yaya.Hedgehog.Fold ( law_cataCancel, law_cataCompose, law_cataRefl, ) -- TODO: For some reason HLint is complaining that TemplateHaskell is unused. -{-# ANN module "HLint: ignore Unused LANGUAGE pragma" #-} +{-# HLINT ignore "Unused LANGUAGE pragma" #-} prop_fixCataCancel :: Property prop_fixCataCancel = diff --git a/core-test/test/Test/Retrofit.hs b/core-test/test/Test/Retrofit.hs index 93f4498..4c011ba 100644 --- a/core-test/test/Test/Retrofit.hs +++ b/core-test/test/Test/Retrofit.hs @@ -1,18 +1,17 @@ --- These are both needed by `extractPatternFunctor`. -{-# LANGUAGE DeriveTraversable #-} {-# LANGUAGE TemplateHaskell #-} +{-# LANGUAGE Unsafe #-} -- | The point of this module is that it should compile _without_ importing any -- other Yaya modules. module Test.Retrofit where -import "base" Data.Bool (Bool) -import "base" Data.Eq (Eq) -import "base" Data.Int (Int) -import "base" System.IO (IO) -import "base" Text.Show (Show) -import "hedgehog" Hedgehog (checkParallel, discover) -import "yaya" Yaya.Retrofit (defaultRules, extractPatternFunctor) +import safe "base" Data.Bool (Bool) +import safe "base" Data.Eq (Eq) +import safe "base" Data.Int (Int) +import safe "base" System.IO (IO) +import safe "base" Text.Show (Show) +import safe "hedgehog" Hedgehog (checkParallel, discover) +import safe "yaya" Yaya.Retrofit (defaultRules, extractPatternFunctor) data DExpr = Lit Int diff --git a/core-test/test/test.hs b/core-test/test/test.hs index 567cc26..6901307 100644 --- a/core-test/test/test.hs +++ b/core-test/test/test.hs @@ -1,5 +1,7 @@ -import "base" System.IO (IO) -import "hedgehog" Hedgehog.Main (defaultMain) +{-# LANGUAGE Unsafe #-} + +import safe "base" System.IO (IO) +import safe "hedgehog" Hedgehog.Main (defaultMain) import qualified "this" Test.Fold as Fold import qualified "this" Test.Fold.Common as Fold.Common import qualified "this" Test.Retrofit as Retrofit diff --git a/core-test/yaya-test.cabal b/core-test/yaya-test.cabal index 7108d5b..0c4e6c9 100644 --- a/core-test/yaya-test.cabal +++ b/core-test/yaya-test.cabal @@ -1,46 +1,149 @@ -name: yaya-test -version: 0.3.1.1 -synopsis: Test suites for `yaya`. -description: This package should not be depended on by anything. -homepage: https://github.com/sellout/yaya#readme -author: Greg Pfeil -maintainer: greg@technomadic.org -copyright: 2017 Greg Pfeil -license: AGPL-3 -license-file: LICENSE -category: Recursion -build-type: Simple -cabal-version: >=1.10 -tested-with: GHC == 8.6.1 - , GHC == 8.8.1, GHC == 8.8.4 - , GHC == 8.10.1 - , GHC == 9.0.1 - , GHC == 9.2.1 - , GHC == 9.4.1, GHC == 9.4.8 - , GHC == 9.6.1 - , GHC == 9.8.1 +cabal-version: 3.0 -test-suite yaya-test - type: exitcode-stdio-1.0 - hs-source-dirs: test - main-is: test.hs - other-modules: Test.Fold - , Test.Fold.Common - , Test.Fold.Native - , Test.Retrofit - build-depends: base >= 4.7 && < 5 - , deriving-compat - , hedgehog - , yaya >= 0.5.0 - , yaya-hedgehog >= 0.2.0 - default-extensions: LambdaCase - , MultiParamTypeClasses - , PackageImports - , StrictData - , NoImplicitPrelude - ghc-options: -threaded -rtsopts -with-rtsopts=-N -Wall - default-language: Haskell2010 +name: yaya-test +version: 0.3.1.2 +synopsis: Test suites for `yaya`. +description: This package should not be depended on by anything. +author: Greg Pfeil +maintainer: Greg Pfeil +copyright: 2017 Greg Pfeil +homepage: https://github.com/sellout/yaya#readme +bug-reports: https://github.com/sellout/yaya/issues +category: Recursion +build-type: Simple +license: AGPL-3.0-or-later +license-files: + LICENSE +tested-with: + GHC == { +-- GHCup Nixpkgs + 8.6.1, + 8.8.1, 8.8.4, + 8.10.1, + 9.0.1, + 9.2.1, + 9.4.1, 9.4.8, + 9.6.1, + 9.8.1 + } source-repository head - type: git + type: git location: https://github.com/sellout/yaya + +-- This mimics the GHC2021 extension +-- (https://ghc.gitlab.haskell.org/ghc/doc/users_guide/exts/control.html?highlight=doandifthenelse#extension-GHC2021), +-- but supporting compilers back to GHC 7.10. If the oldest supported compiler +-- is GHC 9.2, then this stanza can be removed and `import: GHC2021` can be +-- replaced by `default-language: GHC2021`. +common GHC2021 + default-language: Haskell2010 + default-extensions: + BangPatterns + BinaryLiterals + ConstraintKinds + DeriveDataTypeable + DeriveGeneric + -- DeriveLift -- uncomment if the oldest supported version is GHC 8.10.1+ + DeriveTraversable + DerivingStrategies + DoAndIfThenElse + EmptyCase + ExistentialQuantification + FlexibleContexts + FlexibleInstances + GADTSyntax + GeneralizedNewtypeDeriving + HexFloatLiterals + -- ImportQualifiedPost -- uncomment if the oldest supported version is GHC 8.10.1+ + InstanceSigs + LambdaCase + MagicHash + MonadComprehensions + MonomorphismRestriction + MultiParamTypeClasses + NamedFieldPuns + NamedWildCards + NumericUnderscores + PolyKinds + PostfixOperators + RankNTypes + ScopedTypeVariables + StandaloneDeriving + -- StandaloneKindSignatures -- uncomment if the oldest supported version is GHC 8.10.1+ + TupleSections + TypeApplications + TypeOperators + UnicodeSyntax + NoExplicitNamespaces + +common defaults + import: GHC2021 + build-depends: + base ^>= {4.12.0, 4.13.0, 4.14.0, 4.15.0, 4.16.0, 4.17.0, 4.18.0, 4.19.0}, + ghc-options: + -Wall + -Wtrustworthy-safe + -fpackage-trust + if impl(ghc >= 8.10.1) + ghc-options: + -Wmissing-safe-haskell-mode + default-extensions: + DefaultSignatures + ExplicitNamespaces + FunctionalDependencies + LiberalTypeSynonyms + -- replace with `LexicalNegation` if the oldest supported version is GHC 9.0.1+ + NegativeLiterals + PackageImports + ParallelListComp + -- QualifiedDo - uncomment if the oldest supported version is GHC 9.0.1+ + RecursiveDo + -- RequiredTypeArguments - uncomment if the oldest supported version is GHC 9.10.1+ + StrictData + TemplateHaskellQuotes + TransformListComp + NoGeneralizedNewtypeDeriving + NoImplicitPrelude + NoMonomorphismRestriction + NoPatternGuards + NoTypeApplications + +test-suite yaya-test + import: defaults + type: exitcode-stdio-1.0 + hs-source-dirs: + test + main-is: test.hs + other-modules: + Test.Fold + Test.Fold.Common + Test.Fold.Native + Test.Retrofit + build-depends: + deriving-compat, + hedgehog, + yaya >= 0.5.0, + yaya-hedgehog >= 0.2.0, + ghc-options: + -rtsopts + -threaded + -trust adjunctions + -trust array + -trust base + -trust base-orphans + -trust binary + -trust bytestring + -trust containers + -trust distributive + -trust exceptions + -trust ghc-prim + -trust profunctors + -trust semigroupoids + -trust stm + -trust text + -trust transformers-compat + -with-rtsopts=-N + if impl(ghc < 9.6) + ghc-options: + -trust foldable1-classes-compat diff --git a/core/Setup.hs b/core/Setup.hs new file mode 100644 index 0000000..6cea120 --- /dev/null +++ b/core/Setup.hs @@ -0,0 +1,14 @@ +-- __NB__: `custom-setup` doesn’t have any way to specify extensions, so any we +-- want need to be specified here. +{-# LANGUAGE PackageImports #-} +{-# LANGUAGE Unsafe #-} +{-# LANGUAGE NoImplicitPrelude #-} +{-# OPTIONS_GHC -Wall #-} + +module Main (main) where + +import safe "base" System.IO (IO) +import "cabal-doctest" Distribution.Extra.Doctest (defaultMainWithDoctests) + +main :: IO () +main = defaultMainWithDoctests "doctests" diff --git a/core/src/Yaya/Applied.hs b/core/src/Yaya/Applied.hs index 81185d0..b893b17 100644 --- a/core/src/Yaya/Applied.hs +++ b/core/src/Yaya/Applied.hs @@ -1,25 +1,41 @@ +{-# LANGUAGE CPP #-} + +-- __NB__: base-4.17 moves `IsList` to its own module, which avoids the unsafety +-- of importing "GHC.Exts". With prior versions of base, we at least +-- mark the module @Trustworthy@. +#if MIN_VERSION_base(4, 17, 0) +{-# LANGUAGE Safe #-} +#else +{-# LANGUAGE Trustworthy #-} +#endif {-# LANGUAGE TypeApplications #-} {-# LANGUAGE TypeFamilies #-} {-# LANGUAGE ViewPatterns #-} +{-# OPTIONS_GHC -Wno-orphans #-} module Yaya.Applied where -import "base" Control.Applicative (Applicative) -import "base" Control.Category (Category (..)) -import "base" Data.Foldable (Foldable (foldr)) -import "base" Data.Function (flip) -import "base" Data.Functor (Functor (..)) -import "base" Data.Functor.Identity (Identity (..)) -import "base" Data.Int (Int) -import "base" Data.Monoid (Monoid (mempty)) -import "base" Data.Ord (Ord (..)) -import "base" Data.Semigroup (Semigroup ((<>))) -import "base" Data.Traversable (Traversable) +import safe "base" Control.Category (Category (..)) +import safe "base" Data.Foldable (Foldable (foldr)) +import safe "base" Data.Function (flip) +import safe "base" Data.Functor (Functor (..)) +import safe "base" Data.Functor.Identity (Identity (..)) +import safe "base" Data.Int (Int) +import safe "base" Data.Monoid (Monoid (mempty)) +import safe "base" Data.Ord (Ord (..)) +import safe "base" Data.Semigroup (Semigroup ((<>))) + +-- See comment on @{-# LANGUAGE Safe #-}@ above. +#if MIN_VERSION_base(4, 17, 0) +import "base" GHC.IsList (IsList) +import qualified "base" GHC.IsList as IsList +#else import "base" GHC.Exts (IsList) import qualified "base" GHC.Exts as IsList -import "base" Numeric.Natural (Natural) -import "free" Control.Monad.Trans.Free (FreeF (..)) -import "this" Yaya.Fold +#endif +import safe "base" Numeric.Natural (Natural) +import safe "free" Control.Monad.Trans.Free (FreeF (..)) +import safe "this" Yaya.Fold ( Algebra, Corecursive (..), Mu, @@ -29,7 +45,7 @@ import "this" Yaya.Fold Steppable (..), cata2, ) -import "this" Yaya.Fold.Common +import safe "this" Yaya.Fold.Common ( diagonal, fromEither, lucasSequence', @@ -43,15 +59,15 @@ import "this" Yaya.Fold.Common truncate', unarySequence, ) -import "this" Yaya.Fold.Native (Fix) -import "this" Yaya.Pattern +import safe "this" Yaya.Fold.Native (Fix) +import safe "this" Yaya.Pattern ( Either (..), Maybe (..), Pair, XNor (Both, Neither), maybe, ) -import "base" Prelude (Integral, fromIntegral) +import safe "base" Prelude (Integral, fromIntegral) now :: (Steppable (->) t (Either a)) => a -> t now = embed . Left diff --git a/core/src/Yaya/Experimental/Foldable.hs b/core/src/Yaya/Experimental/Foldable.hs index 2d455b8..8029b61 100644 --- a/core/src/Yaya/Experimental/Foldable.hs +++ b/core/src/Yaya/Experimental/Foldable.hs @@ -1,3 +1,5 @@ +{-# LANGUAGE Safe #-} + -- | This shows how `Data.Foldable.Foldable` is basically `Recursive` -- specialized to lists. The true operation of `Data.Foldable.Foldable` is -- `Data.Foldable.toList`. @@ -9,7 +11,6 @@ module Yaya.Experimental.Foldable where import "base" Control.Category (Category (..)) import "base" Data.Function (flip) import "base" Data.Monoid (Monoid) -import "base" Data.String (String) import "free" Control.Monad.Trans.Free (Free, iter) import "this" Yaya.Fold (Recursive (..)) import "this" Yaya.Fold.Common (lowerMonoid) diff --git a/core/src/Yaya/Fold.hs b/core/src/Yaya/Fold.hs index 1912d16..432bc15 100644 --- a/core/src/Yaya/Fold.hs +++ b/core/src/Yaya/Fold.hs @@ -1,8 +1,9 @@ {-# LANGUAGE GADTs #-} +{-# LANGUAGE Safe #-} module Yaya.Fold where -import "base" Control.Applicative (Applicative (..), liftA2) +import "base" Control.Applicative (Applicative (..)) import "base" Control.Category (Category (..)) import "base" Control.Monad (Monad, join, (<=<), (=<<)) import "base" Data.Bifunctor (Bifunctor (..)) @@ -206,8 +207,8 @@ zipAlgebraMs f g = bisequence . bimap (f . fmap fst) (g . fmap snd) . diagonal lowerDay :: (Projectable (->) t g) => Algebra (->) (Day f g) a -> Algebra (->) f (t -> a) lowerDay φ fta t = φ (Day fta (project t) ($)) --- | By analogy with `liftA2` (which also relies on `Day`, at least --- conceptually). +-- | By analogy with `Control.Applicative.liftA2` (which also relies on `Day`, +-- at least conceptually). cata2 :: (Recursive (->) t f, Projectable (->) u g) => Algebra (->) (Day f g) a -> t -> u -> a cata2 = cata . lowerDay diff --git a/core/src/Yaya/Fold/Common.hs b/core/src/Yaya/Fold/Common.hs index a9fff74..bf0dc0f 100644 --- a/core/src/Yaya/Fold/Common.hs +++ b/core/src/Yaya/Fold/Common.hs @@ -1,3 +1,5 @@ +{-# LANGUAGE Safe #-} + -- | Common algebras that are useful when folding. module Yaya.Fold.Common where @@ -27,7 +29,7 @@ import "this" Yaya.Pattern either, maybe, ) -import Prelude (Integer, Integral, Num (..)) +import Prelude (Integer, Num (..)) -- | Converts the free monoid (a list) into some other `Monoid`. lowerMonoid :: (Monoid m) => (a -> m) -> XNor a m -> m diff --git a/core/src/Yaya/Fold/Native.hs b/core/src/Yaya/Fold/Native.hs index ce5b195..41fa592 100644 --- a/core/src/Yaya/Fold/Native.hs +++ b/core/src/Yaya/Fold/Native.hs @@ -1,3 +1,4 @@ +{-# LANGUAGE Safe #-} {-# OPTIONS_GHC -Wno-orphans #-} -- | Uses of recursion schemes that use Haskell’s built-in recursion in a total @@ -9,18 +10,14 @@ module Yaya.Fold.Native ) where -import "base" Control.Applicative (Applicative) import "base" Control.Category (Category (..)) import "base" Data.Bifunctor (Bifunctor (..)) -import "base" Data.Bool (Bool) import "base" Data.Eq (Eq ((==))) import "base" Data.Foldable (Foldable) import "base" Data.Function (($)) import "base" Data.Functor (Functor (..)) import "base" Data.Functor.Classes (Eq1, Show1) import "base" Data.List.NonEmpty -import "base" Data.Monoid (Monoid) -import "base" Data.Ord (Ord) import "base" Numeric.Natural import "base" Text.Show (Show (showsPrec)) import "comonad" Control.Comonad (Comonad (..)) @@ -40,7 +37,6 @@ import "this" Yaya.Fold import "this" Yaya.Fold.Common (diagonal) import "this" Yaya.Fold.Native.Internal (Cofix (unCofix)) import "this" Yaya.Pattern (AndMaybe (..), Maybe, XNor (..), uncurry) -import "base" Prelude (Integral) -- | A fixed-point constructor that uses Haskell's built-in recursion. This is -- strict/recursive. diff --git a/core/src/Yaya/Fold/Native/Internal.hs b/core/src/Yaya/Fold/Native/Internal.hs index e0e5ec5..2db36fa 100644 --- a/core/src/Yaya/Fold/Native/Internal.hs +++ b/core/src/Yaya/Fold/Native/Internal.hs @@ -1,7 +1,9 @@ +{-# LANGUAGE Safe #-} -- NB: We disable @StrictData@ here in order for `Cofix` to be lazy. I don’t -- think there is any way to explicitly add @~@ patterns that has the -- correct semantics. {-# LANGUAGE NoStrictData #-} +{-# OPTIONS_GHC -Wno-unrecognised-pragmas #-} -- | This module only exists to restrict the scope of @NoStrictData@. Everything -- is re-exported via "Yaya.Fold". @@ -18,7 +20,8 @@ import "this" Yaya.Fold -- | A fixed-point constructor that uses Haskell's built-in recursion. This is -- lazy/corecursive. data Cofix f = Cofix {unCofix :: f (Cofix f)} -{-# ANN Cofix "HLint: ignore Use newtype instead of data" #-} + +{-# HLINT ignore Cofix "Use newtype instead of data" #-} instance Projectable (->) (Cofix f) f where project = unCofix diff --git a/core/src/Yaya/Functor.hs b/core/src/Yaya/Functor.hs index 24bbbe4..5f5da22 100644 --- a/core/src/Yaya/Functor.hs +++ b/core/src/Yaya/Functor.hs @@ -1,3 +1,5 @@ +{-# LANGUAGE Safe #-} + -- | This should probably be a separate library, but it provides a number of -- functor type classes between various categories. module Yaya.Functor where diff --git a/core/src/Yaya/Pattern.hs b/core/src/Yaya/Pattern.hs index 82c4090..b48f426 100644 --- a/core/src/Yaya/Pattern.hs +++ b/core/src/Yaya/Pattern.hs @@ -1,3 +1,4 @@ +{-# LANGUAGE Safe #-} {-# OPTIONS_GHC -Wno-orphans #-} -- | Common pattern functors (and instances for them). diff --git a/core/src/Yaya/Retrofit.hs b/core/src/Yaya/Retrofit.hs index e0a7d53..7c62ebb 100644 --- a/core/src/Yaya/Retrofit.hs +++ b/core/src/Yaya/Retrofit.hs @@ -1,5 +1,10 @@ {-# LANGUAGE CPP #-} +#if MIN_VERSION_GLASGOW_HASKELL(9, 0, 0, 0) +{-# LANGUAGE Safe #-} +#else {-# LANGUAGE TemplateHaskell #-} +{-# LANGUAGE Trustworthy #-} +#endif -- | This module re-exports a subset of `Yaya.Fold`, intended for when you want -- to define recursion scheme instances for your existing recursive types. @@ -34,31 +39,34 @@ where -- `Maybe`, etc. is tied to emplate-haskell and does not involve recursion -- schemes. -import "base" Control.Applicative (Applicative (..)) -import "base" Control.Category (Category (..)) -import "base" Control.Exception (Exception (..), throw) -import "base" Control.Monad ((<=<)) -import "base" Data.Bifunctor (Bifunctor (..)) -import "base" Data.Bool (Bool (..), not, otherwise, (&&)) -import "base" Data.Either (Either (..), either) -import "base" Data.Eq (Eq (..)) -import "base" Data.Foldable (Foldable (..)) -import "base" Data.Function (const, flip, ($)) -import "base" Data.Functor (Functor (..), (<$>)) -import "base" Data.Functor.Identity (Identity (..)) -import "base" Data.List (all, null, zip, zip3) -import "base" Data.List.NonEmpty (NonEmpty) -import "base" Data.Maybe (Maybe (..), maybe) -import "base" Data.Semigroup (Semigroup (..)) -import "base" Data.String (String) -import "base" Data.Traversable (Traversable (..)) -import "base" Text.Read.Lex (isSymbolChar) -import "base" Text.Show (Show (..)) -import "either" Data.Either.Validation (Validation (..), validationToEither) -import "template-haskell" Language.Haskell.TH as TH -import "template-haskell" Language.Haskell.TH.Syntax (mkNameG_tc) -import "th-abstraction" Language.Haskell.TH.Datatype as TH.Abs -import "this" Yaya.Fold +import safe "base" Control.Applicative (Applicative (..)) +import safe "base" Control.Category (Category (..)) +import safe "base" Control.Monad ((<=<)) +import safe "base" Control.Monad.Fail (MonadFail (fail)) +import safe "base" Data.Bifunctor (Bifunctor (..)) +import safe "base" Data.Bool (Bool (..), otherwise, (&&)) +import safe "base" Data.Either (Either (..), either) +import safe "base" Data.Eq (Eq (..)) +import safe "base" Data.Foldable (Foldable (..)) +import safe "base" Data.Function (const, flip, ($)) +import safe "base" Data.Functor (Functor (..), (<$>)) +import safe "base" Data.Functor.Identity (Identity (..)) +import safe "base" Data.List (all, zip, zip3) +import safe "base" Data.List.NonEmpty (NonEmpty) +import safe "base" Data.Maybe (Maybe (..), maybe) +import safe "base" Data.Semigroup (Semigroup (..)) +import safe "base" Data.String (String) +import safe "base" Data.Traversable (Traversable (..)) +import safe "base" Text.Read.Lex (isSymbolChar) +import safe "base" Text.Show (Show (..)) +import safe "either" Data.Either.Validation + ( Validation (..), + validationToEither, + ) +import safe "template-haskell" Language.Haskell.TH as TH +import safe "template-haskell" Language.Haskell.TH.Syntax (mkNameG_tc) +import safe qualified "th-abstraction" Language.Haskell.TH.Datatype as TH.Abs +import safe "this" Yaya.Fold ( Corecursive (..), Projectable (..), Recursive (..), @@ -66,14 +74,13 @@ import "this" Yaya.Fold recursiveEq, recursiveShowsPrec, ) -import "base" Prelude (error) #if MIN_VERSION_template_haskell(2, 21, 0) -type TyVarBndr' = TyVarBndr BndrVis #elif MIN_VERSION_template_haskell(2, 17, 0) -type TyVarBndr' = TyVarBndr () +type TyVarBndrVis = TyVarBndr () #else -type TyVarBndr' = TyVarBndr +type TyVarBndrUnit = TyVarBndr +type TyVarBndrVis = TyVarBndr #endif conP' :: Name -> [Pat] -> Pat @@ -133,7 +140,8 @@ conP' = ConP -- In future, we should check the strictness of the recursive parameter and generate only the appropriate one (unless overridden by a rule). extractPatternFunctor :: PatternFunctorRules -> Name -> Q [Dec] extractPatternFunctor rules = - either throw id . makePrimForDI rules <=< reifyDatatype + either (fail . displayUnsupportedDatatype) id . makePrimForDI rules + <=< TH.Abs.reifyDatatype -- | Rules of renaming data names data PatternFunctorRules = PatternFunctorRules @@ -163,50 +171,53 @@ toFName = mkName . f . nameBase data UnsupportedDatatype = UnsupportedInstTypes (NonEmpty Type) - | UnsupportedVariant DatatypeVariant - -instance Show UnsupportedDatatype where - show = \case + | UnsupportedVariant TH.Abs.DatatypeVariant + | UnsupportedGADT [TyVarBndrUnit] Cxt + | NonBinaryInfixConstructor [(Bang, Type)] + deriving (Show) + +displayUnsupportedDatatype :: UnsupportedDatatype -> String +displayUnsupportedDatatype = + ("extractPatternFunctor: " <>) . \case UnsupportedInstTypes tys -> - "extractPatternFunctor: Couldn't process the following types " <> show tys - UnsupportedVariant _variant -> - "extractPatternFunctor: Data families are currently not supported." - -instance Exception UnsupportedDatatype + "Couldn't process the following types " <> show tys + UnsupportedVariant _variant -> "Data families are currently not supported." + UnsupportedGADT _vars _context -> "GADTs are not currently supported." + NonBinaryInfixConstructor bts -> + "internal error: wrong number of BangTypes for InfixConstructor; expected 2, but got " + <> show (length bts) makePrimForDI :: - PatternFunctorRules -> DatatypeInfo -> Either UnsupportedDatatype (Q [Dec]) + PatternFunctorRules -> + TH.Abs.DatatypeInfo -> + Either UnsupportedDatatype (Q [Dec]) makePrimForDI rules - ( DatatypeInfo - { datatypeName = tyName, - datatypeInstTypes = instTys, - datatypeCons = cons, - datatypeVariant = variant + ( TH.Abs.DatatypeInfo + { TH.Abs.datatypeName = tyName, + TH.Abs.datatypeInstTypes = instTys, + TH.Abs.datatypeCons = cons, + TH.Abs.datatypeVariant = variant } ) = - if isDataFamInstance - then Left $ UnsupportedVariant variant - else - bimap - UnsupportedInstTypes - (flip (makePrimForDI' rules (variant == Newtype) tyName) cons) - . validationToEither - $ traverse (\ty -> maybe (Failure $ pure ty) Success $ toTyVarBndr ty) instTys + maybe + (Left $ UnsupportedVariant variant) + ( \safeVariant -> + bimap + UnsupportedInstTypes + (flip (makePrimForDI' rules safeVariant tyName) cons) + . validationToEither + $ traverse + (\ty -> maybe (Failure $ pure ty) Success $ toTyVarBndr ty) + instTys + ) + $ excludeDataFamInstance variant where - isDataFamInstance = case variant of - DataInstance -> True - NewtypeInstance -> True - Datatype -> False - Newtype -> False - - toTyVarBndr :: Type -> Maybe TyVarBndr' + toTyVarBndr :: Type -> Maybe TyVarBndrVis toTyVarBndr (VarT n) = pure $ plainTV n toTyVarBndr (SigT (VarT n) k) = pure $ kindedTV n k toTyVarBndr _ = Nothing --- TH 2.12.O means GHC 8.2.1, otherwise, we work back to GHC 8.0.1 -#if MIN_VERSION_template_haskell(2, 12, 0) deriveds :: [DerivClause] deriveds = pure $ @@ -216,18 +227,54 @@ deriveds = ConT foldableTypeName, ConT traversableTypeName ] + +-- | A restricted version of `TH.Abs.DatatypeVariant` that excludes data family +-- declarations. +#if MIN_VERSION_th_abstraction(0, 5, 0) +data SafeDatatypeVariant = Datatype | Newtype | TypeDataV #else -deriveds :: [TH.Type] -deriveds = - [ ConT functorTypeName, - ConT foldableTypeName, - ConT traversableTypeName - ] +data SafeDatatypeVariant = Datatype | Newtype +#endif + +excludeDataFamInstance :: TH.Abs.DatatypeVariant -> Maybe SafeDatatypeVariant +#if MIN_VERSION_th_abstraction(0, 5, 0) +excludeDataFamInstance = \case + TH.Abs.DataInstance -> Nothing + TH.Abs.NewtypeInstance -> Nothing + TH.Abs.Datatype -> Just Datatype + TH.Abs.Newtype -> Just Newtype + TH.Abs.TypeData -> Just TypeDataV +#else +excludeDataFamInstance = \case + TH.Abs.DataInstance -> Nothing + TH.Abs.NewtypeInstance -> Nothing + TH.Abs.Datatype -> Just Datatype + TH.Abs.Newtype -> Just Newtype +#endif + +makeDataDefinition :: + SafeDatatypeVariant -> Name -> [TyVarBndrVis] -> [Con] -> Dec +#if MIN_VERSION_template_haskell(2, 20, 0) && MIN_VERSION_th_abstraction(0, 5, 0) +makeDataDefinition safeVariant tyName vars cons = + case (safeVariant, cons) of + (Newtype, [con]) -> NewtypeD [] tyName vars Nothing con deriveds + (TypeDataV, _) -> TypeDataD tyName vars Nothing cons + (_, _) -> DataD [] tyName vars Nothing cons deriveds +#else +makeDataDefinition safeVariant tyName vars cons = + case (safeVariant, cons) of + (Newtype, [con]) -> NewtypeD [] tyName vars Nothing con deriveds + (_, _) -> DataD [] tyName vars Nothing cons deriveds #endif makePrimForDI' :: - PatternFunctorRules -> Bool -> Name -> [TyVarBndr'] -> [ConstructorInfo] -> Q [Dec] -makePrimForDI' rules isNewtype tyName vars cons = do + PatternFunctorRules -> + SafeDatatypeVariant -> + Name -> + [TyVarBndrVis] -> + [TH.Abs.ConstructorInfo] -> + Q [Dec] +makePrimForDI' rules safeVariant tyName vars cons = do -- variable parameters let vars' = fmap VarT (typeVars vars) -- Name of base functor @@ -241,23 +288,20 @@ makePrimForDI' rules isNewtype tyName vars cons = do -- Vars let varsF = vars <> [plainTV rName] - -- #33 - cons' <- traverse (conTypeTraversal resolveTypeSynonyms) cons - let consF = - toCon - . conNameMap (patternCon rules) - . conFieldNameMap (patternField rules) - . conTypeMap (substType s r) - <$> cons' - - -- Data definition - let dataDec = case consF of - [conF] - | isNewtype -> NewtypeD [] tyNameF varsF Nothing conF deriveds - _ -> DataD [] tyNameF varsF Nothing consF deriveds - - recursiveDec <- - [d| + -- ekmett/recursion-schemes#33 + cons' <- traverse (conTypeTraversal TH.Abs.resolveTypeSynonyms) cons + consF <- + either (fail . displayUnsupportedDatatype) pure $ + traverse + ( toCon + . conNameMap (patternCon rules) + . conFieldNameMap (patternField rules) + . conTypeMap (substType s r) + ) + cons' + + (makeDataDefinition safeVariant tyNameF varsF consF :) + <$> [d| instance Projectable (->) $(pure s) $(pure $ conAppsT tyNameF vars') where project = $(LamCaseE <$> mkMorphism id (patternCon rules) cons') @@ -270,20 +314,18 @@ makePrimForDI' rules isNewtype tyName vars cons = do instance Corecursive (->) $(pure s) $(pure $ conAppsT tyNameF vars') where ana ψ = embed . fmap (ana ψ) . ψ |] - -- Combine - pure ([dataDec] <> recursiveDec) -- | makes clauses to rename constructors mkMorphism :: (Name -> Name) -> (Name -> Name) -> - [ConstructorInfo] -> + [TH.Abs.ConstructorInfo] -> Q [Match] mkMorphism nFrom nTo = traverse ( \ci -> do - let n = constructorName ci - fs <- traverse (const $ newName "x") $ constructorFields ci + let n = TH.Abs.constructorName ci + fs <- traverse (const $ newName "x") $ TH.Abs.constructorFields ci pure $ Match (conP' (nFrom n) (fmap VarP fs)) -- pattern @@ -295,31 +337,33 @@ mkMorphism nFrom nTo = -- Traversals ------------------------------------------------------------------------------- -conNameTraversal :: Traversal' ConstructorInfo Name -conNameTraversal = lens constructorName (\s v -> s {constructorName = v}) +conNameTraversal :: Traversal' TH.Abs.ConstructorInfo Name +conNameTraversal = lens TH.Abs.constructorName (\s v -> s {TH.Abs.constructorName = v}) -conFieldNameTraversal :: Traversal' ConstructorInfo Name +conFieldNameTraversal :: Traversal' TH.Abs.ConstructorInfo Name conFieldNameTraversal = - lens constructorVariant (\s v -> s {constructorVariant = v}) + lens TH.Abs.constructorVariant (\s v -> s {TH.Abs.constructorVariant = v}) . conVariantTraversal where - conVariantTraversal :: Traversal' ConstructorVariant Name - conVariantTraversal _ NormalConstructor = pure NormalConstructor - conVariantTraversal _ InfixConstructor = pure InfixConstructor - conVariantTraversal f (RecordConstructor fs) = RecordConstructor <$> traverse f fs - -conTypeTraversal :: Traversal' ConstructorInfo Type + conVariantTraversal :: Traversal' TH.Abs.ConstructorVariant Name + conVariantTraversal _ TH.Abs.NormalConstructor = + pure TH.Abs.NormalConstructor + conVariantTraversal _ TH.Abs.InfixConstructor = pure TH.Abs.InfixConstructor + conVariantTraversal f (TH.Abs.RecordConstructor fs) = + TH.Abs.RecordConstructor <$> traverse f fs + +conTypeTraversal :: Traversal' TH.Abs.ConstructorInfo Type conTypeTraversal = - lens constructorFields (\s v -> s {constructorFields = v}) + lens TH.Abs.constructorFields (\s v -> s {TH.Abs.constructorFields = v}) . traverse -conNameMap :: (Name -> Name) -> ConstructorInfo -> ConstructorInfo +conNameMap :: (Name -> Name) -> TH.Abs.ConstructorInfo -> TH.Abs.ConstructorInfo conNameMap = over conNameTraversal -conFieldNameMap :: (Name -> Name) -> ConstructorInfo -> ConstructorInfo +conFieldNameMap :: (Name -> Name) -> TH.Abs.ConstructorInfo -> TH.Abs.ConstructorInfo conFieldNameMap = over conFieldNameTraversal -conTypeMap :: (Type -> Type) -> ConstructorInfo -> ConstructorInfo +conTypeMap :: (Type -> Type) -> TH.Abs.ConstructorInfo -> TH.Abs.ConstructorInfo conTypeMap = over conTypeTraversal ------------------------------------------------------------------------------- @@ -343,8 +387,8 @@ over l f = runIdentity . l (Identity . f) ------------------------------------------------------------------------------- -- | Extract type variables -typeVars :: [TyVarBndr'] -> [Name] -typeVars = fmap tvName +typeVars :: [TyVarBndrVis] -> [Name] +typeVars = fmap TH.Abs.tvName -- | Apply arguments to a type constructor. conAppsT :: Name -> [Type] -> Type @@ -370,42 +414,42 @@ substType a b = go -- Rest are unchanged go x = x -toCon :: ConstructorInfo -> Con +toCon :: TH.Abs.ConstructorInfo -> Either UnsupportedDatatype Con toCon - ( ConstructorInfo - { constructorName = name, - constructorVars = vars, - constructorContext = ctxt, - constructorFields = ftys, - constructorStrictness = fstricts, - constructorVariant = variant + ( TH.Abs.ConstructorInfo + { TH.Abs.constructorName = name, + TH.Abs.constructorVars = vars, + TH.Abs.constructorContext = ctxt, + TH.Abs.constructorFields = ftys, + TH.Abs.constructorStrictness = fstricts, + TH.Abs.constructorVariant = variant } - ) - | not (null vars && null ctxt) = - error "makeBaseFunctor: GADTs are not currently supported." - | otherwise = + ) = + if null vars && null ctxt + then let bangs = fmap toBang fstricts in case variant of - NormalConstructor -> NormalC name $ zip bangs ftys - RecordConstructor fnames -> RecC name $ zip3 fnames bangs ftys - InfixConstructor -> - let [bang1, bang2] = bangs - [fty1, fty2] = ftys - in InfixC (bang1, fty1) name (bang2, fty2) + TH.Abs.NormalConstructor -> pure . NormalC name $ zip bangs ftys + TH.Abs.RecordConstructor fnames -> + pure . RecC name $ zip3 fnames bangs ftys + TH.Abs.InfixConstructor -> case zip bangs ftys of + [bt1, bt2] -> pure $ InfixC bt1 name bt2 + bts -> Left $ NonBinaryInfixConstructor bts + else Left $ UnsupportedGADT vars ctxt where - toBang (FieldStrictness upkd strct) = + toBang (TH.Abs.FieldStrictness upkd strct) = Bang (toSourceUnpackedness upkd) (toSourceStrictness strct) where - toSourceUnpackedness :: Unpackedness -> SourceUnpackedness - toSourceUnpackedness UnspecifiedUnpackedness = NoSourceUnpackedness - toSourceUnpackedness NoUnpack = SourceNoUnpack - toSourceUnpackedness Unpack = SourceUnpack - - toSourceStrictness :: Strictness -> SourceStrictness - toSourceStrictness UnspecifiedStrictness = NoSourceStrictness - toSourceStrictness Lazy = SourceLazy + toSourceUnpackedness :: TH.Abs.Unpackedness -> SourceUnpackedness + toSourceUnpackedness TH.Abs.UnspecifiedUnpackedness = NoSourceUnpackedness + toSourceUnpackedness TH.Abs.NoUnpack = SourceNoUnpack + toSourceUnpackedness TH.Abs.Unpack = SourceUnpack + + toSourceStrictness :: TH.Abs.Strictness -> SourceStrictness + toSourceStrictness TH.Abs.UnspecifiedStrictness = NoSourceStrictness + toSourceStrictness TH.Abs.Lazy = SourceLazy toSourceStrictness TH.Abs.Strict = SourceStrict ------------------------------------------------------------------------------- diff --git a/core/src/Yaya/Zoo.hs b/core/src/Yaya/Zoo.hs index 1438b21..cbe24a0 100644 --- a/core/src/Yaya/Zoo.hs +++ b/core/src/Yaya/Zoo.hs @@ -1,3 +1,5 @@ +{-# LANGUAGE Safe #-} + -- | Contains all the commonly-named folds that aren’t core to the library. In -- general, this can be seen as a mapping from names you may have heard or -- read in a paper to how Yaya expects you to achieve the same end. Of course, diff --git a/core/tests/doctests.hs b/core/tests/doctests.hs new file mode 100644 index 0000000..76c6b7d --- /dev/null +++ b/core/tests/doctests.hs @@ -0,0 +1,10 @@ +module Main (main) where + +import safe "base" Data.Function (($)) +import safe "base" Data.Semigroup (Semigroup ((<>))) +import safe "base" System.IO (IO) +import "doctest" Test.DocTest (doctest) +import "this" Build_doctests (flags, module_sources, pkgs) + +main :: IO () +main = doctest $ flags <> pkgs <> module_sources diff --git a/core/yaya.cabal b/core/yaya.cabal index 4cffacf..bb36301 100644 --- a/core/yaya.cabal +++ b/core/yaya.cabal @@ -1,72 +1,190 @@ -name: yaya -version: 0.5.1.0 -synopsis: Total recursion schemes. -description: Recursion schemes allow you to separate recursion from your - business logic – making your own operations simpler, more - modular, and less error-prone. This library also provides - tools for combining your operations in ways that reduce the - number of passes over your data and is designed to - encourage total (i.e., successfully terminating) functions. -homepage: https://github.com/sellout/yaya#readme -author: Greg Pfeil -maintainer: greg@technomadic.org -copyright: 2017 Greg Pfeil -license: AGPL-3 -license-file: LICENSE -category: Recursion -build-type: Simple -extra-source-files: CHANGELOG.md - , README.md -cabal-version: >=1.10 -tested-with: GHC == 8.6.1 - , GHC == 8.8.1, GHC == 8.8.4 - , GHC == 8.10.1 - , GHC == 9.0.1 - , GHC == 9.2.1 - , GHC == 9.4.1, GHC == 9.4.8 - , GHC == 9.6.1 - , GHC == 9.8.1 +cabal-version: 3.0 -library - hs-source-dirs: src - exposed-modules: Yaya.Pattern - , Yaya.Fold - , Yaya.Fold.Common - , Yaya.Fold.Native - , Yaya.Functor - , Yaya.Retrofit - , Yaya.Applied - , Yaya.Zoo - , Yaya.Experimental.Foldable - other-modules: Yaya.Fold.Native.Internal - build-depends: base >= 4.7 && < 5 - , comonad - , either - , free - , kan-extensions - , lens - , profunctors - , strict - , template-haskell - , th-abstraction - , transformers - default-extensions: ConstraintKinds - , DeriveGeneric - , DeriveTraversable - , FlexibleContexts - , FlexibleInstances - , FunctionalDependencies - , LambdaCase - , MultiParamTypeClasses - , PackageImports - , PolyKinds - , RankNTypes - , ScopedTypeVariables - , StrictData - , TypeOperators - , NoImplicitPrelude - default-language: Haskell2010 +name: yaya +version: 0.5.2.0 +synopsis: Total recursion schemes. +description: Recursion schemes allow you to separate recursion from your + business logic – making your own operations simpler, more modular, + and less error-prone. This library also provides tools for + combining your operations in ways that reduce the number of passes + over your data and is designed to encourage total (i.e., + successfully terminating) functions. +author: Greg Pfeil +maintainer: Greg Pfeil +copyright: 2017 Greg Pfeil +homepage: https://github.com/sellout/yaya#readme +bug-reports: https://github.com/sellout/yaya/issues +category: Recursion +build-type: Custom +license: AGPL-3.0-or-later +license-files: + LICENSE +extra-source-files: + CHANGELOG.md + README.md +tested-with: + GHC == { +-- GHCup Nixpkgs + 8.6.1, + 8.8.1, 8.8.4, + 8.10.1, + 9.0.1, + 9.2.1, + 9.4.1, 9.4.8, + 9.6.1, + 9.8.1 + } source-repository head - type: git + type: git location: https://github.com/sellout/yaya + +-- This mimics the GHC2021 extension +-- (https://ghc.gitlab.haskell.org/ghc/doc/users_guide/exts/control.html?highlight=doandifthenelse#extension-GHC2021), +-- but supporting compilers back to GHC 7.10. If the oldest supported compiler +-- is GHC 9.2, then this stanza can be removed and `import: GHC2021` can be +-- replaced by `default-language: GHC2021`. +common GHC2021 + default-language: Haskell2010 + default-extensions: + BangPatterns + BinaryLiterals + ConstraintKinds + DeriveDataTypeable + DeriveGeneric + -- DeriveLift -- uncomment if the oldest supported version is GHC 8.10.1+ + DeriveTraversable + DerivingStrategies + DoAndIfThenElse + EmptyCase + ExistentialQuantification + FlexibleContexts + FlexibleInstances + GADTSyntax + GeneralizedNewtypeDeriving + HexFloatLiterals + -- ImportQualifiedPost -- uncomment if the oldest supported version is GHC 8.10.1+ + InstanceSigs + LambdaCase + MagicHash + MonadComprehensions + MonomorphismRestriction + MultiParamTypeClasses + NamedFieldPuns + NamedWildCards + NumericUnderscores + PolyKinds + PostfixOperators + RankNTypes + ScopedTypeVariables + StandaloneDeriving + -- StandaloneKindSignatures -- uncomment if the oldest supported version is GHC 8.10.1+ + TupleSections + TypeApplications + TypeOperators + UnicodeSyntax + NoExplicitNamespaces + +common defaults + import: GHC2021 + build-depends: + base ^>= {4.12.0, 4.13.0, 4.14.0, 4.15.0, 4.16.0, 4.17.0, 4.18.0, 4.19.0}, + ghc-options: + -Wall + -Wtrustworthy-safe + -fpackage-trust + if impl(ghc >= 8.10.1) + ghc-options: + -Wmissing-safe-haskell-mode + default-extensions: + DefaultSignatures + ExplicitNamespaces + FunctionalDependencies + LiberalTypeSynonyms + -- replace with `LexicalNegation` if the oldest supported version is GHC 9.0.1+ + NegativeLiterals + PackageImports + ParallelListComp + -- QualifiedDo - uncomment if the oldest supported version is GHC 9.0.1+ + RecursiveDo + -- RequiredTypeArguments - uncomment if the oldest supported version is GHC 9.10.1+ + StrictData + TemplateHaskellQuotes + TransformListComp + NoGeneralizedNewtypeDeriving + NoImplicitPrelude + NoMonomorphismRestriction + NoPatternGuards + NoTypeApplications + +custom-setup + setup-depends: + -- TODO: Remove `Cabal` dep once haskell/cabal#3751 is fixed. + Cabal ^>= {3.0.0, 3.2.0, 3.4.0, 3.6.0, 3.8.0, 3.10.0}, + base ^>= {4.12.0, 4.13.0, 4.14.0, 4.15.0, 4.16.0, 4.17.0, 4.18.0, 4.19.0}, + cabal-doctest ^>= 1.0.0 + +library + import: defaults + hs-source-dirs: src + exposed-modules: + Yaya.Applied + Yaya.Experimental.Foldable + Yaya.Fold + Yaya.Fold.Common + Yaya.Fold.Native + Yaya.Functor + Yaya.Pattern + Yaya.Retrofit + Yaya.Zoo + other-modules: + Yaya.Fold.Native.Internal + build-depends: + comonad, + either, + free, + kan-extensions, + lens, + profunctors, + strict, + template-haskell, + th-abstraction, + transformers, + ghc-options: + -trust adjunctions + -trust array + -trust base + -trust base-orphans + -trust binary + -trust bytestring + -trust containers + -trust distributive + -trust exceptions + -trust ghc-prim + -trust lens + -trust profunctors + -trust semigroupoids + -trust stm + -trust template-haskell + -trust text + -trust transformers-compat + if impl(ghc < 9.6) + ghc-options: + -trust foldable1-classes-compat + +test-suite doctests + import: defaults + type: exitcode-stdio-1.0 + hs-source-dirs: tests + main-is: doctests.hs + build-depends: + doctest ^>= {0.15.0, 0.16.0, 0.17.0, 0.18.0, 0.19.0, 0.20.0, 0.21.0, 0.22.0}, + yaya, + ghc-options: + -trust base + default-extensions: + -- TODO: Other flags require each module to be compiled with a safety level. + -- Since it’s currently not possible to add `{-# LANGUAGE Safe -#}` to + -- the generated “Build_doctests.hs” and since doctests.hs is + -- `Unsafe`, this is the only safety level that can be used. + Unsafe diff --git a/flake.nix b/flake.nix index 197ba19..2c3867e 100644 --- a/flake.nix +++ b/flake.nix @@ -156,7 +156,9 @@ home.packages = [ (pkgs.haskellPackages.ghcWithPackages (hpkgs: [ hpkgs.${pname} + hpkgs."${pname}-containers" hpkgs."${pname}-hedgehog" + hpkgs."${pname}-quickcheck" hpkgs."${pname}-unsafe" ])) ]; @@ -225,7 +227,6 @@ "ghc945" "ghc946" "ghc947" - "ghc948" "ghc962" "ghc963" ]; @@ -244,7 +245,7 @@ {default = self.packages.${system}."${self.lib.defaultCompiler}_all";} // concat.lib.mkPackages pkgs - (self.lib.testedGhcVersions system) + (self.lib.supportedGhcVersions system) cabalPackages; projectConfigurations = @@ -254,7 +255,7 @@ {default = self.devShells.${system}.${self.lib.defaultCompiler};} // concat.lib.mkDevShells pkgs - (self.lib.testedGhcVersions system) + (self.lib.supportedGhcVersions system) cabalPackages (hpkgs: [self.projectConfigurations.${system}.packages.path] diff --git a/garnix.yaml b/garnix.yaml index dc132b8..c312328 100644 --- a/garnix.yaml +++ b/garnix.yaml @@ -1,2 +1,2 @@ # This file was generated by Project Manager. -{"builds":{"exclude":["*.x86_64-darwin","*.x86_64-darwin.*","homeConfigurations.x86_64-darwin-yaya-example","devShells.*.lax-checks"],"include":["*.*","*.*.*"]}} \ No newline at end of file +{"builds":{"exclude":["*.x86_64-darwin","*.x86_64-darwin.*","homeConfigurations.x86_64-darwin-yaya-example","devShells.*.lax-checks"],"include":["homeConfigurations.*","nixosConfigurations.*","checks.aarch64-darwin.*","packages.aarch64-darwin.default","devShells.aarch64-darwin.ghc948","packages.aarch64-darwin.ghc948_all","devShells.aarch64-darwin.ghc981","packages.aarch64-darwin.ghc981_all","checks.aarch64-linux.*","packages.aarch64-linux.default","devShells.aarch64-linux.ghc948","packages.aarch64-linux.ghc948_all","devShells.aarch64-linux.ghc981","packages.aarch64-linux.ghc981_all","devShells.aarch64-linux.ghc884","packages.aarch64-linux.ghc884_all","checks.i686-linux.*","packages.i686-linux.default","devShells.i686-linux.ghc948","packages.i686-linux.ghc948_all","devShells.i686-linux.ghc981","packages.i686-linux.ghc981_all","devShells.i686-linux.ghc884","packages.i686-linux.ghc884_all","checks.x86_64-linux.*","packages.x86_64-linux.default","devShells.x86_64-linux.ghc948","packages.x86_64-linux.ghc948_all","devShells.x86_64-linux.ghc981","packages.x86_64-linux.ghc981_all","devShells.x86_64-linux.ghc884","packages.x86_64-linux.ghc884_all"]}} \ No newline at end of file diff --git a/hedgehog/Setup.hs b/hedgehog/Setup.hs new file mode 100644 index 0000000..6cea120 --- /dev/null +++ b/hedgehog/Setup.hs @@ -0,0 +1,14 @@ +-- __NB__: `custom-setup` doesn’t have any way to specify extensions, so any we +-- want need to be specified here. +{-# LANGUAGE PackageImports #-} +{-# LANGUAGE Unsafe #-} +{-# LANGUAGE NoImplicitPrelude #-} +{-# OPTIONS_GHC -Wall #-} + +module Main (main) where + +import safe "base" System.IO (IO) +import "cabal-doctest" Distribution.Extra.Doctest (defaultMainWithDoctests) + +main :: IO () +main = defaultMainWithDoctests "doctests" diff --git a/hedgehog/src/Yaya/Hedgehog.hs b/hedgehog/src/Yaya/Hedgehog.hs index d66426a..d3885e8 100644 --- a/hedgehog/src/Yaya/Hedgehog.hs +++ b/hedgehog/src/Yaya/Hedgehog.hs @@ -1,16 +1,16 @@ -{-# LANGUAGE NumericUnderscores #-} +{-# LANGUAGE Unsafe #-} module Yaya.Hedgehog where -import "base" Control.Category (Category ((.))) -import "base" Control.Monad ((<=<)) -import "base" Control.Monad.IO.Class (MonadIO) -import "base" Data.Function (const) -import "base" Data.Maybe (maybe) +import safe "base" Control.Category (Category ((.))) +import safe "base" Control.Monad ((<=<)) +import safe "base" Control.Monad.IO.Class (MonadIO) +import safe "base" Data.Function (const) +import safe "base" Data.Maybe (maybe) import "base" GHC.IO (evaluate) -import "base" GHC.Stack (HasCallStack) -import "base" System.Timeout (timeout) -import "base" Text.Show (Show) +import safe "base" GHC.Stack (HasCallStack) +import safe "base" System.Timeout (timeout) +import safe "base" Text.Show (Show) import "hedgehog" Hedgehog -- | Returns success if the expression doesn’t terminate, failure otherwise. diff --git a/hedgehog/src/Yaya/Hedgehog/Expr.hs b/hedgehog/src/Yaya/Hedgehog/Expr.hs index 5ef8713..0ca62b2 100644 --- a/hedgehog/src/Yaya/Hedgehog/Expr.hs +++ b/hedgehog/src/Yaya/Hedgehog/Expr.hs @@ -1,22 +1,23 @@ {-# LANGUAGE TemplateHaskell #-} +{-# LANGUAGE Unsafe #-} module Yaya.Hedgehog.Expr where -import "base" Control.Applicative (Applicative (..)) -import "base" Data.Eq (Eq) -import "base" Data.Foldable (Foldable) -import "base" Data.Functor (Functor, (<$>)) -import "base" Data.Int (Int) -import "base" Data.Traversable (Traversable) -import "base" Text.Show (Show) -import "deriving-compat" Data.Eq.Deriving (deriveEq1) -import "deriving-compat" Text.Show.Deriving (deriveShow1) -import "hedgehog" Hedgehog (Gen, Size) -import qualified "hedgehog" Hedgehog.Gen as Gen -import qualified "hedgehog" Hedgehog.Range as Range -import "yaya" Yaya.Fold (Mu, Nu, Steppable) -import "yaya" Yaya.Fold.Native (Cofix, Fix) -import "this" Yaya.Hedgehog.Fold (embeddableOfHeight) +import safe "base" Control.Applicative (Applicative (..)) +import safe "base" Data.Eq (Eq) +import safe "base" Data.Foldable (Foldable) +import safe "base" Data.Functor (Functor, (<$>)) +import safe "base" Data.Int (Int) +import safe "base" Data.Traversable (Traversable) +import safe "base" Text.Show (Show) +import safe "deriving-compat" Data.Eq.Deriving (deriveEq1) +import safe "deriving-compat" Text.Show.Deriving (deriveShow1) +import safe "hedgehog" Hedgehog (Gen, Size) +import safe qualified "hedgehog" Hedgehog.Gen as Gen +import safe qualified "hedgehog" Hedgehog.Range as Range +import safe "yaya" Yaya.Fold (Mu, Nu, Steppable) +import safe "yaya" Yaya.Fold.Native (Cofix, Fix) +import safe "this" Yaya.Hedgehog.Fold (embeddableOfHeight) data Expr a = Lit Int diff --git a/hedgehog/src/Yaya/Hedgehog/Fold.hs b/hedgehog/src/Yaya/Hedgehog/Fold.hs index ded8358..823cc1a 100644 --- a/hedgehog/src/Yaya/Hedgehog/Fold.hs +++ b/hedgehog/src/Yaya/Hedgehog/Fold.hs @@ -1,19 +1,20 @@ -{-# LANGUAGE RankNTypes #-} -{-# LANGUAGE ScopedTypeVariables #-} {-# LANGUAGE TypeApplications #-} +-- "Hedgehog" is @Unsafe@ +{-# LANGUAGE Unsafe #-} +{-# OPTIONS_GHC -Wno-unrecognised-pragmas #-} module Yaya.Hedgehog.Fold where -import "base" Control.Category (Category (..)) -import "base" Data.Bifunctor (Bifunctor (..)) -import "base" Data.Eq (Eq) -import "base" Data.Function (($)) -import "base" Data.Functor (Functor (..)) -import "base" Data.Proxy (Proxy (..)) -import qualified "base" Data.Tuple as Tuple -import "base" Data.Void (Void, absurd) -import "base" Numeric.Natural (Natural) -import "base" Text.Show (Show) +import safe "base" Control.Category (Category (..)) +import safe "base" Data.Bifunctor (Bifunctor (..)) +import safe "base" Data.Eq (Eq) +import safe "base" Data.Function (($)) +import safe "base" Data.Functor (Functor (..)) +import safe "base" Data.Proxy (Proxy (..)) +import safe qualified "base" Data.Tuple as Tuple +import safe "base" Data.Void (Void, absurd) +import safe "base" Numeric.Natural (Natural) +import safe "base" Text.Show (Show) import "hedgehog" Hedgehog ( Gen, MonadTest, @@ -30,13 +31,13 @@ import "yaya" Yaya.Fold Recursive (..), Steppable (..), ) -import "yaya" Yaya.Fold.Common (diagonal) -import "yaya" Yaya.Fold.Native () -import "yaya" Yaya.Pattern (Maybe, Pair ((:!:)), fst, maybe, uncurry) +import safe "yaya" Yaya.Fold.Common (diagonal) +import safe "yaya" Yaya.Fold.Native () +import safe "yaya" Yaya.Pattern (Maybe, Pair ((:!:)), fst, maybe, uncurry) import "this" Yaya.Hedgehog (evalNonterminating) -import "base" Prelude (fromIntegral) +import safe "base" Prelude (fromIntegral) -{-# ANN module "HLint: ignore Use camelCase" #-} +{-# HLINT ignore "Use camelCase" #-} law_cataCancel :: ( Eq a, diff --git a/hedgehog/tests/doctests.hs b/hedgehog/tests/doctests.hs new file mode 100644 index 0000000..26008dc --- /dev/null +++ b/hedgehog/tests/doctests.hs @@ -0,0 +1,10 @@ +module Main (main) where + +import "base" Data.Function (($)) +import "base" Data.Semigroup (Semigroup ((<>))) +import "base" System.IO (IO) +import "doctest" Test.DocTest (doctest) +import "this" Build_doctests (flags, module_sources, pkgs) + +main :: IO () +main = doctest $ flags <> pkgs <> module_sources diff --git a/hedgehog/yaya-hedgehog.cabal b/hedgehog/yaya-hedgehog.cabal index c38959b..bfa5ad5 100644 --- a/hedgehog/yaya-hedgehog.cabal +++ b/hedgehog/yaya-hedgehog.cabal @@ -1,53 +1,170 @@ -name: yaya-hedgehog -version: 0.2.1.0 -synopsis: Hedgehog testing support for the Yaya recursion scheme - library. -description: If you use Yaya in your own code and have tests written - using Hedgehog, then this library will help you with - generating trees, verifying type class instances, etc. -homepage: https://github.com/sellout/yaya#readme -author: Greg Pfeil -maintainer: greg@technomadic.org -copyright: 2017 Greg Pfeil -license: AGPL-3 -license-file: LICENSE -category: Recursion -build-type: Simple -extra-source-files: CHANGELOG.md - , README.md -cabal-version: >=1.10 -tested-with: GHC == 8.6.1 - , GHC == 8.8.1, GHC == 8.8.4 - , GHC == 8.10.1 - , GHC == 9.0.1 - , GHC == 9.2.1 - , GHC == 9.4.1, GHC == 9.4.8 - , GHC == 9.6.1 - , GHC == 9.8.1 +cabal-version: 3.0 -library - hs-source-dirs: src - exposed-modules: Yaya.Hedgehog - , Yaya.Hedgehog.Expr - , Yaya.Hedgehog.Fold - build-depends: base >= 4.7 && < 5 - , deriving-compat - , hedgehog - , yaya >= 0.3.0 - default-extensions: ConstraintKinds - , DeriveTraversable - , FlexibleContexts - , FlexibleInstances - , FunctionalDependencies - , LambdaCase - , MultiParamTypeClasses - , PackageImports - , RankNTypes - , ScopedTypeVariables - , StrictData - , NoImplicitPrelude - default-language: Haskell2010 +name: yaya-hedgehog +version: 0.2.1.1 +synopsis: Hedgehog testing support for the Yaya recursion scheme + library. +description: If you use Yaya in your own code and have tests written + using Hedgehog, then this library will help you with + generating trees, verifying type class instances, etc. +author: Greg Pfeil +maintainer: Greg Pfeil +copyright: 2017 Greg Pfeil +homepage: https://github.com/sellout/yaya#readme +bug-reports: https://github.com/sellout/yaya/issues +category: Recursion +build-type: Custom +license: AGPL-3.0-or-later +license-files: + LICENSE +extra-source-files: + CHANGELOG.md + README.md +tested-with: + GHC == { +-- GHCup Nixpkgs + 8.6.1, + 8.8.1, 8.8.4, + 8.10.1, + 9.0.1, + 9.2.1, + 9.4.1, 9.4.8, + 9.6.1, + 9.8.1 + } source-repository head - type: git + type: git location: https://github.com/sellout/yaya + +-- This mimics the GHC2021 extension +-- (https://ghc.gitlab.haskell.org/ghc/doc/users_guide/exts/control.html?highlight=doandifthenelse#extension-GHC2021), +-- but supporting compilers back to GHC 7.10. If the oldest supported compiler +-- is GHC 9.2, then this stanza can be removed and `import: GHC2021` can be +-- replaced by `default-language: GHC2021`. +common GHC2021 + default-language: Haskell2010 + default-extensions: + BangPatterns + BinaryLiterals + ConstraintKinds + DeriveDataTypeable + DeriveGeneric + -- DeriveLift -- uncomment if the oldest supported version is GHC 8.10.1+ + DeriveTraversable + DerivingStrategies + DoAndIfThenElse + EmptyCase + ExistentialQuantification + FlexibleContexts + FlexibleInstances + GADTSyntax + GeneralizedNewtypeDeriving + HexFloatLiterals + -- ImportQualifiedPost -- uncomment if the oldest supported version is GHC 8.10.1+ + InstanceSigs + LambdaCase + MagicHash + MonadComprehensions + MonomorphismRestriction + MultiParamTypeClasses + NamedFieldPuns + NamedWildCards + NumericUnderscores + PolyKinds + PostfixOperators + RankNTypes + ScopedTypeVariables + StandaloneDeriving + -- StandaloneKindSignatures -- uncomment if the oldest supported version is GHC 8.10.1+ + TupleSections + TypeApplications + TypeOperators + UnicodeSyntax + NoExplicitNamespaces + +common defaults + import: GHC2021 + build-depends: + base ^>= {4.12.0, 4.13.0, 4.14.0, 4.15.0, 4.16.0, 4.17.0, 4.18.0, 4.19.0}, + ghc-options: + -Wall + -Wtrustworthy-safe + -fpackage-trust + if impl(ghc >= 8.10.1) + ghc-options: + -Wmissing-safe-haskell-mode + default-extensions: + DefaultSignatures + ExplicitNamespaces + FunctionalDependencies + LiberalTypeSynonyms + -- replace with `LexicalNegation` if the oldest supported version is GHC 9.0.1+ + NegativeLiterals + PackageImports + ParallelListComp + -- QualifiedDo - uncomment if the oldest supported version is GHC 9.0.1+ + RecursiveDo + -- RequiredTypeArguments - uncomment if the oldest supported version is GHC 9.10.1+ + StrictData + TemplateHaskellQuotes + TransformListComp + NoGeneralizedNewtypeDeriving + NoImplicitPrelude + NoMonomorphismRestriction + NoPatternGuards + NoTypeApplications + +custom-setup + setup-depends: + -- TODO: Remove `Cabal` dep once haskell/cabal#3751 is fixed. + Cabal ^>= {3.0.0, 3.2.0, 3.4.0, 3.6.0, 3.8.0, 3.10.0}, + base ^>= {4.12.0, 4.13.0, 4.14.0, 4.15.0, 4.16.0, 4.17.0, 4.18.0, 4.19.0}, + cabal-doctest ^>= 1.0.0 + +library + import: defaults + hs-source-dirs: + src + exposed-modules: + Yaya.Hedgehog + Yaya.Hedgehog.Expr + Yaya.Hedgehog.Fold + build-depends: + deriving-compat, + hedgehog, + yaya >= 0.3.0, + ghc-options: + -trust adjunctions + -trust array + -trust base + -trust base-orphans + -trust binary + -trust bytestring + -trust containers + -trust distributive + -trust exceptions + -trust ghc-prim + -trust profunctors + -trust semigroupoids + -trust stm + -trust text + -trust transformers-compat + if impl(ghc < 9.6) + ghc-options: + -trust foldable1-classes-compat + +test-suite doctests + import: defaults + type: exitcode-stdio-1.0 + hs-source-dirs: tests + main-is: doctests.hs + build-depends: + doctest ^>= {0.15.0, 0.16.0, 0.17.0, 0.18.0, 0.19.0, 0.20.0, 0.21.0, 0.22.0}, + yaya-hedgehog, + default-extensions: + -- TODO: Other flags require each module to be compiled with a safety level. + -- Since it’s currently not possible to add `{-# LANGUAGE Safe -#}` to + -- the generated “Build_doctests.hs” and since doctests.hs is + -- `Unsafe`, this is the only safety level that can be used. + Unsafe diff --git a/pre-push b/pre-push deleted file mode 100755 index af29406..0000000 --- a/pre-push +++ /dev/null @@ -1,3 +0,0 @@ -#!/usr/bin/env bash - -nix flake check diff --git a/quickcheck/Setup.hs b/quickcheck/Setup.hs new file mode 100644 index 0000000..6cea120 --- /dev/null +++ b/quickcheck/Setup.hs @@ -0,0 +1,14 @@ +-- __NB__: `custom-setup` doesn’t have any way to specify extensions, so any we +-- want need to be specified here. +{-# LANGUAGE PackageImports #-} +{-# LANGUAGE Unsafe #-} +{-# LANGUAGE NoImplicitPrelude #-} +{-# OPTIONS_GHC -Wall #-} + +module Main (main) where + +import safe "base" System.IO (IO) +import "cabal-doctest" Distribution.Extra.Doctest (defaultMainWithDoctests) + +main :: IO () +main = defaultMainWithDoctests "doctests" diff --git a/quickcheck/src/Yaya/QuickCheck/Fold.hs b/quickcheck/src/Yaya/QuickCheck/Fold.hs index dd38299..fbf3cf2 100644 --- a/quickcheck/src/Yaya/QuickCheck/Fold.hs +++ b/quickcheck/src/Yaya/QuickCheck/Fold.hs @@ -1,3 +1,4 @@ +{-# LANGUAGE Safe #-} {-# OPTIONS_GHC -Wno-orphans #-} module Yaya.QuickCheck.Fold diff --git a/quickcheck/tests/doctests.hs b/quickcheck/tests/doctests.hs new file mode 100644 index 0000000..26008dc --- /dev/null +++ b/quickcheck/tests/doctests.hs @@ -0,0 +1,10 @@ +module Main (main) where + +import "base" Data.Function (($)) +import "base" Data.Semigroup (Semigroup ((<>))) +import "base" System.IO (IO) +import "doctest" Test.DocTest (doctest) +import "this" Build_doctests (flags, module_sources, pkgs) + +main :: IO () +main = doctest $ flags <> pkgs <> module_sources diff --git a/quickcheck/yaya-quickcheck.cabal b/quickcheck/yaya-quickcheck.cabal index 7ed6889..ddffc3e 100644 --- a/quickcheck/yaya-quickcheck.cabal +++ b/quickcheck/yaya-quickcheck.cabal @@ -1,50 +1,169 @@ -name: yaya-quickcheck -version: 0.1.0.0 -synopsis: QuickCheck testing support for the Yaya recursion scheme - library. -description: If you use Yaya in your own code and have tests written - using QuickCheck, then this library will help you with - generating trees, verifying type class instances, etc. -homepage: https://github.com/sellout/yaya#readme -author: Greg Pfeil -maintainer: greg@technomadic.org -copyright: 2024 Greg Pfeil -license: AGPL-3 -license-file: LICENSE -category: Recursion -build-type: Simple -extra-source-files: CHANGELOG.md - , README.md -cabal-version: >=1.10 -tested-with: GHC == 8.6.1 - , GHC == 8.8.1, GHC == 8.8.4 - , GHC == 8.10.1 - , GHC == 9.0.1 - , GHC == 9.2.1 - , GHC == 9.4.1, GHC == 9.4.8 - , GHC == 9.6.1 - , GHC == 9.8.1 +cabal-version: 3.0 -library - hs-source-dirs: src - exposed-modules: Yaya.QuickCheck.Fold - build-depends: QuickCheck - , base >= 4.7 && < 5 - , yaya >= 0.5.0 - default-extensions: ConstraintKinds - , DeriveTraversable - , FlexibleContexts - , FlexibleInstances - , FunctionalDependencies - , LambdaCase - , MultiParamTypeClasses - , PackageImports - , RankNTypes - , ScopedTypeVariables - , StrictData - , NoImplicitPrelude - default-language: Haskell2010 +name: yaya-quickcheck +version: 0.1.0.1 +synopsis: QuickCheck testing support for the Yaya recursion scheme library. +description: If you use Yaya in your own code and have tests written using + QuickCheck, then this library will help you with generating trees, + verifying type class instances, etc. +author: Greg Pfeil +maintainer: Greg Pfeil +copyright: 2017 Greg Pfeil +homepage: https://github.com/sellout/yaya#readme +bug-reports: https://github.com/sellout/yaya/issues +category: Recursion +build-type: Custom +license: AGPL-3.0-or-later +license-files: + LICENSE +extra-source-files: + CHANGELOG.md + README.md +tested-with: + GHC == { +-- GHCup Nixpkgs + 8.6.1, + 8.8.1, 8.8.4, + 8.10.1, + 9.0.1, + 9.2.1, + 9.4.1, 9.4.8, + 9.6.1, + 9.8.1 + } source-repository head - type: git + type: git location: https://github.com/sellout/yaya + +-- This mimics the GHC2021 extension +-- (https://ghc.gitlab.haskell.org/ghc/doc/users_guide/exts/control.html?highlight=doandifthenelse#extension-GHC2021), +-- but supporting compilers back to GHC 7.10. If the oldest supported compiler +-- is GHC 9.2, then this stanza can be removed and `import: GHC2021` can be +-- replaced by `default-language: GHC2021`. +common GHC2021 + default-language: Haskell2010 + default-extensions: + BangPatterns + BinaryLiterals + ConstraintKinds + DeriveDataTypeable + DeriveGeneric + -- DeriveLift -- uncomment if the oldest supported version is GHC 8.10.1+ + DeriveTraversable + DerivingStrategies + DoAndIfThenElse + EmptyCase + ExistentialQuantification + FlexibleContexts + FlexibleInstances + GADTSyntax + GeneralizedNewtypeDeriving + HexFloatLiterals + -- ImportQualifiedPost -- uncomment if the oldest supported version is GHC 8.10.1+ + InstanceSigs + LambdaCase + MagicHash + MonadComprehensions + MonomorphismRestriction + MultiParamTypeClasses + NamedFieldPuns + NamedWildCards + NumericUnderscores + PolyKinds + PostfixOperators + RankNTypes + ScopedTypeVariables + StandaloneDeriving + -- StandaloneKindSignatures -- uncomment if the oldest supported version is GHC 8.10.1+ + TupleSections + TypeApplications + TypeOperators + UnicodeSyntax + NoExplicitNamespaces + +common defaults + import: GHC2021 + build-depends: + base ^>= {4.12.0, 4.13.0, 4.14.0, 4.15.0, 4.16.0, 4.17.0, 4.18.0, 4.19.0}, + ghc-options: + -Wall + -Wtrustworthy-safe + -fpackage-trust + if impl(ghc >= 8.10.1) + ghc-options: + -Wmissing-safe-haskell-mode + default-extensions: + DefaultSignatures + ExplicitNamespaces + FunctionalDependencies + LiberalTypeSynonyms + -- replace with `LexicalNegation` if the oldest supported version is GHC 9.0.1+ + NegativeLiterals + PackageImports + ParallelListComp + -- QualifiedDo - uncomment if the oldest supported version is GHC 9.0.1+ + RecursiveDo + -- RequiredTypeArguments - uncomment if the oldest supported version is GHC 9.10.1+ + StrictData + TemplateHaskellQuotes + TransformListComp + NoGeneralizedNewtypeDeriving + NoImplicitPrelude + NoMonomorphismRestriction + NoPatternGuards + NoTypeApplications + +custom-setup + setup-depends: + -- TODO: Remove `Cabal` dep once haskell/cabal#3751 is fixed. + Cabal ^>= {3.0.0, 3.2.0, 3.4.0, 3.6.0, 3.8.0, 3.10.0}, + base ^>= {4.12.0, 4.13.0, 4.14.0, 4.15.0, 4.16.0, 4.17.0, 4.18.0, 4.19.0}, + cabal-doctest ^>= 1.0.0 + +library + import: defaults + hs-source-dirs: + src + exposed-modules: + Yaya.QuickCheck.Fold + build-depends: + QuickCheck, + yaya >= 0.5.0, + ghc-options: + -trust QuickCheck + -trust adjunctions + -trust array + -trust base + -trust base-orphans + -trust binary + -trust bytestring + -trust containers + -trust distributive + -trust exceptions + -trust ghc-prim + -trust profunctors + -trust random + -trust semigroupoids + -trust splitmix + -trust stm + -trust text + -trust transformers-compat + if impl(ghc < 9.6) + ghc-options: + -trust foldable1-classes-compat + +test-suite doctests + import: defaults + type: exitcode-stdio-1.0 + hs-source-dirs: tests + main-is: doctests.hs + build-depends: + doctest ^>= {0.15.0, 0.16.0, 0.17.0, 0.18.0, 0.19.0, 0.20.0, 0.21.0, 0.22.0}, + yaya-quickcheck, + default-extensions: + -- TODO: Other flags require each module to be compiled with a safety level. + -- Since it’s currently not possible to add `{-# LANGUAGE Safe -#}` to + -- the generated “Build_doctests.hs” and since doctests.hs is + -- `Unsafe`, this is the only safety level that can be used. + Unsafe diff --git a/unsafe-test/test/Test/Fold.hs b/unsafe-test/test/Test/Fold.hs index 3d2b1d3..60c54f8 100644 --- a/unsafe-test/test/Test/Fold.hs +++ b/unsafe-test/test/Test/Fold.hs @@ -1,22 +1,23 @@ -{-# LANGUAGE ScopedTypeVariables #-} {-# LANGUAGE TemplateHaskell #-} {-# LANGUAGE TypeApplications #-} +{-# LANGUAGE Unsafe #-} +{-# OPTIONS_GHC -Wno-unrecognised-pragmas #-} module Test.Fold where -import "base" Control.Category (Category (..)) -import "base" Control.Monad ((=<<)) -import "base" Data.Bool (Bool) -import "base" Data.Function (($)) -import "base" Data.Int (Int) -import "base" Data.Proxy (Proxy (..)) -import "base" System.IO (IO) -import "hedgehog" Hedgehog (Property, checkParallel, discover, forAll, property) -import qualified "hedgehog" Hedgehog.Gen as Gen -import "yaya" Yaya.Fold (Mu, Nu) -import "yaya" Yaya.Fold.Common (size) -import "yaya" Yaya.Fold.Native (Cofix, Fix) -import "yaya-hedgehog" Yaya.Hedgehog.Expr +import safe "base" Control.Category (Category (..)) +import safe "base" Control.Monad ((=<<)) +import safe "base" Data.Bool (Bool) +import safe "base" Data.Function (($)) +import safe "base" Data.Int (Int) +import safe "base" Data.Proxy (Proxy (..)) +import safe "base" System.IO (IO) +import safe "hedgehog" Hedgehog (Property, checkParallel, discover, forAll, property) +import safe qualified "hedgehog" Hedgehog.Gen as Gen +import safe "yaya" Yaya.Fold (Mu, Nu) +import safe "yaya" Yaya.Fold.Common (size) +import safe "yaya" Yaya.Fold.Native (Cofix, Fix) +import safe "yaya-hedgehog" Yaya.Hedgehog.Expr ( Expr, genCofixExpr, genExpr, @@ -24,7 +25,7 @@ import "yaya-hedgehog" Yaya.Hedgehog.Expr genMuExpr, genNuExpr, ) -import "yaya-hedgehog" Yaya.Hedgehog.Fold +import safe "yaya-hedgehog" Yaya.Hedgehog.Fold ( corecursiveIsUnsafe, law_anaRefl, law_cataCancel, @@ -32,10 +33,10 @@ import "yaya-hedgehog" Yaya.Hedgehog.Fold law_cataRefl, recursiveIsUnsafe, ) -import qualified "yaya-unsafe" Yaya.Unsafe.Fold.Instances () +import safe qualified "yaya-unsafe" Yaya.Unsafe.Fold.Instances () -- TODO: For some reason HLint is complaining that TemplateHaskell is unused. -{-# ANN module "HLint: ignore Unused LANGUAGE pragma" #-} +{-# HLINT ignore "Unused LANGUAGE pragma" #-} prop_fixAnaRefl :: Property prop_fixAnaRefl = diff --git a/unsafe-test/test/test.hs b/unsafe-test/test/test.hs index e806f99..4a7a953 100644 --- a/unsafe-test/test/test.hs +++ b/unsafe-test/test/test.hs @@ -1,5 +1,7 @@ -import "base" System.IO (IO) -import "hedgehog" Hedgehog.Main (defaultMain) +{-# LANGUAGE Unsafe #-} + +import safe "base" System.IO (IO) +import safe "hedgehog" Hedgehog.Main (defaultMain) import qualified "this" Test.Fold as Fold main :: IO () diff --git a/unsafe-test/yaya-unsafe-test.cabal b/unsafe-test/yaya-unsafe-test.cabal index 36e93f9..4e113ed 100644 --- a/unsafe-test/yaya-unsafe-test.cabal +++ b/unsafe-test/yaya-unsafe-test.cabal @@ -1,44 +1,151 @@ -name: yaya-unsafe-test -version: 0.2.0.0 -synopsis: Test suites for `yaya-unsafe`. -description: This package should not be depended on by anything. -homepage: https://github.com/sellout/yaya#readme -author: Greg Pfeil -maintainer: greg@technomadic.org -copyright: 2017 Greg Pfeil -license: AGPL-3 -license-file: LICENSE -category: Recursion -build-type: Simple -cabal-version: >=1.10 -tested-with: GHC == 8.6.1 - , GHC == 8.8.1, GHC == 8.8.4 - , GHC == 8.10.1 - , GHC == 9.0.1 - , GHC == 9.2.1 - , GHC == 9.4.1, GHC == 9.4.8 - , GHC == 9.6.1 - , GHC == 9.8.1 +cabal-version: 3.0 -test-suite yaya-unsafe-test - type: exitcode-stdio-1.0 - hs-source-dirs: test - main-is: test.hs - other-modules: Test.Fold - build-depends: base >= 4.7 && < 5 - , hedgehog - , yaya >= 0.5.0 - , yaya-hedgehog >= 0.2.1 - , yaya-unsafe >= 0.3.0 - default-extensions: FlexibleContexts - , PackageImports - , StrictData - , NoImplicitPrelude - -- NB: Need `-fno-omit-yields` so that `timeout` can interrupt native - -- recursion in non-termination tests. - ghc-options: -fno-omit-yields -threaded -rtsopts -with-rtsopts=-N -Wall - default-language: Haskell2010 +name: yaya-unsafe-test +version: 0.2.0.1 +synopsis: Test suites for `yaya-unsafe`. +description: This package should not be depended on by anything. +author: Greg Pfeil +maintainer: Greg Pfeil +copyright: 2017 Greg Pfeil +homepage: https://github.com/sellout/yaya#readme +bug-reports: https://github.com/sellout/yaya/issues +category: Recursion +build-type: Simple +license: AGPL-3.0-or-later +license-files: + LICENSE +tested-with: + GHC == { +-- GHCup Nixpkgs + 8.6.1, + 8.8.1, 8.8.4, + 8.10.1, + 9.0.1, + 9.2.1, + 9.4.1, 9.4.8, + 9.6.1, + 9.8.1 + } source-repository head - type: git + type: git location: https://github.com/sellout/yaya + +-- This mimics the GHC2021 extension +-- (https://ghc.gitlab.haskell.org/ghc/doc/users_guide/exts/control.html?highlight=doandifthenelse#extension-GHC2021), +-- but supporting compilers back to GHC 7.10. If the oldest supported compiler +-- is GHC 9.2, then this stanza can be removed and `import: GHC2021` can be +-- replaced by `default-language: GHC2021`. +common GHC2021 + default-language: Haskell2010 + default-extensions: + BangPatterns + BinaryLiterals + ConstraintKinds + DeriveDataTypeable + DeriveGeneric + -- DeriveLift -- uncomment if the oldest supported version is GHC 8.10.1+ + DeriveTraversable + DerivingStrategies + DoAndIfThenElse + EmptyCase + ExistentialQuantification + FlexibleContexts + FlexibleInstances + GADTSyntax + GeneralizedNewtypeDeriving + HexFloatLiterals + -- ImportQualifiedPost -- uncomment if the oldest supported version is GHC 8.10.1+ + InstanceSigs + LambdaCase + MagicHash + MonadComprehensions + MonomorphismRestriction + MultiParamTypeClasses + NamedFieldPuns + NamedWildCards + NumericUnderscores + PolyKinds + PostfixOperators + RankNTypes + ScopedTypeVariables + StandaloneDeriving + -- StandaloneKindSignatures -- uncomment if the oldest supported version is GHC 8.10.1+ + TupleSections + TypeApplications + TypeOperators + UnicodeSyntax + NoExplicitNamespaces + +common defaults + import: GHC2021 + build-depends: + base ^>= {4.12.0, 4.13.0, 4.14.0, 4.15.0, 4.16.0, 4.17.0, 4.18.0, 4.19.0}, + ghc-options: + -Wall + -Wtrustworthy-safe + -fpackage-trust + if impl(ghc >= 8.10.1) + ghc-options: + -Wmissing-safe-haskell-mode + default-extensions: + DefaultSignatures + ExplicitNamespaces + FunctionalDependencies + LiberalTypeSynonyms + -- replace with `LexicalNegation` if the oldest supported version is GHC 9.0.1+ + NegativeLiterals + PackageImports + ParallelListComp + -- QualifiedDo - uncomment if the oldest supported version is GHC 9.0.1+ + RecursiveDo + -- RequiredTypeArguments - uncomment if the oldest supported version is GHC 9.10.1+ + StrictData + TemplateHaskellQuotes + TransformListComp + NoGeneralizedNewtypeDeriving + NoImplicitPrelude + NoMonomorphismRestriction + NoPatternGuards + NoTypeApplications + +test-suite yaya-unsafe-test + import: defaults + type: exitcode-stdio-1.0 + hs-source-dirs: + test + main-is: test.hs + other-modules: + Test.Fold + build-depends: + hedgehog, + yaya >= 0.5.0, + yaya-hedgehog >= 0.2.1, + yaya-unsafe >= 0.3.0, + ghc-options: + -- NB: Need `-fno-omit-yields` so that `timeout` can interrupt native + -- recursion in non-termination tests. + -fno-omit-yields + -rtsopts + -threaded + -trust adjunctions + -trust array + -trust base + -trust base-orphans + -trust binary + -trust bytestring + -trust containers + -trust distributive + -trust exceptions + -trust ghc-prim + -trust lens + -trust profunctors + -trust semigroupoids + -trust stm + -trust template-haskell + -trust text + -trust transformers-compat + -with-rtsopts=-N + if impl(ghc < 9.6) + ghc-options: + -trust foldable1-classes-compat diff --git a/unsafe/Setup.hs b/unsafe/Setup.hs new file mode 100644 index 0000000..6cea120 --- /dev/null +++ b/unsafe/Setup.hs @@ -0,0 +1,14 @@ +-- __NB__: `custom-setup` doesn’t have any way to specify extensions, so any we +-- want need to be specified here. +{-# LANGUAGE PackageImports #-} +{-# LANGUAGE Unsafe #-} +{-# LANGUAGE NoImplicitPrelude #-} +{-# OPTIONS_GHC -Wall #-} + +module Main (main) where + +import safe "base" System.IO (IO) +import "cabal-doctest" Distribution.Extra.Doctest (defaultMainWithDoctests) + +main :: IO () +main = defaultMainWithDoctests "doctests" diff --git a/unsafe/src/Yaya/Unsafe/Applied.hs b/unsafe/src/Yaya/Unsafe/Applied.hs index 2ec2e87..fcbb5e7 100644 --- a/unsafe/src/Yaya/Unsafe/Applied.hs +++ b/unsafe/src/Yaya/Unsafe/Applied.hs @@ -1,3 +1,5 @@ +{-# LANGUAGE Safe #-} + module Yaya.Unsafe.Applied where import "yaya" Yaya.Fold (Steppable (embed)) diff --git a/unsafe/src/Yaya/Unsafe/Fold.hs b/unsafe/src/Yaya/Unsafe/Fold.hs index 50cd29b..016c6d0 100644 --- a/unsafe/src/Yaya/Unsafe/Fold.hs +++ b/unsafe/src/Yaya/Unsafe/Fold.hs @@ -1,3 +1,5 @@ +{-# LANGUAGE Safe #-} + -- | Definitions and instances that use direct recursion, which (because of -- laziness) can lead to non-termination. module Yaya.Unsafe.Fold where diff --git a/unsafe/src/Yaya/Unsafe/Fold/Instances.hs b/unsafe/src/Yaya/Unsafe/Fold/Instances.hs index 13b996f..5296eab 100644 --- a/unsafe/src/Yaya/Unsafe/Fold/Instances.hs +++ b/unsafe/src/Yaya/Unsafe/Fold/Instances.hs @@ -1,3 +1,13 @@ +{-# LANGUAGE CPP #-} + +-- __NB__: base-4.17 moves `IsList` to its own module, which avoids the unsafety +-- of importing "GHC.Exts". With prior versions of base, we at least +-- mark the module @Trustworthy@. +#if MIN_VERSION_base(4, 17, 0) +{-# LANGUAGE Safe #-} +#else +{-# LANGUAGE Trustworthy #-} +#endif {-# LANGUAGE TypeFamilies #-} {-# OPTIONS_GHC -Wno-orphans #-} @@ -12,19 +22,25 @@ -- to terminate. module Yaya.Unsafe.Fold.Instances where -import "base" Control.Category (Category (..)) -import "base" Data.Eq (Eq (..)) -import "base" Data.Foldable (Foldable) -import "base" Data.Function (flip) -import "base" Data.Functor (Functor, (<$>)) -import "base" Data.Functor.Classes (Eq1, Show1) -import "base" Data.List.NonEmpty (NonEmpty) +import safe "base" Control.Category (Category (..)) +import safe "base" Data.Eq (Eq (..)) +import safe "base" Data.Foldable (Foldable) +import safe "base" Data.Function (flip) +import safe "base" Data.Functor (Functor, (<$>)) +import safe "base" Data.Functor.Classes (Eq1, Show1) +import safe "base" Data.List.NonEmpty (NonEmpty) + +-- See comment on @{-# LANGUAGE Safe #-}@ above. +#if MIN_VERSION_base(4, 17, 0) +import "base" GHC.IsList (IsList (Item, fromList, fromListN, toList)) +#else import "base" GHC.Exts (IsList (Item, fromList, fromListN, toList)) -import "base" Text.Show (Show (..)) -import "comonad" Control.Comonad.Env (EnvT) -import "free" Control.Comonad.Cofree (Cofree) -import "free" Control.Monad.Trans.Free (Free, FreeF (..), free) -import "yaya" Yaya.Fold +#endif +import safe "base" Text.Show (Show (..)) +import safe "comonad" Control.Comonad.Env (EnvT) +import safe "free" Control.Comonad.Cofree (Cofree) +import safe "free" Control.Monad.Trans.Free (Free, FreeF (..), free) +import safe "yaya" Yaya.Fold ( Corecursive (..), DistributiveLaw, Mu, @@ -35,10 +51,10 @@ import "yaya" Yaya.Fold recursiveEq, recursiveShowsPrec, ) -import "yaya" Yaya.Fold.Native (Cofix, Fix) -import "yaya" Yaya.Pattern (AndMaybe, XNor) -import "this" Yaya.Unsafe.Applied (unsafeFromList) -import qualified "this" Yaya.Unsafe.Fold as Unsafe +import safe "yaya" Yaya.Fold.Native (Cofix, Fix) +import safe "yaya" Yaya.Pattern (AndMaybe, XNor) +import safe "this" Yaya.Unsafe.Applied (unsafeFromList) +import safe qualified "this" Yaya.Unsafe.Fold as Unsafe instance (Functor f) => Corecursive (->) (Fix f) f where ana = Unsafe.hylo embed diff --git a/unsafe/src/Yaya/Unsafe/Zoo.hs b/unsafe/src/Yaya/Unsafe/Zoo.hs index 9ce1d44..4755735 100644 --- a/unsafe/src/Yaya/Unsafe/Zoo.hs +++ b/unsafe/src/Yaya/Unsafe/Zoo.hs @@ -1,3 +1,5 @@ +{-# LANGUAGE Safe #-} + module Yaya.Unsafe.Zoo where import "base" Control.Applicative (Applicative (..)) @@ -35,7 +37,7 @@ import "yaya" Yaya.Fold.Common (diagonal, fromEither) import "yaya" Yaya.Fold.Native (distCofreeT) import "yaya" Yaya.Pattern (Either, Maybe (..), Pair (..), XNor (..)) import qualified "this" Yaya.Unsafe.Fold as Unsafe -import qualified "this" Yaya.Unsafe.Fold.Instances as Unsafe -- NB: extremely unsafe +import qualified "this" Yaya.Unsafe.Fold.Instances as Unsafe -- FIXME: extremely unsafe chrono :: (Functor f) => diff --git a/unsafe/tests/doctests.hs b/unsafe/tests/doctests.hs new file mode 100644 index 0000000..26008dc --- /dev/null +++ b/unsafe/tests/doctests.hs @@ -0,0 +1,10 @@ +module Main (main) where + +import "base" Data.Function (($)) +import "base" Data.Semigroup (Semigroup ((<>))) +import "base" System.IO (IO) +import "doctest" Test.DocTest (doctest) +import "this" Build_doctests (flags, module_sources, pkgs) + +main :: IO () +main = doctest $ flags <> pkgs <> module_sources diff --git a/unsafe/yaya-unsafe.cabal b/unsafe/yaya-unsafe.cabal index d0edb17..f98f742 100644 --- a/unsafe/yaya-unsafe.cabal +++ b/unsafe/yaya-unsafe.cabal @@ -1,61 +1,180 @@ -name: yaya-unsafe -version: 0.3.1.0 -synopsis: Non-total extensions to the Yaya recursion scheme library. -description: Yaya is designed as a _total_ library. However, it is often - expedient to use partial operations in some cases, and this - package extends Yaya to provide those operations. It’s in a - separate package (and modules) in order to make sure its - use is very intentional and also relatively obvious to - those reading your code. It’s recommended that you import - these modules qualified and, in particular, all the type - class instances here have been pulled into a separate - module to avoid accidentally bringing them into scope. -homepage: https://github.com/sellout/yaya#readme -author: Greg Pfeil -maintainer: greg@technomadic.org -copyright: 2017 Greg Pfeil -license: AGPL-3 -license-file: LICENSE -category: Recursion -build-type: Simple -extra-source-files: CHANGELOG.md - , README.md -cabal-version: >=1.10 -tested-with: GHC == 8.6.1 - , GHC == 8.8.1, GHC == 8.8.4 - , GHC == 8.10.1 - , GHC == 9.0.1 - , GHC == 9.2.1 - , GHC == 9.4.1, GHC == 9.4.8 - , GHC == 9.6.1 - , GHC == 9.8.1 +cabal-version: 3.0 -library - hs-source-dirs: src - exposed-modules: Yaya.Unsafe.Applied - , Yaya.Unsafe.Fold - , Yaya.Unsafe.Fold.Instances - , Yaya.Unsafe.Zoo - build-depends: base >= 4.7 && < 5 - , bifunctors - , comonad - , free - , lens - , yaya >= 0.5.1 - default-extensions: ConstraintKinds - , DeriveTraversable - , FlexibleContexts - , FlexibleInstances - , FunctionalDependencies - , LambdaCase - , MultiParamTypeClasses - , PackageImports - , RankNTypes - , ScopedTypeVariables - , StrictData - , NoImplicitPrelude - default-language: Haskell2010 +name: yaya-unsafe +version: 0.3.2.0 +synopsis: Non-total extensions to the Yaya recursion scheme library. +description: Yaya is designed as a _total_ library. However, it is often + expedient to use partial operations in some cases, and this package + extends Yaya to provide those operations. It’s in a separate + package (and modules) in order to make sure its use is very + intentional and also relatively obvious to those reading your code. + It’s recommended that you import these modules qualified and, in + particular, all the type class instances here have been pulled into + a separate module to avoid accidentally bringing them into scope. +author: Greg Pfeil +maintainer: Greg Pfeil +copyright: 2017 Greg Pfeil +homepage: https://github.com/sellout/yaya#readme +bug-reports: https://github.com/sellout/yaya/issues +category: Recursion +build-type: Custom +license: AGPL-3.0-or-later +license-files: + LICENSE +extra-source-files: + CHANGELOG.md + README.md +tested-with: + GHC == { +-- GHCup Nixpkgs + 8.6.1, + 8.8.1, 8.8.4, + 8.10.1, + 9.0.1, + 9.2.1, + 9.4.1, 9.4.8, + 9.6.1, + 9.8.1 + } source-repository head - type: git + type: git location: https://github.com/sellout/yaya + +-- This mimics the GHC2021 extension +-- (https://ghc.gitlab.haskell.org/ghc/doc/users_guide/exts/control.html?highlight=doandifthenelse#extension-GHC2021), +-- but supporting compilers back to GHC 7.10. If the oldest supported compiler +-- is GHC 9.2, then this stanza can be removed and `import: GHC2021` can be +-- replaced by `default-language: GHC2021`. +common GHC2021 + default-language: Haskell2010 + default-extensions: + BangPatterns + BinaryLiterals + ConstraintKinds + DeriveDataTypeable + DeriveGeneric + -- DeriveLift -- uncomment if the oldest supported version is GHC 8.10.1+ + DeriveTraversable + DerivingStrategies + DoAndIfThenElse + EmptyCase + ExistentialQuantification + FlexibleContexts + FlexibleInstances + GADTSyntax + GeneralizedNewtypeDeriving + HexFloatLiterals + -- ImportQualifiedPost -- uncomment if the oldest supported version is GHC 8.10.1+ + InstanceSigs + LambdaCase + MagicHash + MonadComprehensions + MonomorphismRestriction + MultiParamTypeClasses + NamedFieldPuns + NamedWildCards + NumericUnderscores + PolyKinds + PostfixOperators + RankNTypes + ScopedTypeVariables + StandaloneDeriving + -- StandaloneKindSignatures -- uncomment if the oldest supported version is GHC 8.10.1+ + TupleSections + TypeApplications + TypeOperators + UnicodeSyntax + NoExplicitNamespaces + +common defaults + import: GHC2021 + build-depends: + base ^>= {4.12.0, 4.13.0, 4.14.0, 4.15.0, 4.16.0, 4.17.0, 4.18.0, 4.19.0}, + ghc-options: + -Wall + -Wtrustworthy-safe + -fpackage-trust + if impl(ghc >= 8.10.1) + ghc-options: + -Wmissing-safe-haskell-mode + default-extensions: + DefaultSignatures + ExplicitNamespaces + FunctionalDependencies + LiberalTypeSynonyms + -- replace with `LexicalNegation` if the oldest supported version is GHC 9.0.1+ + NegativeLiterals + PackageImports + ParallelListComp + -- QualifiedDo - uncomment if the oldest supported version is GHC 9.0.1+ + RecursiveDo + -- RequiredTypeArguments - uncomment if the oldest supported version is GHC 9.10.1+ + StrictData + TemplateHaskellQuotes + TransformListComp + NoGeneralizedNewtypeDeriving + NoImplicitPrelude + NoMonomorphismRestriction + NoPatternGuards + NoTypeApplications + +custom-setup + setup-depends: + -- TODO: Remove `Cabal` dep once haskell/cabal#3751 is fixed. + Cabal ^>= {3.0.0, 3.2.0, 3.4.0, 3.6.0, 3.8.0, 3.10.0}, + base ^>= {4.12.0, 4.13.0, 4.14.0, 4.15.0, 4.16.0, 4.17.0, 4.18.0, 4.19.0}, + cabal-doctest ^>= 1.0.0 + +library + import: defaults + hs-source-dirs: + src + exposed-modules: + Yaya.Unsafe.Applied + Yaya.Unsafe.Fold + Yaya.Unsafe.Fold.Instances + Yaya.Unsafe.Zoo + build-depends: + bifunctors, + comonad, + free, + lens, + yaya >= 0.5.1, + ghc-options: + -trust adjunctions + -trust array + -trust base + -trust base-orphans + -trust binary + -trust bytestring + -trust containers + -trust distributive + -trust exceptions + -trust ghc-prim + -trust lens + -trust profunctors + -trust semigroupoids + -trust stm + -trust text + -trust transformers-compat + if impl(ghc < 9.6) + ghc-options: + -trust foldable1-classes-compat + +test-suite doctests + import: defaults + type: exitcode-stdio-1.0 + hs-source-dirs: tests + main-is: doctests.hs + ghc-options: + -trust base + build-depends: + doctest ^>= {0.15.0, 0.16.0, 0.17.0, 0.18.0, 0.19.0, 0.20.0, 0.21.0, 0.22.0}, + yaya-unsafe, + default-extensions: + -- TODO: Other flags require each module to be compiled with a safety level. + -- Since it’s currently not possible to add `{-# LANGUAGE Safe -#}` to + -- the generated “Build_doctests.hs” and since doctests.hs is + -- `Unsafe`, this is the only safety level that can be used. + Unsafe