Hello community, here is the log from the commit of package ghc-bifunctors for openSUSE:Factory checked in at 2020-10-23 15:13:37 ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ Comparing /work/SRC/openSUSE:Factory/ghc-bifunctors (Old) and /work/SRC/openSUSE:Factory/.ghc-bifunctors.new.3463 (New) ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
Package is "ghc-bifunctors" Fri Oct 23 15:13:37 2020 rev:21 rq:842740 version:5.5.8 Changes: -------- --- /work/SRC/openSUSE:Factory/ghc-bifunctors/ghc-bifunctors.changes 2020-09-07 21:28:42.409197449 +0200 +++ /work/SRC/openSUSE:Factory/.ghc-bifunctors.new.3463/ghc-bifunctors.changes 2020-10-23 15:13:38.982114040 +0200 @@ -1,0 +2,12 @@ +Tue Oct 6 08:56:02 UTC 2020 - psim...@suse.com + +- Update bifunctors to version 5.5.8. + 5.5.8 [2020.10.01] + ------------------ + * Fix a bug in which `deriveBifunctor` would fail on sufficiently complex uses + of rank-n types in constructor fields. + * Fix a bug in which `deriveBiunctor` and related functions would needlessly + reject data types whose two last type parameters appear as oversaturated + arguments to a type family. + +------------------------------------------------------------------- Old: ---- bifunctors-5.5.7.tar.gz bifunctors.cabal New: ---- bifunctors-5.5.8.tar.gz ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ Other differences: ------------------ ++++++ ghc-bifunctors.spec ++++++ --- /var/tmp/diff_new_pack.U2D2DU/_old 2020-10-23 15:13:39.974114518 +0200 +++ /var/tmp/diff_new_pack.U2D2DU/_new 2020-10-23 15:13:39.978114520 +0200 @@ -19,13 +19,12 @@ %global pkg_name bifunctors %bcond_with tests Name: ghc-%{pkg_name} -Version: 5.5.7 +Version: 5.5.8 Release: 0 Summary: Collection Haskell 98 bifunctors, bifoldables and bitraversables License: BSD-2-Clause URL: https://hackage.haskell.org/package/%{pkg_name} Source0: https://hackage.haskell.org/package/%{pkg_name}-%{version}/%{pkg_name}-%{version}.tar.gz -Source1: https://hackage.haskell.org/package/%{pkg_name}-%{version}/revision/1.cabal#/%{pkg_name}.cabal BuildRequires: ghc-Cabal-devel BuildRequires: ghc-base-orphans-devel BuildRequires: ghc-comonad-devel @@ -56,7 +55,6 @@ %prep %autosetup -n %{pkg_name}-%{version} -cp -p %{SOURCE1} %{pkg_name}.cabal %build %ghc_lib_build ++++++ bifunctors-5.5.7.tar.gz -> bifunctors-5.5.8.tar.gz ++++++ diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/bifunctors-5.5.7/.travis.yml new/bifunctors-5.5.8/.travis.yml --- old/bifunctors-5.5.7/.travis.yml 2001-09-09 03:46:40.000000000 +0200 +++ new/bifunctors-5.5.8/.travis.yml 2001-09-09 03:46:40.000000000 +0200 @@ -2,9 +2,13 @@ # # haskell-ci '--output=.travis.yml' '--config=cabal.haskell-ci' 'cabal.project' # +# To regenerate the script (for example after adjusting tested-with) run +# +# haskell-ci regenerate +# # For more information, see https://github.com/haskell-CI/haskell-ci # -# version: 0.9.20191126 +# version: 0.10 # version: ~> 1.0 language: c @@ -19,7 +23,7 @@ - irc.freenode.org#haskell-lens skip_join: true template: - - "\"\\x0313bifunctors\\x03/\\x0306%{branch}\\x03 \\x0314%{commit}\\x03 %{build_url} %{message}\"" + - "\x0313bifunctors\x03/\x0306%{branch}\x03 \x0314%{commit}\x03 %{build_url} %{message}" cache: directories: - $HOME/.cabal/packages @@ -37,49 +41,44 @@ jobs: include: - compiler: ghc-8.10.1 - addons: {"apt":{"sources":[{"sourceline":"deb http://ppa.launchpad.net/hvr/ghc/ubuntu xenial main","key_url":"https://keyserver.ubuntu.com/pks/lookup?op=get&search=0x063dab2bdc0b3f9fcebc378bff3aeacef6f88286"}],"packages":["ghc-8.10.1","cabal-install-3.0"]}} + addons: {"apt":{"sources":[{"sourceline":"deb http://ppa.launchpad.net/hvr/ghc/ubuntu xenial main","key_url":"https://keyserver.ubuntu.com/pks/lookup?op=get&search=0x063dab2bdc0b3f9fcebc378bff3aeacef6f88286"}],"packages":["ghc-8.10.1","cabal-install-3.2"]}} os: linux - - compiler: ghc-8.8.1 - addons: {"apt":{"sources":[{"sourceline":"deb http://ppa.launchpad.net/hvr/ghc/ubuntu xenial main","key_url":"https://keyserver.ubuntu.com/pks/lookup?op=get&search=0x063dab2bdc0b3f9fcebc378bff3aeacef6f88286"}],"packages":["ghc-8.8.1","cabal-install-3.0"]}} + - compiler: ghc-8.8.3 + addons: {"apt":{"sources":[{"sourceline":"deb http://ppa.launchpad.net/hvr/ghc/ubuntu xenial main","key_url":"https://keyserver.ubuntu.com/pks/lookup?op=get&search=0x063dab2bdc0b3f9fcebc378bff3aeacef6f88286"}],"packages":["ghc-8.8.3","cabal-install-3.2"]}} os: linux - compiler: ghc-8.6.5 - addons: {"apt":{"sources":[{"sourceline":"deb http://ppa.launchpad.net/hvr/ghc/ubuntu xenial main","key_url":"https://keyserver.ubuntu.com/pks/lookup?op=get&search=0x063dab2bdc0b3f9fcebc378bff3aeacef6f88286"}],"packages":["ghc-8.6.5","cabal-install-3.0"]}} + addons: {"apt":{"sources":[{"sourceline":"deb http://ppa.launchpad.net/hvr/ghc/ubuntu xenial main","key_url":"https://keyserver.ubuntu.com/pks/lookup?op=get&search=0x063dab2bdc0b3f9fcebc378bff3aeacef6f88286"}],"packages":["ghc-8.6.5","cabal-install-3.2"]}} os: linux - compiler: ghc-8.4.4 - addons: {"apt":{"sources":[{"sourceline":"deb http://ppa.launchpad.net/hvr/ghc/ubuntu xenial main","key_url":"https://keyserver.ubuntu.com/pks/lookup?op=get&search=0x063dab2bdc0b3f9fcebc378bff3aeacef6f88286"}],"packages":["ghc-8.4.4","cabal-install-3.0"]}} + addons: {"apt":{"sources":[{"sourceline":"deb http://ppa.launchpad.net/hvr/ghc/ubuntu xenial main","key_url":"https://keyserver.ubuntu.com/pks/lookup?op=get&search=0x063dab2bdc0b3f9fcebc378bff3aeacef6f88286"}],"packages":["ghc-8.4.4","cabal-install-3.2"]}} os: linux - compiler: ghc-8.2.2 - addons: {"apt":{"sources":[{"sourceline":"deb http://ppa.launchpad.net/hvr/ghc/ubuntu xenial main","key_url":"https://keyserver.ubuntu.com/pks/lookup?op=get&search=0x063dab2bdc0b3f9fcebc378bff3aeacef6f88286"}],"packages":["ghc-8.2.2","cabal-install-3.0"]}} + addons: {"apt":{"sources":[{"sourceline":"deb http://ppa.launchpad.net/hvr/ghc/ubuntu xenial main","key_url":"https://keyserver.ubuntu.com/pks/lookup?op=get&search=0x063dab2bdc0b3f9fcebc378bff3aeacef6f88286"}],"packages":["ghc-8.2.2","cabal-install-3.2"]}} os: linux - compiler: ghc-8.0.2 - addons: {"apt":{"sources":[{"sourceline":"deb http://ppa.launchpad.net/hvr/ghc/ubuntu xenial main","key_url":"https://keyserver.ubuntu.com/pks/lookup?op=get&search=0x063dab2bdc0b3f9fcebc378bff3aeacef6f88286"}],"packages":["ghc-8.0.2","cabal-install-3.0"]}} + addons: {"apt":{"sources":[{"sourceline":"deb http://ppa.launchpad.net/hvr/ghc/ubuntu xenial main","key_url":"https://keyserver.ubuntu.com/pks/lookup?op=get&search=0x063dab2bdc0b3f9fcebc378bff3aeacef6f88286"}],"packages":["ghc-8.0.2","cabal-install-3.2"]}} os: linux - compiler: ghc-7.10.3 - addons: {"apt":{"sources":[{"sourceline":"deb http://ppa.launchpad.net/hvr/ghc/ubuntu xenial main","key_url":"https://keyserver.ubuntu.com/pks/lookup?op=get&search=0x063dab2bdc0b3f9fcebc378bff3aeacef6f88286"}],"packages":["ghc-7.10.3","cabal-install-3.0"]}} + addons: {"apt":{"sources":[{"sourceline":"deb http://ppa.launchpad.net/hvr/ghc/ubuntu xenial main","key_url":"https://keyserver.ubuntu.com/pks/lookup?op=get&search=0x063dab2bdc0b3f9fcebc378bff3aeacef6f88286"}],"packages":["ghc-7.10.3","cabal-install-3.2"]}} os: linux - compiler: ghc-7.8.4 - addons: {"apt":{"sources":[{"sourceline":"deb http://ppa.launchpad.net/hvr/ghc/ubuntu xenial main","key_url":"https://keyserver.ubuntu.com/pks/lookup?op=get&search=0x063dab2bdc0b3f9fcebc378bff3aeacef6f88286"}],"packages":["ghc-7.8.4","cabal-install-3.0"]}} + addons: {"apt":{"sources":[{"sourceline":"deb http://ppa.launchpad.net/hvr/ghc/ubuntu xenial main","key_url":"https://keyserver.ubuntu.com/pks/lookup?op=get&search=0x063dab2bdc0b3f9fcebc378bff3aeacef6f88286"}],"packages":["ghc-7.8.4","cabal-install-3.2"]}} os: linux - compiler: ghc-7.6.3 - addons: {"apt":{"sources":[{"sourceline":"deb http://ppa.launchpad.net/hvr/ghc/ubuntu xenial main","key_url":"https://keyserver.ubuntu.com/pks/lookup?op=get&search=0x063dab2bdc0b3f9fcebc378bff3aeacef6f88286"}],"packages":["ghc-7.6.3","cabal-install-3.0"]}} + addons: {"apt":{"sources":[{"sourceline":"deb http://ppa.launchpad.net/hvr/ghc/ubuntu xenial main","key_url":"https://keyserver.ubuntu.com/pks/lookup?op=get&search=0x063dab2bdc0b3f9fcebc378bff3aeacef6f88286"}],"packages":["ghc-7.6.3","cabal-install-3.2"]}} os: linux - compiler: ghc-7.4.2 - addons: {"apt":{"sources":[{"sourceline":"deb http://ppa.launchpad.net/hvr/ghc/ubuntu xenial main","key_url":"https://keyserver.ubuntu.com/pks/lookup?op=get&search=0x063dab2bdc0b3f9fcebc378bff3aeacef6f88286"}],"packages":["ghc-7.4.2","cabal-install-3.0"]}} + addons: {"apt":{"sources":[{"sourceline":"deb http://ppa.launchpad.net/hvr/ghc/ubuntu xenial main","key_url":"https://keyserver.ubuntu.com/pks/lookup?op=get&search=0x063dab2bdc0b3f9fcebc378bff3aeacef6f88286"}],"packages":["ghc-7.4.2","cabal-install-3.2"]}} os: linux - compiler: ghc-7.2.2 - addons: {"apt":{"sources":[{"sourceline":"deb http://ppa.launchpad.net/hvr/ghc/ubuntu xenial main","key_url":"https://keyserver.ubuntu.com/pks/lookup?op=get&search=0x063dab2bdc0b3f9fcebc378bff3aeacef6f88286"}],"packages":["ghc-7.2.2","cabal-install-3.0"]}} + addons: {"apt":{"sources":[{"sourceline":"deb http://ppa.launchpad.net/hvr/ghc/ubuntu xenial main","key_url":"https://keyserver.ubuntu.com/pks/lookup?op=get&search=0x063dab2bdc0b3f9fcebc378bff3aeacef6f88286"}],"packages":["ghc-7.2.2","cabal-install-3.2"]}} os: linux - compiler: ghc-7.0.4 - addons: {"apt":{"sources":[{"sourceline":"deb http://ppa.launchpad.net/hvr/ghc/ubuntu xenial main","key_url":"https://keyserver.ubuntu.com/pks/lookup?op=get&search=0x063dab2bdc0b3f9fcebc378bff3aeacef6f88286"}],"packages":["ghc-7.0.4","cabal-install-3.0"]}} - os: linux - - compiler: ghc-head - addons: {"apt":{"sources":[{"sourceline":"deb http://ppa.launchpad.net/hvr/ghc/ubuntu xenial main","key_url":"https://keyserver.ubuntu.com/pks/lookup?op=get&search=0x063dab2bdc0b3f9fcebc378bff3aeacef6f88286"}],"packages":["ghc-head","cabal-install-head"]}} + addons: {"apt":{"sources":[{"sourceline":"deb http://ppa.launchpad.net/hvr/ghc/ubuntu xenial main","key_url":"https://keyserver.ubuntu.com/pks/lookup?op=get&search=0x063dab2bdc0b3f9fcebc378bff3aeacef6f88286"}],"packages":["ghc-7.0.4","cabal-install-3.2"]}} os: linux allow_failures: - - compiler: ghc-head - compiler: ghc-7.0.4 - compiler: ghc-7.2.2 - - compiler: ghc-8.10.1 before_install: - HC=$(echo "/opt/$CC/bin/ghc" | sed 's/-/\//') - WITHCOMPILER="-w $HC" @@ -92,69 +91,31 @@ - TOP=$(pwd) - "HCNUMVER=$(${HC} --numeric-version|perl -ne '/^(\\d+)\\.(\\d+)\\.(\\d+)(\\.(\\d+))?$/; print(10000 * $1 + 100 * $2 + ($3 == 0 ? $5 != 1 : $3))')" - echo $HCNUMVER - - CABAL="$CABAL -vnormal+nowrap+markoutput" + - CABAL="$CABAL -vnormal+nowrap" - set -o pipefail - - | - echo 'function blue(s) { printf "\033[0;34m" s "\033[0m " }' >> .colorful.awk - echo 'BEGIN { state = "output"; }' >> .colorful.awk - echo '/^-----BEGIN CABAL OUTPUT-----$/ { state = "cabal" }' >> .colorful.awk - echo '/^-----END CABAL OUTPUT-----$/ { state = "output" }' >> .colorful.awk - echo '!/^(-----BEGIN CABAL OUTPUT-----|-----END CABAL OUTPUT-----)/ {' >> .colorful.awk - echo ' if (state == "cabal") {' >> .colorful.awk - echo ' print blue($0)' >> .colorful.awk - echo ' } else {' >> .colorful.awk - echo ' print $0' >> .colorful.awk - echo ' }' >> .colorful.awk - echo '}' >> .colorful.awk - - cat .colorful.awk - - | - color_cabal_output () { - awk -f $TOP/.colorful.awk - } - - echo text | color_cabal_output -install: - - ${CABAL} --version - - echo "$(${HC} --version) [$(${HC} --print-project-git-commit-id 2> /dev/null || echo '?')]" - TEST=--enable-tests - BENCH=--enable-benchmarks - HEADHACKAGE=false - - if [ $HCNUMVER -ge 81000 ] ; then HEADHACKAGE=true ; fi - rm -f $CABALHOME/config - | - echo "verbose: normal +nowrap +markoutput" >> $CABALHOME/config - echo "remote-build-reporting: anonymous" >> $CABALHOME/config - echo "write-ghc-environment-files: always" >> $CABALHOME/config - echo "remote-repo-cache: $CABALHOME/packages" >> $CABALHOME/config - echo "logs-dir: $CABALHOME/logs" >> $CABALHOME/config - echo "world-file: $CABALHOME/world" >> $CABALHOME/config - echo "extra-prog-path: $CABALHOME/bin" >> $CABALHOME/config - echo "symlink-bindir: $CABALHOME/bin" >> $CABALHOME/config - echo "installdir: $CABALHOME/bin" >> $CABALHOME/config - echo "build-summary: $CABALHOME/logs/build.log" >> $CABALHOME/config - echo "store-dir: $CABALHOME/store" >> $CABALHOME/config - echo "install-dirs user" >> $CABALHOME/config - echo " prefix: $CABALHOME" >> $CABALHOME/config - echo "repository hackage.haskell.org" >> $CABALHOME/config - echo " url: http://hackage.haskell.org/" >> $CABALHOME/config - echo " secure: True" >> $CABALHOME/config - echo " key-threshold: 3" >> $CABALHOME/config - echo " root-keys:" >> $CABALHOME/config - echo " fe331502606802feac15e514d9b9ea83fee8b6ffef71335479a2e68d84adc6b0" >> $CABALHOME/config - echo " 1ea9ba32c526d1cc91ab5e5bd364ec5e9e8cb67179a471872f6e26f0ae773d42" >> $CABALHOME/config - echo " 2c6c3627bd6c982990239487f1abd02e08a02e6cf16edb105a8012d444d870c3" >> $CABALHOME/config - echo " 0a5c7ea47cd1b15f01f5f51a33adda7e655bc0f0b0615baa8e271f4c3351e21d" >> $CABALHOME/config - echo " 51f0161b906011b52c6613376b1ae937670da69322113a246a09f807c62f6921" >> $CABALHOME/config - - | - if $HEADHACKAGE; then - echo "allow-newer: $($HCPKG list --simple-output | sed -E 's/([a-zA-Z-]+)-[0-9.]+/*:\1/g')" >> $CABALHOME/config - echo "repository head.hackage.ghc.haskell.org" >> $CABALHOME/config - echo " url: https://ghc.gitlab.haskell.org/head.hackage/" >> $CABALHOME/config - echo " secure: True" >> $CABALHOME/config - echo " root-keys: 7541f32a4ccca4f97aea3b22f5e593ba2c0267546016b992dfadcd2fe944e55d" >> $CABALHOME/config - echo " 26021a13b401500c8eb2761ca95c61f2d625bfef951b939a8124ed12ecf07329" >> $CABALHOME/config - echo " f76d08be13e9a61a377a85e2fb63f4c5435d40f8feb3e12eb05905edb8cdea89" >> $CABALHOME/config - echo " key-threshold: 3" >> $CABALHOME/config - fi + echo "verbose: normal +nowrap +markoutput" >> $CABALHOME/config + echo "remote-build-reporting: anonymous" >> $CABALHOME/config + echo "write-ghc-environment-files: always" >> $CABALHOME/config + echo "remote-repo-cache: $CABALHOME/packages" >> $CABALHOME/config + echo "logs-dir: $CABALHOME/logs" >> $CABALHOME/config + echo "world-file: $CABALHOME/world" >> $CABALHOME/config + echo "extra-prog-path: $CABALHOME/bin" >> $CABALHOME/config + echo "symlink-bindir: $CABALHOME/bin" >> $CABALHOME/config + echo "installdir: $CABALHOME/bin" >> $CABALHOME/config + echo "build-summary: $CABALHOME/logs/build.log" >> $CABALHOME/config + echo "store-dir: $CABALHOME/store" >> $CABALHOME/config + echo "install-dirs user" >> $CABALHOME/config + echo " prefix: $CABALHOME" >> $CABALHOME/config + echo "repository hackage.haskell.org" >> $CABALHOME/config + echo " url: http://hackage.haskell.org/" >> $CABALHOME/config +install: + - ${CABAL} --version + - echo "$(${HC} --version) [$(${HC} --print-project-git-commit-id 2> /dev/null || echo '?')]" - | echo "program-default-options" >> $CABALHOME/config echo " ghc-options: $GHCJOBS +RTS -M6G -RTS" >> $CABALHOME/config @@ -166,19 +127,21 @@ - touch cabal.project - | echo "packages: ." >> cabal.project + - if [ $HCNUMVER -ge 80200 ] ; then echo 'package bifunctors' >> cabal.project ; fi + - "if [ $HCNUMVER -ge 80200 ] ; then echo ' ghc-options: -Werror=missing-methods' >> cabal.project ; fi" - | - "for pkg in $($HCPKG list --simple-output); do echo $pkg | sed 's/-[^-]*$//' | (grep -vE -- '^(bifunctors)$' || true) | sed 's/^/constraints: /' | sed 's/$/ installed/' >> cabal.project.local; done" - cat cabal.project || true - cat cabal.project.local || true - if [ -f "./configure.ac" ]; then (cd "." && autoreconf -i); fi - - ${CABAL} v2-freeze $WITHCOMPILER ${TEST} ${BENCH} | color_cabal_output + - ${CABAL} v2-freeze $WITHCOMPILER ${TEST} ${BENCH} - "cat cabal.project.freeze | sed -E 's/^(constraints: *| *)//' | sed 's/any.//'" - rm cabal.project.freeze - - ${CABAL} v2-build $WITHCOMPILER ${TEST} ${BENCH} --dep -j2 all | color_cabal_output + - travis_wait 40 ${CABAL} v2-build $WITHCOMPILER ${TEST} ${BENCH} --dep -j2 all script: - DISTDIR=$(mktemp -d /tmp/dist-test.XXXX) # Packaging... - - ${CABAL} v2-sdist all | color_cabal_output + - ${CABAL} v2-sdist all # Unpacking... - mv dist-newstyle/sdist/*.tar.gz ${DISTDIR}/ - cd ${DISTDIR} || false @@ -190,19 +153,21 @@ - touch cabal.project - | echo "packages: ${PKGDIR_bifunctors}" >> cabal.project + - if [ $HCNUMVER -ge 80200 ] ; then echo 'package bifunctors' >> cabal.project ; fi + - "if [ $HCNUMVER -ge 80200 ] ; then echo ' ghc-options: -Werror=missing-methods' >> cabal.project ; fi" - | - "for pkg in $($HCPKG list --simple-output); do echo $pkg | sed 's/-[^-]*$//' | (grep -vE -- '^(bifunctors)$' || true) | sed 's/^/constraints: /' | sed 's/$/ installed/' >> cabal.project.local; done" - cat cabal.project || true - cat cabal.project.local || true # Building with tests and benchmarks... # build & run tests, build benchmarks - - ${CABAL} v2-build $WITHCOMPILER ${TEST} ${BENCH} all | color_cabal_output + - ${CABAL} v2-build $WITHCOMPILER ${TEST} ${BENCH} all # Testing... - - ${CABAL} v2-test $WITHCOMPILER ${TEST} ${BENCH} all | color_cabal_output + - ${CABAL} v2-test $WITHCOMPILER ${TEST} ${BENCH} all # cabal check... - (cd ${PKGDIR_bifunctors} && ${CABAL} -vnormal check) # haddock... - - ${CABAL} v2-haddock $WITHCOMPILER --with-haddock $HADDOCK ${TEST} ${BENCH} all | color_cabal_output + - ${CABAL} v2-haddock $WITHCOMPILER --with-haddock $HADDOCK ${TEST} ${BENCH} all -# REGENDATA ("0.9.20191126",["--output=.travis.yml","--config=cabal.haskell-ci","cabal.project"]) +# REGENDATA ("0.10",["--output=.travis.yml","--config=cabal.haskell-ci","cabal.project"]) # EOF diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/bifunctors-5.5.7/CHANGELOG.markdown new/bifunctors-5.5.8/CHANGELOG.markdown --- old/bifunctors-5.5.7/CHANGELOG.markdown 2001-09-09 03:46:40.000000000 +0200 +++ new/bifunctors-5.5.8/CHANGELOG.markdown 2001-09-09 03:46:40.000000000 +0200 @@ -1,3 +1,11 @@ +5.5.8 [2020.10.01] +------------------ +* Fix a bug in which `deriveBifunctor` would fail on sufficiently complex uses + of rank-n types in constructor fields. +* Fix a bug in which `deriveBiunctor` and related functions would needlessly + reject data types whose two last type parameters appear as oversaturated + arguments to a type family. + 5.5.7 [2020.01.29] ------------------ * Add `Data.Bifunctor.Biap`. diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/bifunctors-5.5.7/bifunctors.cabal new/bifunctors-5.5.8/bifunctors.cabal --- old/bifunctors-5.5.7/bifunctors.cabal 2001-09-09 03:46:40.000000000 +0200 +++ new/bifunctors-5.5.8/bifunctors.cabal 2001-09-09 03:46:40.000000000 +0200 @@ -1,8 +1,8 @@ name: bifunctors category: Data, Functors -version: 5.5.7 +version: 5.5.8 license: BSD3 -cabal-version: >= 1.8 +cabal-version: >= 1.10 license-file: LICENSE author: Edward A. Kmett maintainer: Edward A. Kmett <ekm...@gmail.com> @@ -23,7 +23,7 @@ , GHC == 8.2.2 , GHC == 8.4.4 , GHC == 8.6.5 - , GHC == 8.8.1 + , GHC == 8.8.3 , GHC == 8.10.1 extra-source-files: .travis.yml @@ -60,8 +60,8 @@ base-orphans >= 0.5.2 && < 1, comonad >= 4 && < 6, containers >= 0.1 && < 0.7, - template-haskell >= 2.4 && < 2.17, - th-abstraction >= 0.3 && < 0.4, + template-haskell >= 2.4 && < 2.18, + th-abstraction >= 0.4 && < 0.5, transformers >= 0.2 && < 0.6 if !impl(ghc > 8.2) @@ -74,7 +74,7 @@ build-depends: tagged >= 0.7.3 && < 1 if flag(semigroups) && !impl(ghc >= 8.0) - build-depends: semigroups >= 0.8.3.1 && < 1 + build-depends: semigroups >= 0.16.2 && < 1 if impl(ghc<7.9) hs-source-dirs: old-src/ghc709 @@ -110,6 +110,7 @@ Paths_bifunctors ghc-options: -Wall + default-language: Haskell2010 test-suite bifunctors-spec @@ -118,6 +119,9 @@ main-is: Spec.hs other-modules: BifunctorSpec ghc-options: -Wall + if impl(ghc >= 8.6) + ghc-options: -Wno-star-is-type + default-language: Haskell2010 build-tool-depends: hspec-discover:hspec-discover >= 1.8 build-depends: base >= 4 && < 5, diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/bifunctors-5.5.7/old-src/ghc709/Data/Bifunctor.hs new/bifunctors-5.5.8/old-src/ghc709/Data/Bifunctor.hs --- old/bifunctors-5.5.7/old-src/ghc709/Data/Bifunctor.hs 2001-09-09 03:46:40.000000000 +0200 +++ new/bifunctors-5.5.8/old-src/ghc709/Data/Bifunctor.hs 2001-09-09 03:46:40.000000000 +0200 @@ -8,9 +8,6 @@ {-# LANGUAGE Trustworthy #-} #endif -#ifndef MIN_VERSION_semigroups -#define MIN_VERSION_semigroups(x,y,z) 0 -#endif ----------------------------------------------------------------------------- -- | -- Copyright : (C) 2008-2015 Edward Kmett @@ -33,10 +30,7 @@ import Control.Applicative import Data.Functor.Constant - -#if MIN_VERSION_semigroups(0,16,2) import Data.Semigroup -#endif #ifdef MIN_VERSION_tagged import Data.Tagged @@ -116,10 +110,8 @@ bimap f g ~(a, b) = (f a, g b) {-# INLINE bimap #-} -#if MIN_VERSION_semigroups(0,16,2) instance Bifunctor Arg where bimap f g (Arg a b) = Arg (f a) (g b) -#endif instance Bifunctor ((,,) x) where bimap f g ~(x, a, b) = (x, f a, g b) diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/bifunctors-5.5.7/old-src/ghc801/Data/Bifoldable.hs new/bifunctors-5.5.8/old-src/ghc801/Data/Bifoldable.hs --- old/bifunctors-5.5.7/old-src/ghc801/Data/Bifoldable.hs 2001-09-09 03:46:40.000000000 +0200 +++ new/bifunctors-5.5.8/old-src/ghc801/Data/Bifoldable.hs 2001-09-09 03:46:40.000000000 +0200 @@ -7,9 +7,6 @@ {-# LANGUAGE Trustworthy #-} #endif -#ifndef MIN_VERSION_semigroups -#define MIN_VERSION_semigroups(x,y,z) 0 -#endif ----------------------------------------------------------------------------- -- | -- Copyright : (C) 2011-2015 Edward Kmett @@ -68,9 +65,7 @@ import Unsafe.Coerce #endif -#if MIN_VERSION_base(4,9,0) || MIN_VERSION_semigroups(0,16,2) import Data.Semigroup (Arg(..)) -#endif #ifdef MIN_VERSION_tagged import Data.Tagged @@ -159,10 +154,8 @@ deriving instance Typeable Bifoldable #endif -#if MIN_VERSION_base(4,9,0) || MIN_VERSION_semigroups(0,16,2) instance Bifoldable Arg where bifoldMap f g (Arg a b) = f a `mappend` g b -#endif instance Bifoldable (,) where bifoldMap f g ~(a, b) = f a `mappend` g b diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/bifunctors-5.5.7/old-src/ghc801/Data/Bitraversable.hs new/bifunctors-5.5.8/old-src/ghc801/Data/Bitraversable.hs --- old/bifunctors-5.5.7/old-src/ghc801/Data/Bitraversable.hs 2001-09-09 03:46:40.000000000 +0200 +++ new/bifunctors-5.5.8/old-src/ghc801/Data/Bitraversable.hs 2001-09-09 03:46:40.000000000 +0200 @@ -7,9 +7,6 @@ {-# LANGUAGE Trustworthy #-} #endif -#ifndef MIN_VERSION_semigroups -#define MIN_VERSION_semigroups(x,y,z) 0 -#endif ----------------------------------------------------------------------------- -- | -- Copyright : (C) 2011-2015 Edward Kmett @@ -51,9 +48,7 @@ import Data.Monoid #endif -#if MIN_VERSION_base(4,9,0) || MIN_VERSION_semigroups(0,16,2) import Data.Semigroup (Arg(..)) -#endif #ifdef MIN_VERSION_tagged import Data.Tagged @@ -185,10 +180,8 @@ deriving instance Typeable Bitraversable #endif -#if MIN_VERSION_base(4,9,0) || MIN_VERSION_semigroups(0,16,2) instance Bitraversable Arg where bitraverse f g (Arg a b) = Arg <$> f a <*> g b -#endif instance Bitraversable (,) where bitraverse f g ~(a, b) = (,) <$> f a <*> g b diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/bifunctors-5.5.7/src/Data/Biapplicative.hs new/bifunctors-5.5.8/src/Data/Biapplicative.hs --- old/bifunctors-5.5.7/src/Data/Biapplicative.hs 2001-09-09 03:46:40.000000000 +0200 +++ new/bifunctors-5.5.8/src/Data/Biapplicative.hs 2001-09-09 03:46:40.000000000 +0200 @@ -7,9 +7,6 @@ {-# LANGUAGE Trustworthy #-} #endif -#ifndef MIN_VERSION_semigroups -#define MIN_VERSION_semigroups(x,y,z) 0 -#endif ----------------------------------------------------------------------------- -- | -- Copyright : (C) 2011-2015 Edward Kmett @@ -42,9 +39,7 @@ import Data.Traversable (Traversable (traverse)) #endif -#if MIN_VERSION_base(4,9,0) || MIN_VERSION_semigroups(0,16,2) import Data.Semigroup (Arg(..)) -#endif #ifdef MIN_VERSION_tagged import Data.Tagged @@ -178,7 +173,7 @@ go (Map f x) (Map g y) = bimap f g (go x y) go (Ap fs xs) (Ap gs ys) = go fs gs <<*>> go xs ys #if MIN_VERSION_base(4,10,0) - go (LiftA2 f xs ys) (LiftA2 g zs ws) = bimap f g (go xs zs) <<*>> go ys ws + go (LiftA2 f xs ys) (LiftA2 g zs ws) = biliftA2 f g (go xs zs) (go ys ws) #endif go (One x) (One _) = p x go _ _ = impossibleError @@ -278,7 +273,6 @@ biliftA2 f g (x, y) (a, b) = (f x a, g y b) {-# INLINE biliftA2 #-} -#if MIN_VERSION_base(4,9,0) || MIN_VERSION_semigroups(0,16,2) instance Biapplicative Arg where bipure = Arg {-# INLINE bipure #-} @@ -286,7 +280,6 @@ {-# INLINE (<<*>>) #-} biliftA2 f g (Arg x y) (Arg a b) = Arg (f x a) (g y b) {-# INLINE biliftA2 #-} -#endif instance Monoid x => Biapplicative ((,,) x) where bipure = (,,) mempty diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/bifunctors-5.5.7/src/Data/Bifunctor/Biap.hs new/bifunctors-5.5.8/src/Data/Bifunctor/Biap.hs --- old/bifunctors-5.5.7/src/Data/Bifunctor/Biap.hs 2001-09-09 03:46:40.000000000 +0200 +++ new/bifunctors-5.5.8/src/Data/Bifunctor/Biap.hs 2001-09-09 03:46:40.000000000 +0200 @@ -11,9 +11,6 @@ #endif #include "bifunctors-common.h" -#ifndef MIN_VERSION_semigroups -#define MIN_VERSION_semigroups(x,y,z) 0 -#endif ----------------------------------------------------------------------------- -- | @@ -47,9 +44,7 @@ import Data.Traversable #endif -#if MIN_VERSION_base(4,9,0) || MIN_VERSION_semigroups(0,16,2) import qualified Data.Semigroup as S -#endif -- | Pointwise lifting of a class over two arguments, using -- 'Biapplicative'. diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/bifunctors-5.5.7/src/Data/Bifunctor/TH/Internal.hs new/bifunctors-5.5.8/src/Data/Bifunctor/TH/Internal.hs --- old/bifunctors-5.5.7/src/Data/Bifunctor/TH/Internal.hs 2001-09-09 03:46:40.000000000 +0200 +++ new/bifunctors-5.5.8/src/Data/Bifunctor/TH/Internal.hs 2001-09-09 03:46:40.000000000 +0200 @@ -15,7 +15,6 @@ -} module Data.Bifunctor.TH.Internal where -import Data.Bifunctor (bimap) import Data.Foldable (foldr') import Data.List import qualified Data.Map as Map (singleton) @@ -110,21 +109,6 @@ -- Assorted utilities ------------------------------------------------------------------------------- --- isRight and fromEither taken from the extra package (BSD3-licensed) - --- | Test if an 'Either' value is the 'Right' constructor. --- Provided as standard with GHC 7.8 and above. -isRight :: Either l r -> Bool -isRight Right{} = True; isRight _ = False - --- | Pull the value out of an 'Either' where both alternatives --- have the same type. --- --- > \x -> fromEither (Left x ) == x --- > \x -> fromEither (Right x) == x -fromEither :: Either a a -> a -fromEither = either id id - -- filterByList, filterByLists, and partitionByList taken from GHC (BSD3-licensed) -- | 'filterByList' takes a list of Bools and a list of some elements and @@ -166,15 +150,6 @@ go trues falses (False : bs) (x : xs) = go trues (x:falses) bs xs go trues falses _ _ = (reverse trues, reverse falses) --- | Apply an @Either Exp Exp@ expression to an 'Exp' expression, --- preserving the 'Either'-ness. -appEitherE :: Q (Either Exp Exp) -> Q Exp -> Q (Either Exp Exp) -appEitherE e1Q e2Q = do - e2 <- e2Q - let e2' :: Exp -> Exp - e2' = (`AppE` e2) - bimap e2' e2' `fmap` e1Q - -- | Returns True if a Type has kind *. hasKindStar :: Type -> Bool hasKindStar VarT{} = True @@ -276,23 +251,52 @@ isTyVar (SigT t _) = isTyVar t isTyVar _ = False --- | Is the given type a type family constructor (and not a data family constructor)? -isTyFamily :: Type -> Q Bool -isTyFamily (ConT n) = do - info <- reify n - return $ case info of +-- | Detect if a Name in a list of provided Names occurs as an argument to some +-- type family. This makes an effort to exclude /oversaturated/ arguments to +-- type families. For instance, if one declared the following type family: +-- +-- @ +-- type family F a :: Type -> Type +-- @ +-- +-- Then in the type @F a b@, we would consider @a@ to be an argument to @F@, +-- but not @b@. +isInTypeFamilyApp :: [Name] -> Type -> [Type] -> Q Bool +isInTypeFamilyApp names tyFun tyArgs = + case tyFun of + ConT tcName -> go tcName + _ -> return False + where + go :: Name -> Q Bool + go tcName = do + info <- reify tcName + case info of #if MIN_VERSION_template_haskell(2,11,0) - FamilyI OpenTypeFamilyD{} _ -> True + FamilyI (OpenTypeFamilyD (TypeFamilyHead _ bndrs _ _)) _ + -> withinFirstArgs bndrs #elif MIN_VERSION_template_haskell(2,7,0) - FamilyI (FamilyD TypeFam _ _ _) _ -> True + FamilyI (FamilyD TypeFam _ bndrs _) _ + -> withinFirstArgs bndrs #else - TyConI (FamilyD TypeFam _ _ _) -> True + TyConI (FamilyD TypeFam _ bndrs _) + -> withinFirstArgs bndrs #endif -#if MIN_VERSION_template_haskell(2,9,0) - FamilyI ClosedTypeFamilyD{} _ -> True + +#if MIN_VERSION_template_haskell(2,11,0) + FamilyI (ClosedTypeFamilyD (TypeFamilyHead _ bndrs _ _) _) _ + -> withinFirstArgs bndrs +#elif MIN_VERSION_template_haskell(2,9,0) + FamilyI (ClosedTypeFamilyD _ bndrs _ _) _ + -> withinFirstArgs bndrs #endif - _ -> False -isTyFamily _ = return False + + _ -> return False + where + withinFirstArgs :: [a] -> Q Bool + withinFirstArgs bndrs = + let firstArgs = take (length bndrs) tyArgs + argFVs = freeVariables firstArgs + in return $ any (`elem` argFVs) names -- | Are all of the items in a list (which have an ordering) distinct? -- @@ -347,14 +351,17 @@ -- @ -- [Either, Int, Char] -- @ -unapplyTy :: Type -> [Type] -unapplyTy = reverse . go +unapplyTy :: Type -> (Type, [Type]) +unapplyTy ty = go ty ty [] where - go :: Type -> [Type] - go (AppT t1 t2) = t2:go t1 - go (SigT t _) = go t - go (ForallT _ _ t) = go t - go t = [t] + go :: Type -> Type -> [Type] -> (Type, [Type]) + go _ (AppT ty1 ty2) args = go ty1 ty1 (ty2:args) + go origTy (SigT ty' _) args = go origTy ty' args +#if MIN_VERSION_template_haskell(2,11,0) + go origTy (InfixT ty1 n ty2) args = go origTy (ConT n `AppT` ty1 `AppT` ty2) args + go origTy (ParensT ty') args = go origTy ty' args +#endif + go origTy _ args = (origTy, args) -- | Split a type signature by the arrows on its spine. For example, this: -- @@ -464,11 +471,6 @@ unwrapMonadValName :: Name unwrapMonadValName = mkNameG_v "base" "Control.Applicative" "unwrapMonad" -#if MIN_VERSION_base(4,6,0) && !(MIN_VERSION_base(4,9,0)) -starKindName :: Name -starKindName = mkNameG_tc "ghc-prim" "GHC.Prim" "*" -#endif - #if MIN_VERSION_base(4,8,0) bifunctorTypeName :: Name bifunctorTypeName = mkNameG_tc "base" "Data.Bifunctor" "Bifunctor" diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/bifunctors-5.5.7/src/Data/Bifunctor/TH.hs new/bifunctors-5.5.8/src/Data/Bifunctor/TH.hs --- old/bifunctors-5.5.7/src/Data/Bifunctor/TH.hs 2001-09-09 03:46:40.000000000 +0200 +++ new/bifunctors-5.5.8/src/Data/Bifunctor/TH.hs 2001-09-09 03:46:40.000000000 +0200 @@ -1,6 +1,7 @@ {-# LANGUAGE CPP #-} -{-# LANGUAGE PatternGuards #-} {-# LANGUAGE BangPatterns #-} +{-# LANGUAGE PatternGuards #-} +{-# LANGUAGE ScopedTypeVariables #-} #if __GLASGOW_HASKELL__ >= 704 {-# LANGUAGE Unsafe #-} @@ -61,15 +62,15 @@ , defaultOptions ) where -import Control.Monad (guard, unless, when, zipWithM) +import Control.Monad (guard, unless, when) import Data.Bifunctor.TH.Internal -import Data.Either (rights) import Data.List -import qualified Data.Map as Map (fromList, keys, lookup, size) +import qualified Data.Map as Map ((!), fromList, keys, lookup, member, size) import Data.Maybe import Language.Haskell.TH.Datatype +import Language.Haskell.TH.Datatype.TyVarBndr import Language.Haskell.TH.Lib import Language.Haskell.TH.Ppr import Language.Haskell.TH.Syntax @@ -400,15 +401,15 @@ -- All constructors must be from the same type. makeBiFunForCons :: BiFun -> Options -> Name -> [Type] -> [ConstructorInfo] -> Q Exp makeBiFunForCons biFun opts _parentName instTys cons = do - argNames <- mapM newName $ catMaybes [ Just "f" - , Just "g" - , guard (biFun == Bifoldr) >> Just "z" - , Just "value" - ] - let ([map1, map2], others) = splitAt 2 argNames - z = head others -- If we're deriving bifoldr, this will be well defined - -- and useful. Otherwise, it'll be ignored. - value = last others + map1 <- newName "f" + map2 <- newName "g" + z <- newName "z" -- Only used for deriving bifoldr + value <- newName "value" + let argNames = catMaybes [ Just map1 + , Just map2 + , guard (biFun == Bifoldr) >> Just z + , Just value + ] lastTyVars = map varTToName $ drop (length instTys - 2) instTys tvMap = Map.fromList $ zip lastTyVars [map1, map2] lamE (map varP argNames) @@ -459,140 +460,178 @@ coerce = varE coerceValName `appE` varE value #endif --- | Generates a lambda expression for a single constructor. +-- | Generates a match for a single constructor. makeBiFunForCon :: BiFun -> Name -> TyVarMap -> ConstructorInfo -> Q Match makeBiFunForCon biFun z tvMap - (ConstructorInfo { constructorName = conName - , constructorContext = ctxt - , constructorFields = ts }) = do - ts' <- mapM resolveTypeSynonyms ts - argNames <- newNameList "_arg" $ length ts' - if (any (`predMentionsName` Map.keys tvMap) ctxt - || Map.size tvMap < 2) - && not (allowExQuant (biFunToClass biFun)) - then existentialContextError conName - else makeBiFunForArgs biFun z tvMap conName ts' argNames - --- | Generates a lambda expression for a single constructor's arguments. -makeBiFunForArgs :: BiFun - -> Name - -> TyVarMap - -> Name - -> [Type] - -> [Name] - -> Q Match -makeBiFunForArgs biFun z tvMap conName tys args = - match (conP conName $ map varP args) - (normalB $ biFunCombine biFun conName z args mappedArgs) - [] + con@(ConstructorInfo { constructorName = conName + , constructorContext = ctxt }) = do + when ((any (`predMentionsName` Map.keys tvMap) ctxt + || Map.size tvMap < 2) + && not (allowExQuant (biFunToClass biFun))) $ + existentialContextError conName + case biFun of + Bimap -> makeBimapMatch tvMap con + Bifoldr -> makeBifoldrMatch z tvMap con + BifoldMap -> makeBifoldMapMatch tvMap con + Bitraverse -> makeBitraverseMatch tvMap con + +-- | Generates a match whose right-hand side implements @bimap@. +makeBimapMatch :: TyVarMap -> ConstructorInfo -> Q Match +makeBimapMatch tvMap con@(ConstructorInfo{constructorName = conName}) = do + parts <- foldDataConArgs tvMap ft_bimap con + match_for_con conName parts + where + ft_bimap :: FFoldType (Exp -> Q Exp) + ft_bimap = FT { ft_triv = return + , ft_var = \v x -> return $ VarE (tvMap Map.! v) `AppE` x + , ft_fun = \g h x -> mkSimpleLam $ \b -> do + gg <- g b + h $ x `AppE` gg + , ft_tup = mkSimpleTupleCase match_for_con + , ft_ty_app = \argGs x -> do + let inspect :: (Type, Exp -> Q Exp) -> Q Exp + inspect (argTy, g) + -- If the argument type is a bare occurrence of one + -- of the data type's last type variables, then we + -- can generate more efficient code. + -- This was inspired by GHC#17880. + | Just argVar <- varTToName_maybe argTy + , Just f <- Map.lookup argVar tvMap + = return $ VarE f + | otherwise + = mkSimpleLam g + appsE $ varE (fmapArity (length argGs)) + : map inspect argGs + ++ [return x] + , ft_forall = \_ g x -> g x + , ft_bad_app = \_ -> outOfPlaceTyVarError conName + , ft_co_var = \_ _ -> contravarianceError conName + } + + -- Con a1 a2 ... -> Con (f1 a1) (f2 a2) ... + match_for_con :: Name -> [Exp -> Q Exp] -> Q Match + match_for_con = mkSimpleConMatch $ \conName' xs -> + appsE (conE conName':xs) -- Con x1 x2 .. + +-- | Generates a match whose right-hand side implements @bifoldr@. +makeBifoldrMatch :: Name -> TyVarMap -> ConstructorInfo -> Q Match +makeBifoldrMatch z tvMap con@(ConstructorInfo{constructorName = conName}) = do + parts <- foldDataConArgs tvMap ft_bifoldr con + parts' <- sequence parts + match_for_con (VarE z) conName parts' where - mappedArgs :: Q [Either Exp Exp] - mappedArgs = zipWithM (makeBiFunForArg biFun tvMap conName) tys args + -- The Bool is True if the type mentions of the last two type parameters, + -- False otherwise. Later, match_for_con uses mkSimpleConMatch2 to filter + -- out expressions that do not mention the last parameters by checking for + -- False. + ft_bifoldr :: FFoldType (Q (Bool, Exp)) + ft_bifoldr = FT { -- See Note [ft_triv for Bifoldable and Bitraversable] + ft_triv = do lam <- mkSimpleLam2 $ \_ z' -> return z' + return (False, lam) + , ft_var = \v -> return (True, VarE $ tvMap Map.! v) + , ft_tup = \t gs -> do + gg <- sequence gs + lam <- mkSimpleLam2 $ \x z' -> + mkSimpleTupleCase (match_for_con z') t gg x + return (True, lam) + , ft_ty_app = \gs -> do + lam <- mkSimpleLam2 $ \x z' -> + appsE $ varE (foldrArity (length gs)) + : map (\(_, hs) -> fmap snd hs) gs + ++ map return [z', x] + return (True, lam) + , ft_forall = \_ g -> g + , ft_co_var = \_ -> contravarianceError conName + , ft_fun = \_ _ -> noFunctionsError conName + , ft_bad_app = outOfPlaceTyVarError conName + } --- | Generates a lambda expression for a single argument of a constructor. --- The returned value is 'Right' if its type mentions one of the last two type --- parameters. Otherwise, it is 'Left'. -makeBiFunForArg :: BiFun - -> TyVarMap - -> Name - -> Type - -> Name - -> Q (Either Exp Exp) -makeBiFunForArg biFun tvMap conName ty tyExpName = - makeBiFunForType biFun tvMap conName True ty `appEitherE` varE tyExpName - --- | Generates a lambda expression for a specific type. The returned value is --- 'Right' if its type mentions one of the last two type parameters. Otherwise, --- it is 'Left'. -makeBiFunForType :: BiFun - -> TyVarMap - -> Name - -> Bool - -> Type - -> Q (Either Exp Exp) -makeBiFunForType biFun tvMap conName covariant (VarT tyName) = - case Map.lookup tyName tvMap of - Just mapName -> fmap Right . varE $ - if covariant - then mapName - else contravarianceError conName - Nothing -> fmap Left $ biFunTriv biFun -makeBiFunForType biFun tvMap conName covariant (SigT ty _) = - makeBiFunForType biFun tvMap conName covariant ty -makeBiFunForType biFun tvMap conName covariant (ForallT _ _ ty) = - makeBiFunForType biFun tvMap conName covariant ty -makeBiFunForType biFun tvMap conName covariant ty = - let tyCon :: Type - tyArgs :: [Type] - tyCon:tyArgs = unapplyTy ty - - numLastArgs :: Int - numLastArgs = min 2 $ length tyArgs - - lhsArgs, rhsArgs :: [Type] - (lhsArgs, rhsArgs) = splitAt (length tyArgs - numLastArgs) tyArgs - - tyVarNames :: [Name] - tyVarNames = Map.keys tvMap - - mentionsTyArgs :: Bool - mentionsTyArgs = any (`mentionsName` tyVarNames) tyArgs - - makeBiFunTuple :: ([Q Pat] -> Q Pat) -> (Int -> Name) -> Int - -> Q (Either Exp Exp) - makeBiFunTuple mkTupP mkTupleDataName n = do - args <- mapM newName $ catMaybes [ Just "x" - , guard (biFun == Bifoldr) >> Just "z" - ] - xs <- newNameList "_tup" n + match_for_con :: Exp -> Name -> [(Bool, Exp)] -> Q Match + match_for_con zExp = mkSimpleConMatch2 $ \_ xs -> return $ mkBifoldr xs + where + -- g1 v1 (g2 v2 (.. z)) + mkBifoldr :: [Exp] -> Exp + mkBifoldr = foldr AppE zExp + +-- | Generates a match whose right-hand side implements @bifoldMap@. +makeBifoldMapMatch :: TyVarMap -> ConstructorInfo -> Q Match +makeBifoldMapMatch tvMap con@(ConstructorInfo{constructorName = conName}) = do + parts <- foldDataConArgs tvMap ft_bifoldMap con + parts' <- sequence parts + match_for_con conName parts' + where + -- The Bool is True if the type mentions of the last two type parameters, + -- False otherwise. Later, match_for_con uses mkSimpleConMatch2 to filter + -- out expressions that do not mention the last parameters by checking for + -- False. + ft_bifoldMap :: FFoldType (Q (Bool, Exp)) + ft_bifoldMap = FT { -- See Note [ft_triv for Bifoldable and Bitraversable] + ft_triv = do lam <- mkSimpleLam $ \_ -> return $ VarE memptyValName + return (False, lam) + , ft_var = \v -> return (True, VarE $ tvMap Map.! v) + , ft_tup = \t gs -> do + gg <- sequence gs + lam <- mkSimpleLam $ mkSimpleTupleCase match_for_con t gg + return (True, lam) + , ft_ty_app = \gs -> do + e <- appsE $ varE (foldMapArity (length gs)) + : map (\(_, hs) -> fmap snd hs) gs + return (True, e) + , ft_forall = \_ g -> g + , ft_co_var = \_ -> contravarianceError conName + , ft_fun = \_ _ -> noFunctionsError conName + , ft_bad_app = outOfPlaceTyVarError conName + } - let x = head args - z = last args - fmap Right $ lamE (map varP args) $ caseE (varE x) - [ match (mkTupP $ map varP xs) - (normalB $ biFunCombine biFun - (mkTupleDataName n) - z - xs - (zipWithM makeBiFunTupleField tyArgs xs) - ) - [] - ] - - makeBiFunTupleField :: Type -> Name -> Q (Either Exp Exp) - makeBiFunTupleField fieldTy fieldName = - makeBiFunForType biFun tvMap conName covariant fieldTy - `appEitherE` varE fieldName - - in case tyCon of - ArrowT - | not (allowFunTys (biFunToClass biFun)) -> noFunctionsError conName - | mentionsTyArgs, [argTy, resTy] <- tyArgs -> - do x <- newName "x" - b <- newName "b" - fmap Right . lamE [varP x, varP b] $ - covBiFun covariant resTy `appE` (varE x `appE` - (covBiFun (not covariant) argTy `appE` varE b)) - where - covBiFun :: Bool -> Type -> Q Exp - covBiFun cov = fmap fromEither . makeBiFunForType biFun tvMap conName cov -#if MIN_VERSION_template_haskell(2,6,0) - UnboxedTupleT n - | n > 0 && mentionsTyArgs -> makeBiFunTuple unboxedTupP unboxedTupleDataName n -#endif - TupleT n - | n > 0 && mentionsTyArgs -> makeBiFunTuple tupP tupleDataName n - _ -> do - itf <- isTyFamily tyCon - if any (`mentionsName` tyVarNames) lhsArgs || (itf && mentionsTyArgs) - then outOfPlaceTyVarError conName - else if any (`mentionsName` tyVarNames) rhsArgs - then fmap Right . biFunApp biFun . appsE $ - ( varE (fromJust $ biFunArity biFun numLastArgs) - : map (fmap fromEither . makeBiFunForType biFun tvMap conName covariant) - rhsArgs - ) - else fmap Left $ biFunTriv biFun + match_for_con :: Name -> [(Bool, Exp)] -> Q Match + match_for_con = mkSimpleConMatch2 $ \_ xs -> return $ mkBifoldMap xs + where + -- mappend v1 (mappend v2 ..) + mkBifoldMap :: [Exp] -> Exp + mkBifoldMap [] = VarE memptyValName + mkBifoldMap es = foldr1 (AppE . AppE (VarE mappendValName)) es + +-- | Generates a match whose right-hand side implements @bitraverse@. +makeBitraverseMatch :: TyVarMap -> ConstructorInfo -> Q Match +makeBitraverseMatch tvMap con@(ConstructorInfo{constructorName = conName}) = do + parts <- foldDataConArgs tvMap ft_bitrav con + parts' <- sequence parts + match_for_con conName parts' + where + -- The Bool is True if the type mentions of the last two type parameters, + -- False otherwise. Later, match_for_con uses mkSimpleConMatch2 to filter + -- out expressions that do not mention the last parameters by checking for + -- False. + ft_bitrav :: FFoldType (Q (Bool, Exp)) + ft_bitrav = FT { -- See Note [ft_triv for Bifoldable and Bitraversable] + ft_triv = return (False, VarE pureValName) + , ft_var = \v -> return (True, VarE $ tvMap Map.! v) + , ft_tup = \t gs -> do + gg <- sequence gs + lam <- mkSimpleLam $ mkSimpleTupleCase match_for_con t gg + return (True, lam) + , ft_ty_app = \gs -> do + e <- appsE $ varE (traverseArity (length gs)) + : map (\(_, hs) -> fmap snd hs) gs + return (True, e) + , ft_forall = \_ g -> g + , ft_co_var = \_ -> contravarianceError conName + , ft_fun = \_ _ -> noFunctionsError conName + , ft_bad_app = outOfPlaceTyVarError conName + } + + -- Con a1 a2 ... -> liftA2 (\b1 b2 ... -> Con b1 b2 ...) (g1 a1) + -- (g2 a2) <*> ... + match_for_con :: Name -> [(Bool, Exp)] -> Q Match + match_for_con = mkSimpleConMatch2 $ \conExp xs -> return $ mkApCon conExp xs + where + -- liftA2 (\b1 b2 ... -> Con b1 b2 ...) x1 x2 <*> .. + mkApCon :: Exp -> [Exp] -> Exp + mkApCon conExp [] = VarE pureValName `AppE` conExp + mkApCon conExp [e] = VarE fmapValName `AppE` conExp `AppE` e + mkApCon conExp (e1:e2:es) = foldl' appAp + (VarE liftA2ValName `AppE` conExp `AppE` e1 `AppE` e2) es + where appAp se1 se2 = InfixE (Just se1) (VarE apValName) (Just se2) ------------------------------------------------------------------------------- -- Template Haskell reifying and AST manipulation @@ -842,8 +881,8 @@ -- | Either the given data type doesn't have enough type variables, or one of -- the type variables to be eta-reduced cannot realize kind *. -derivingKindError :: BiClass -> Name -> a -derivingKindError biClass tyConName = error +derivingKindError :: BiClass -> Name -> Q a +derivingKindError biClass tyConName = fail . showString "Cannot derive well-kinded instance of form ‘" . showString className . showChar ' ' @@ -861,8 +900,8 @@ -- | One of the last two type variables appeard in a contravariant position -- when deriving Bifoldable or Bitraversable. -contravarianceError :: Name -> a -contravarianceError conName = error +contravarianceError :: Name -> Q a +contravarianceError conName = fail . showString "Constructor ‘" . showString (nameBase conName) . showString "‘ must not use the last type variable(s) in a function argument" @@ -870,8 +909,8 @@ -- | A constructor has a function argument in a derived Bifoldable or Bitraversable -- instance. -noFunctionsError :: Name -> a -noFunctionsError conName = error +noFunctionsError :: Name -> Q a +noFunctionsError conName = fail . showString "Constructor ‘" . showString (nameBase conName) . showString "‘ must not contain function types" @@ -879,8 +918,8 @@ -- | The data type has a DatatypeContext which mentions one of the eta-reduced -- type variables. -datatypeContextError :: Name -> Type -> a -datatypeContextError dataName instanceType = error +datatypeContextError :: Name -> Type -> Q a +datatypeContextError dataName instanceType = fail . showString "Can't make a derived instance of ‘" . showString (pprint instanceType) . showString "‘:\n\tData type ‘" @@ -890,8 +929,8 @@ -- | The data type has an existential constraint which mentions one of the -- eta-reduced type variables. -existentialContextError :: Name -> a -existentialContextError conName = error +existentialContextError :: Name -> Q a +existentialContextError conName = fail . showString "Constructor ‘" . showString (nameBase conName) . showString "‘ must be truly polymorphic in the last argument(s) of the data type" @@ -899,8 +938,8 @@ -- | The data type mentions one of the n eta-reduced type variables in a place other -- than the last nth positions of a data type in a constructor's field. -outOfPlaceTyVarError :: Name -> a -outOfPlaceTyVarError conName = error +outOfPlaceTyVarError :: Name -> Q a +outOfPlaceTyVarError conName = fail . showString "Constructor ‘" . showString (nameBase conName) . showString "‘ must only use its last two type variable(s) within" @@ -909,8 +948,8 @@ -- | One of the last type variables cannot be eta-reduced (see the canEtaReduce -- function for the criteria it would have to meet). -etaReductionError :: Type -> a -etaReductionError instanceType = error $ +etaReductionError :: Type -> Q a +etaReductionError instanceType = fail $ "Cannot eta-reduce to an instance of form \n\tinstance (...) => " ++ pprint instanceType @@ -960,120 +999,33 @@ biClassConstraint biClass 2 = Just $ biClassName biClass biClassConstraint _ _ = Nothing -biFunArity :: BiFun -> Int -> Maybe Name -biFunArity Bimap 1 = Just fmapValName -biFunArity Bifoldr 1 = Just foldrValName -biFunArity BifoldMap 1 = Just foldMapValName -biFunArity Bitraverse 1 = Just traverseValName -biFunArity biFun 2 = Just $ biFunName biFun -biFunArity _ _ = Nothing - -allowFunTys :: BiClass -> Bool -allowFunTys Bifunctor = True -allowFunTys _ = False +fmapArity :: Int -> Name +fmapArity 1 = fmapValName +fmapArity 2 = bimapValName +fmapArity n = arityErr n + +foldrArity :: Int -> Name +foldrArity 1 = foldrValName +foldrArity 2 = bifoldrValName +foldrArity n = arityErr n + +foldMapArity :: Int -> Name +foldMapArity 1 = foldMapValName +foldMapArity 2 = bifoldMapValName +foldMapArity n = arityErr n + +traverseArity :: Int -> Name +traverseArity 1 = traverseValName +traverseArity 2 = bitraverseValName +traverseArity n = arityErr n + +arityErr :: Int -> a +arityErr n = error $ "Unsupported arity: " ++ show n allowExQuant :: BiClass -> Bool allowExQuant Bifoldable = True allowExQuant _ = False --- See Trac #7436 for why explicit lambdas are used -biFunTriv :: BiFun -> Q Exp -biFunTriv Bimap = do - x <- newName "x" - lamE [varP x] $ varE x --- The biFunTriv definitions for bifoldr, bifoldMap, and bitraverse might seem --- useless, but they do serve a purpose. --- See Note [biFunTriv for Bifoldable and Bitraversable] -biFunTriv Bifoldr = do - z <- newName "z" - lamE [wildP, varP z] $ varE z -biFunTriv BifoldMap = lamE [wildP] $ varE memptyValName -biFunTriv Bitraverse = varE pureValName - -biFunApp :: BiFun -> Q Exp -> Q Exp -biFunApp Bifoldr e = do - x <- newName "x" - z <- newName "z" - lamE [varP x, varP z] $ appsE [e, varE z, varE x] -biFunApp _ e = e - -biFunCombine :: BiFun - -> Name - -> Name - -> [Name] - -> Q [Either Exp Exp] - -> Q Exp -biFunCombine Bimap = bimapCombine -biFunCombine Bifoldr = bifoldrCombine -biFunCombine BifoldMap = bifoldMapCombine -biFunCombine Bitraverse = bitraverseCombine - -bimapCombine :: Name - -> Name - -> [Name] - -> Q [Either Exp Exp] - -> Q Exp -bimapCombine conName _ _ = fmap (foldl' AppE (ConE conName) . fmap fromEither) - --- bifoldr, bifoldMap, and bitraverse are handled differently from bimap, since --- they filter out subexpressions whose types do not mention one of the last two --- type parameters. See --- https://ghc.haskell.org/trac/ghc/wiki/Commentary/Compiler/DeriveFunctor#AlternativestrategyforderivingFoldableandTraversable --- for further discussion. - -bifoldrCombine :: Name - -> Name - -> [Name] - -> Q [Either Exp Exp] - -> Q Exp -bifoldrCombine _ zName _ = fmap (foldr AppE (VarE zName) . rights) - -bifoldMapCombine :: Name - -> Name - -> [Name] - -> Q [Either Exp Exp] - -> Q Exp -bifoldMapCombine _ _ _ = fmap (go . rights) - where - go :: [Exp] -> Exp - go [] = VarE memptyValName - go es = foldr1 (AppE . AppE (VarE mappendValName)) es - -bitraverseCombine :: Name - -> Name - -> [Name] - -> Q [Either Exp Exp] - -> Q Exp -bitraverseCombine conName _ args essQ = do - ess <- essQ - - let argTysTyVarInfo :: [Bool] - argTysTyVarInfo = map isRight ess - - argsWithTyVar, argsWithoutTyVar :: [Name] - (argsWithTyVar, argsWithoutTyVar) = partitionByList argTysTyVarInfo args - - conExpQ :: Q Exp - conExpQ - | null argsWithTyVar - = appsE (conE conName:map varE argsWithoutTyVar) - | otherwise = do - bs <- newNameList "b" $ length args - let bs' = filterByList argTysTyVarInfo bs - vars = filterByLists argTysTyVarInfo - (map varE bs) (map varE args) - lamE (map varP bs') (appsE (conE conName:vars)) - - conExp <- conExpQ - - let go :: [Exp] -> Exp - go [] = VarE pureValName `AppE` conExp - go [e] = VarE fmapValName `AppE` conExp `AppE` e - go (e1:e2:es) = foldl' (\se1 se2 -> InfixE (Just se1) (VarE apValName) (Just se2)) - (VarE liftA2ValName `AppE` conExp `AppE` e1 `AppE` e2) es - - return . go . rights $ ess - biFunEmptyCase :: BiFun -> Name -> Name -> Q Exp biFunEmptyCase biFun z value = biFunTrivial emptyCase @@ -1104,11 +1056,11 @@ go Bitraverse = bitraverseE {- -Note [biFunTriv for Bifoldable and Bitraversable] -~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ +Note [ft_triv for Bifoldable and Bitraversable] +~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ When deriving Bifoldable and Bitraversable, we filter out any subexpressions whose type does not mention one of the last two type parameters. From this, you might -think that we don't need to implement biFunTriv for bifoldr, bifoldMap, or +think that we don't need to implement ft_triv for bifoldr, bifoldMap, or bitraverse at all, but in fact we do need to. Imagine the following data type: data T a b = MkT a (T Int b) @@ -1118,6 +1070,241 @@ bifoldMap f g (MkT a1 a2) = f a1 <> bifoldMap (\_ -> mempty) g arg2 -You need to fill in biFunTriv (\_ -> mempty) as the first argument to the recursive +You need to fill in bi_triv (\_ -> mempty) as the first argument to the recursive call to bifoldMap, since that is how the algorithm handles polymorphic recursion. -} + +------------------------------------------------------------------------------- +-- Generic traversal for functor-like deriving +------------------------------------------------------------------------------- + +-- Much of the code below is cargo-culted from the TcGenFunctor module in GHC. + +data FFoldType a -- Describes how to fold over a Type in a functor like way + = FT { ft_triv :: a + -- ^ Does not contain variables + , ft_var :: Name -> a + -- ^ A bare variable + , ft_co_var :: Name -> a + -- ^ A bare variable, contravariantly + , ft_fun :: a -> a -> a + -- ^ Function type + , ft_tup :: TupleSort -> [a] -> a + -- ^ Tuple type. The [a] is the result of folding over the + -- arguments of the tuple. + , ft_ty_app :: [(Type, a)] -> a + -- ^ Type app, variables only in last argument. The [(Type, a)] + -- represents the last argument types. That is, they form the + -- argument parts of @fun_ty arg_ty_1 ... arg_ty_n@. + , ft_bad_app :: a + -- ^ Type app, variable other than in last arguments + , ft_forall :: [TyVarBndrSpec] -> a -> a + -- ^ Forall type + } + +-- Note that in GHC, this function is pure. It must be monadic here since we: +-- +-- (1) Expand type synonyms +-- (2) Detect type family applications +-- +-- Which require reification in Template Haskell, but are pure in Core. +functorLikeTraverse :: forall a. + TyVarMap -- ^ Variables to look for + -> FFoldType a -- ^ How to fold + -> Type -- ^ Type to process + -> Q a +functorLikeTraverse tvMap (FT { ft_triv = caseTrivial, ft_var = caseVar + , ft_co_var = caseCoVar, ft_fun = caseFun + , ft_tup = caseTuple, ft_ty_app = caseTyApp + , ft_bad_app = caseWrongArg, ft_forall = caseForAll }) + ty + = do ty' <- resolveTypeSynonyms ty + (res, _) <- go False ty' + return res + where + go :: Bool -- Covariant or contravariant context + -> Type + -> Q (a, Bool) -- (result of type a, does type contain var) + go co t@AppT{} + | (ArrowT, [funArg, funRes]) <- unapplyTy t + = do (funArgR, funArgC) <- go (not co) funArg + (funResR, funResC) <- go co funRes + if funArgC || funResC + then return (caseFun funArgR funResR, True) + else trivial + go co t@AppT{} = do + let (f, args) = unapplyTy t + (_, fc) <- go co f + (xrs, xcs) <- fmap unzip $ mapM (go co) args + let numLastArgs, numFirstArgs :: Int + numLastArgs = min 2 $ length args + numFirstArgs = length args - numLastArgs + + tuple :: TupleSort -> Q (a, Bool) + tuple tupSort = return (caseTuple tupSort xrs, True) + + wrongArg :: Q (a, Bool) + wrongArg = return (caseWrongArg, True) + + case () of + _ | not (or xcs) + -> trivial -- Variable does not occur + -- At this point we know that xrs, xcs is not empty, + -- and at least one xr is True + | TupleT len <- f + -> tuple $ Boxed len +#if MIN_VERSION_template_haskell(2,6,0) + | UnboxedTupleT len <- f + -> tuple $ Unboxed len +#endif + | fc || or (take numFirstArgs xcs) + -> wrongArg -- T (..var..) ty_1 ... ty_n + | otherwise -- T (..no var..) ty_1 ... ty_n + -> do itf <- isInTypeFamilyApp tyVarNames f args + if itf -- We can't decompose type families, so + -- error if we encounter one here. + then wrongArg + else return ( caseTyApp $ drop numFirstArgs $ zip args xrs + , True ) + go co (SigT t k) = do + (_, kc) <- go_kind co k + if kc + then return (caseWrongArg, True) + else go co t + go co (VarT v) + | Map.member v tvMap + = return (if co then caseCoVar v else caseVar v, True) + | otherwise + = trivial + go co (ForallT tvbs _ t) = do + (tr, tc) <- go co t + let tvbNames = map tvName tvbs + if not tc || any (`elem` tvbNames) tyVarNames + then trivial + else return (caseForAll tvbs tr, True) + go _ _ = trivial + + go_kind :: Bool + -> Kind + -> Q (a, Bool) +#if MIN_VERSION_template_haskell(2,9,0) + go_kind = go +#else + go_kind _ _ = trivial +#endif + + trivial :: Q (a, Bool) + trivial = return (caseTrivial, False) + + tyVarNames :: [Name] + tyVarNames = Map.keys tvMap + +-- Fold over the arguments of a data constructor in a Functor-like way. +foldDataConArgs :: forall a. TyVarMap -> FFoldType a -> ConstructorInfo -> Q [a] +foldDataConArgs tvMap ft con = do + fieldTys <- mapM resolveTypeSynonyms $ constructorFields con + mapM foldArg fieldTys + where + foldArg :: Type -> Q a + foldArg = functorLikeTraverse tvMap ft + +-- Make a 'LamE' using a fresh variable. +mkSimpleLam :: (Exp -> Q Exp) -> Q Exp +mkSimpleLam lam = do + n <- newName "n" + body <- lam (VarE n) + return $ LamE [VarP n] body + +-- Make a 'LamE' using two fresh variables. +mkSimpleLam2 :: (Exp -> Exp -> Q Exp) -> Q Exp +mkSimpleLam2 lam = do + n1 <- newName "n1" + n2 <- newName "n2" + body <- lam (VarE n1) (VarE n2) + return $ LamE [VarP n1, VarP n2] body + +-- "Con a1 a2 a3 -> fold [x1 a1, x2 a2, x3 a3]" +-- +-- @mkSimpleConMatch fold conName insides@ produces a match clause in +-- which the LHS pattern-matches on @extraPats@, followed by a match on the +-- constructor @conName@ and its arguments. The RHS folds (with @fold@) over +-- @conName@ and its arguments, applying an expression (from @insides@) to each +-- of the respective arguments of @conName@. +mkSimpleConMatch :: (Name -> [a] -> Q Exp) + -> Name + -> [Exp -> a] + -> Q Match +mkSimpleConMatch fold conName insides = do + varsNeeded <- newNameList "_arg" $ length insides + let pat = ConP conName (map VarP varsNeeded) + rhs <- fold conName (zipWith (\i v -> i $ VarE v) insides varsNeeded) + return $ Match pat (NormalB rhs) [] + +-- "Con a1 a2 a3 -> fmap (\b2 -> Con a1 b2 a3) (traverse f a2)" +-- +-- @mkSimpleConMatch2 fold conName insides@ behaves very similarly to +-- 'mkSimpleConMatch', with two key differences: +-- +-- 1. @insides@ is a @[(Bool, Exp)]@ instead of a @[Exp]@. This is because it +-- filters out the expressions corresponding to arguments whose types do not +-- mention the last type variable in a derived 'Foldable' or 'Traversable' +-- instance (i.e., those elements of @insides@ containing @False@). +-- +-- 2. @fold@ takes an expression as its first argument instead of a +-- constructor name. This is because it uses a specialized +-- constructor function expression that only takes as many parameters as +-- there are argument types that mention the last type variable. +mkSimpleConMatch2 :: (Exp -> [Exp] -> Q Exp) + -> Name + -> [(Bool, Exp)] + -> Q Match +mkSimpleConMatch2 fold conName insides = do + varsNeeded <- newNameList "_arg" lengthInsides + let pat = ConP conName (map VarP varsNeeded) + -- Make sure to zip BEFORE invoking catMaybes. We want the variable + -- indicies in each expression to match up with the argument indices + -- in conExpr (defined below). + exps = catMaybes $ zipWith (\(m, i) v -> if m then Just (i `AppE` VarE v) + else Nothing) + insides varsNeeded + -- An element of argTysTyVarInfo is True if the constructor argument + -- with the same index has a type which mentions the last type + -- variable. + argTysTyVarInfo = map (\(m, _) -> m) insides + (asWithTyVar, asWithoutTyVar) = partitionByList argTysTyVarInfo varsNeeded + + conExpQ + | null asWithTyVar = appsE (conE conName:map varE asWithoutTyVar) + | otherwise = do + bs <- newNameList "b" lengthInsides + let bs' = filterByList argTysTyVarInfo bs + vars = filterByLists argTysTyVarInfo + (map varE bs) (map varE varsNeeded) + lamE (map varP bs') (appsE (conE conName:vars)) + + conExp <- conExpQ + rhs <- fold conExp exps + return $ Match pat (NormalB rhs) [] + where + lengthInsides = length insides + +-- Indicates whether a tuple is boxed or unboxed, as well as its number of +-- arguments. For instance, (a, b) corresponds to @Boxed 2@, and (# a, b, c #) +-- corresponds to @Unboxed 3@. +data TupleSort + = Boxed Int +#if MIN_VERSION_template_haskell(2,6,0) + | Unboxed Int +#endif + +-- "case x of (a1,a2,a3) -> fold [x1 a1, x2 a2, x3 a3]" +mkSimpleTupleCase :: (Name -> [a] -> Q Match) + -> TupleSort -> [a] -> Exp -> Q Exp +mkSimpleTupleCase matchForCon tupSort insides x = do + let tupDataName = case tupSort of + Boxed len -> tupleDataName len +#if MIN_VERSION_template_haskell(2,6,0) + Unboxed len -> unboxedTupleDataName len +#endif + m <- matchForCon tupDataName insides + return $ CaseE x [m] diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/bifunctors-5.5.7/tests/BifunctorSpec.hs new/bifunctors-5.5.8/tests/BifunctorSpec.hs --- old/bifunctors-5.5.7/tests/BifunctorSpec.hs 2001-09-09 03:46:40.000000000 +0200 +++ new/bifunctors-5.5.8/tests/BifunctorSpec.hs 2001-09-09 03:46:40.000000000 +0200 @@ -117,6 +117,15 @@ type role Empty2 nominal nominal #endif +data TyCon81 a b + = TyCon81a (forall c. c -> (forall d. a -> d) -> a) + | TyCon81b (Int -> forall c. c -> b) + +type family F :: * -> * -> * +type instance F = Either + +data TyCon82 a b = TyCon82 (F a b) + -- Data families data family StrangeFam x y z @@ -178,6 +187,14 @@ data instance IntHashFunFam a b = IntHashFunFam ((((a -> Int#) -> b) -> Int#) -> a) +data family TyFamily81 x y +data instance TyFamily81 a b + = TyFamily81a (forall c. c -> (forall d. a -> d) -> a) + | TyFamily81b (Int -> forall c. c -> b) + +data family TyFamily82 x y +data instance TyFamily82 a b = TyFamily82 (F a b) + ------------------------------------------------------------------------------- -- Plain data types @@ -246,6 +263,12 @@ $(deriveBifoldableOptions defaultOptions{emptyCaseBehavior = True} ''Empty2) $(deriveBitraversableOptions defaultOptions{emptyCaseBehavior = True} ''Empty2) +$(deriveBifunctor ''TyCon81) + +$(deriveBifunctor ''TyCon82) +$(deriveBifoldable ''TyCon82) +$(deriveBitraversable ''TyCon82) + #if MIN_VERSION_template_haskell(2,7,0) -- Data families @@ -303,6 +326,12 @@ $(deriveBitraversable 'IntHashFam) $(deriveBifunctor 'IntHashFunFam) + +$(deriveBifunctor 'TyFamily81a) + +$(deriveBifunctor 'TyFamily82) +$(deriveBifoldable 'TyFamily82) +$(deriveBitraversable 'TyFamily82) #endif -------------------------------------------------------------------------------