From cf9a3a9e9c177182bbd976c58e607cb817570da9 Mon Sep 17 00:00:00 2001 From: Hiromi ISHII Date: Mon, 30 Sep 2024 16:49:15 +0900 Subject: [PATCH] Initial commit --- .allstar/allstar.yaml | 2 + .allstar/security.yaml | 2 + .github/workflows/haskell.yml | 211 + .gitignore | 180 + .pre-commit-config.yaml | 22 + .vscode/extensions.json | 13 + .vscode/settings.shared.json | 15 + CONTRIBUTING.md | 51 + README.md | 56 + cabal.project | 3 + cabal.project.freeze | 3063 +++++++++++++++ ci/configs/ghc-9.2.8.project | 3067 +++++++++++++++ ci/configs/ghc-9.4.8.project | 3022 +++++++++++++++ ci/configs/ghc-9.6.6.project | 3385 +++++++++++++++++ ci/configs/ghc-9.8.2.project | 3133 +++++++++++++++ ci/scripts/cabal-check-packages.sh | 63 + ci/scripts/calc-cache-keys.js | 40 + ci/scripts/collect-bins.sh | 86 + ci/scripts/enumerate-ci.js | 21 + elgenerics-containers/.gitignore | 2 + elgenerics-containers/ChangeLog.md | 3 + elgenerics-containers/LICENSE | 30 + elgenerics-containers/README.md | 16 + elgenerics-containers/Setup.hs | 3 + elgenerics-containers/app/record-test.hs | 47 + .../app/record-tylist-test.hs | 106 + .../elgenerics-containers.cabal | 150 + elgenerics-containers/src/Data/HList.hs | 302 ++ .../src/Data/HList/HigherKinded.hs | 986 +++++ .../src/Data/HList/HigherKinded/Builder.hs | 43 + .../src/Data/HList/Internal.hs | 9 + .../src/Data/Product/Class.hs | 103 + elgenerics-containers/src/Data/Record.hs | 185 + .../src/Data/Record/Builder/HigherKinded.hs | 132 + .../Record/Builder/HigherKinded/BottomUp.hs | 117 + .../src/Data/Record/HigherKinded.hs | 2006 ++++++++++ .../src/Data/Record/HigherKinded/Internal.hs | 73 + .../src/Data/Record/HigherKinded/OnEntry.hs | 265 ++ .../src/Data/Record/HigherKinded/Unsafe.hs | 29 + .../src/Data/Record/Plugin.hs | 108 + elgenerics-containers/src/Data/Sum/Class.hs | 113 + .../src/Data/TypeLevel/BinTree.hs | 50 + .../src/Data/TypeLevel/Path.hs | 134 + elgenerics-containers/src/Data/Union.hs | 140 + .../src/Data/Union/HigherKinded.hs | 142 + .../src/Data/Union/Internal.hs | 10 + .../Builder/HigherKinded/BottomUpSpec.hs | 138 + .../Data/Record/Builder/HigherKindedSpec.hs | 55 + .../test/Data/Record/Cases.hs | 98 + .../test/Data/Record/Failures.hs | 31 + .../test/Data/Record/HigherKindedSpec.hs | 497 +++ .../test/Data/Record/PluginSpec.hs | 39 + elgenerics-containers/test/Data/RecordSpec.hs | 40 + elgenerics-containers/test/Spec.hs | 1 + elgenerics-known/.gitignore | 2 + elgenerics-known/ChangeLog.md | 3 + elgenerics-known/LICENSE | 30 + elgenerics-known/README.md | 16 + elgenerics-known/Setup.hs | 3 + elgenerics-known/app/NormDefs.hs | 35 + elgenerics-known/app/normalise-test.hs | 30 + elgenerics-known/app/simple-plugin-test.hs | 58 + elgenerics-known/elgenerics-known.cabal | 165 + .../src/Control/Category/Monoid.hs | 22 + .../src/Data/Constraint/Deferrable/Solver.hs | 218 ++ .../src/Data/Constraint/Operators.hs | 256 ++ elgenerics-known/src/Data/Constraint/TH.hs | 86 + elgenerics-known/src/Data/Inhabited.hs | 110 + elgenerics-known/src/Data/Membership.hs | 266 ++ .../src/Data/TypeLevel/Applicative.hs | 86 + elgenerics-known/src/Data/TypeLevel/Bool.hs | 56 + elgenerics-known/src/Data/TypeLevel/Eq.hs | 24 + .../src/Data/TypeLevel/Foldable.hs | 24 + .../src/Data/TypeLevel/Function.hs | 87 + elgenerics-known/src/Data/TypeLevel/Known.hs | 88 + .../src/Data/TypeLevel/Known/Core.hs | 593 +++ .../src/Data/TypeLevel/Known/TH.hs | 510 +++ elgenerics-known/src/Data/TypeLevel/List.hs | 319 ++ .../src/Data/TypeLevel/List/Core.hs | 135 + .../src/Data/TypeLevel/List/Overloaded.hs | 93 + .../src/Data/TypeLevel/List/Properties.hs | 27 + .../src/Data/TypeLevel/List/Solver.hs | 101 + .../Data/TypeLevel/List/Solver/Constraint.hs | 656 ++++ .../src/Data/TypeLevel/List/Solver/Free.hs | 329 ++ .../Data/TypeLevel/List/Solver/Generation.hs | 351 ++ .../src/Data/TypeLevel/List/Solver/Reduce.hs | 79 + .../src/Data/TypeLevel/List/Solver/Syntax.hs | 737 ++++ .../src/Data/TypeLevel/List/Solver/Utils.hs | 78 + .../src/Data/TypeLevel/List/Unsafe.hs | 40 + elgenerics-known/src/Data/TypeLevel/Maybe.hs | 119 + elgenerics-known/src/Data/TypeLevel/Monoid.hs | 50 + elgenerics-known/src/Data/TypeLevel/Nat.hs | 220 ++ .../src/Data/TypeLevel/Normalise/Plugin.hs | 137 + elgenerics-known/src/Data/TypeLevel/Ord.hs | 274 ++ .../src/Data/TypeLevel/Ord/Internal.hs | 12 + elgenerics-known/src/Data/TypeLevel/OrdMap.hs | 2634 +++++++++++++ .../src/Data/TypeLevel/OrdMap/Internal.hs | 72 + elgenerics-known/src/Data/TypeLevel/Tuple.hs | 21 + .../src/Data/TypeLevel/Typeable.hs | 229 ++ .../src/Data/UnionFind/Primitive.hs | 53 + elgenerics-known/src/GHC/TcPluginM/Orphans.hs | 56 + .../Data/Constraint/Deferrable/SolverSpec.hs | 33 + .../Constraint/Deferrable/SolverSpec/Cases.hs | 58 + .../Deferrable/SolverSpec/Undeferreds.hs | 28 + .../test/Data/TypeLevel/KnownSpec.hs | 71 + .../test/Data/TypeLevel/ListSpec.hs | 267 ++ .../test/Data/TypeLevel/ListSpec/Cases.hs | 225 ++ .../Data/TypeLevel/ListSpec/Undeferred.hs | 19 + .../test/Data/TypeLevel/Nat/Definitions.hs | 23 + .../test/Data/TypeLevel/NatSpec.hs | 33 + .../test/Data/TypeLevel/OrdMapSpec.hs | 167 + .../test/Data/TypeLevel/OrdMapSpec/Cases.hs | 72 + .../Data/TypeLevel/OrdMapSpec/Failures.hs | 35 + elgenerics-known/test/Helpers.hs | 62 + elgenerics-known/test/Spec.hs | 1 + fourmolu.yaml | 8 + 116 files changed, 33330 insertions(+) create mode 100644 .allstar/allstar.yaml create mode 100644 .allstar/security.yaml create mode 100644 .github/workflows/haskell.yml create mode 100644 .gitignore create mode 100644 .pre-commit-config.yaml create mode 100644 .vscode/extensions.json create mode 100644 .vscode/settings.shared.json create mode 100644 CONTRIBUTING.md create mode 100644 README.md create mode 100644 cabal.project create mode 100644 cabal.project.freeze create mode 100644 ci/configs/ghc-9.2.8.project create mode 100644 ci/configs/ghc-9.4.8.project create mode 100644 ci/configs/ghc-9.6.6.project create mode 100644 ci/configs/ghc-9.8.2.project create mode 100644 ci/scripts/cabal-check-packages.sh create mode 100644 ci/scripts/calc-cache-keys.js create mode 100644 ci/scripts/collect-bins.sh create mode 100644 ci/scripts/enumerate-ci.js create mode 100644 elgenerics-containers/.gitignore create mode 100644 elgenerics-containers/ChangeLog.md create mode 100644 elgenerics-containers/LICENSE create mode 100644 elgenerics-containers/README.md create mode 100644 elgenerics-containers/Setup.hs create mode 100644 elgenerics-containers/app/record-test.hs create mode 100644 elgenerics-containers/app/record-tylist-test.hs create mode 100644 elgenerics-containers/elgenerics-containers.cabal create mode 100644 elgenerics-containers/src/Data/HList.hs create mode 100644 elgenerics-containers/src/Data/HList/HigherKinded.hs create mode 100644 elgenerics-containers/src/Data/HList/HigherKinded/Builder.hs create mode 100644 elgenerics-containers/src/Data/HList/Internal.hs create mode 100644 elgenerics-containers/src/Data/Product/Class.hs create mode 100644 elgenerics-containers/src/Data/Record.hs create mode 100644 elgenerics-containers/src/Data/Record/Builder/HigherKinded.hs create mode 100644 elgenerics-containers/src/Data/Record/Builder/HigherKinded/BottomUp.hs create mode 100644 elgenerics-containers/src/Data/Record/HigherKinded.hs create mode 100644 elgenerics-containers/src/Data/Record/HigherKinded/Internal.hs create mode 100644 elgenerics-containers/src/Data/Record/HigherKinded/OnEntry.hs create mode 100644 elgenerics-containers/src/Data/Record/HigherKinded/Unsafe.hs create mode 100644 elgenerics-containers/src/Data/Record/Plugin.hs create mode 100644 elgenerics-containers/src/Data/Sum/Class.hs create mode 100644 elgenerics-containers/src/Data/TypeLevel/BinTree.hs create mode 100644 elgenerics-containers/src/Data/TypeLevel/Path.hs create mode 100644 elgenerics-containers/src/Data/Union.hs create mode 100644 elgenerics-containers/src/Data/Union/HigherKinded.hs create mode 100644 elgenerics-containers/src/Data/Union/Internal.hs create mode 100644 elgenerics-containers/test/Data/Record/Builder/HigherKinded/BottomUpSpec.hs create mode 100644 elgenerics-containers/test/Data/Record/Builder/HigherKindedSpec.hs create mode 100644 elgenerics-containers/test/Data/Record/Cases.hs create mode 100644 elgenerics-containers/test/Data/Record/Failures.hs create mode 100644 elgenerics-containers/test/Data/Record/HigherKindedSpec.hs create mode 100644 elgenerics-containers/test/Data/Record/PluginSpec.hs create mode 100644 elgenerics-containers/test/Data/RecordSpec.hs create mode 100644 elgenerics-containers/test/Spec.hs create mode 100644 elgenerics-known/.gitignore create mode 100644 elgenerics-known/ChangeLog.md create mode 100644 elgenerics-known/LICENSE create mode 100644 elgenerics-known/README.md create mode 100644 elgenerics-known/Setup.hs create mode 100644 elgenerics-known/app/NormDefs.hs create mode 100644 elgenerics-known/app/normalise-test.hs create mode 100644 elgenerics-known/app/simple-plugin-test.hs create mode 100644 elgenerics-known/elgenerics-known.cabal create mode 100644 elgenerics-known/src/Control/Category/Monoid.hs create mode 100644 elgenerics-known/src/Data/Constraint/Deferrable/Solver.hs create mode 100644 elgenerics-known/src/Data/Constraint/Operators.hs create mode 100644 elgenerics-known/src/Data/Constraint/TH.hs create mode 100644 elgenerics-known/src/Data/Inhabited.hs create mode 100644 elgenerics-known/src/Data/Membership.hs create mode 100644 elgenerics-known/src/Data/TypeLevel/Applicative.hs create mode 100644 elgenerics-known/src/Data/TypeLevel/Bool.hs create mode 100644 elgenerics-known/src/Data/TypeLevel/Eq.hs create mode 100644 elgenerics-known/src/Data/TypeLevel/Foldable.hs create mode 100644 elgenerics-known/src/Data/TypeLevel/Function.hs create mode 100644 elgenerics-known/src/Data/TypeLevel/Known.hs create mode 100644 elgenerics-known/src/Data/TypeLevel/Known/Core.hs create mode 100644 elgenerics-known/src/Data/TypeLevel/Known/TH.hs create mode 100644 elgenerics-known/src/Data/TypeLevel/List.hs create mode 100644 elgenerics-known/src/Data/TypeLevel/List/Core.hs create mode 100644 elgenerics-known/src/Data/TypeLevel/List/Overloaded.hs create mode 100644 elgenerics-known/src/Data/TypeLevel/List/Properties.hs create mode 100644 elgenerics-known/src/Data/TypeLevel/List/Solver.hs create mode 100644 elgenerics-known/src/Data/TypeLevel/List/Solver/Constraint.hs create mode 100644 elgenerics-known/src/Data/TypeLevel/List/Solver/Free.hs create mode 100644 elgenerics-known/src/Data/TypeLevel/List/Solver/Generation.hs create mode 100644 elgenerics-known/src/Data/TypeLevel/List/Solver/Reduce.hs create mode 100644 elgenerics-known/src/Data/TypeLevel/List/Solver/Syntax.hs create mode 100644 elgenerics-known/src/Data/TypeLevel/List/Solver/Utils.hs create mode 100644 elgenerics-known/src/Data/TypeLevel/List/Unsafe.hs create mode 100644 elgenerics-known/src/Data/TypeLevel/Maybe.hs create mode 100644 elgenerics-known/src/Data/TypeLevel/Monoid.hs create mode 100644 elgenerics-known/src/Data/TypeLevel/Nat.hs create mode 100644 elgenerics-known/src/Data/TypeLevel/Normalise/Plugin.hs create mode 100644 elgenerics-known/src/Data/TypeLevel/Ord.hs create mode 100644 elgenerics-known/src/Data/TypeLevel/Ord/Internal.hs create mode 100644 elgenerics-known/src/Data/TypeLevel/OrdMap.hs create mode 100644 elgenerics-known/src/Data/TypeLevel/OrdMap/Internal.hs create mode 100644 elgenerics-known/src/Data/TypeLevel/Tuple.hs create mode 100644 elgenerics-known/src/Data/TypeLevel/Typeable.hs create mode 100644 elgenerics-known/src/Data/UnionFind/Primitive.hs create mode 100644 elgenerics-known/src/GHC/TcPluginM/Orphans.hs create mode 100644 elgenerics-known/test/Data/Constraint/Deferrable/SolverSpec.hs create mode 100644 elgenerics-known/test/Data/Constraint/Deferrable/SolverSpec/Cases.hs create mode 100644 elgenerics-known/test/Data/Constraint/Deferrable/SolverSpec/Undeferreds.hs create mode 100644 elgenerics-known/test/Data/TypeLevel/KnownSpec.hs create mode 100644 elgenerics-known/test/Data/TypeLevel/ListSpec.hs create mode 100644 elgenerics-known/test/Data/TypeLevel/ListSpec/Cases.hs create mode 100644 elgenerics-known/test/Data/TypeLevel/ListSpec/Undeferred.hs create mode 100644 elgenerics-known/test/Data/TypeLevel/Nat/Definitions.hs create mode 100644 elgenerics-known/test/Data/TypeLevel/NatSpec.hs create mode 100644 elgenerics-known/test/Data/TypeLevel/OrdMapSpec.hs create mode 100644 elgenerics-known/test/Data/TypeLevel/OrdMapSpec/Cases.hs create mode 100644 elgenerics-known/test/Data/TypeLevel/OrdMapSpec/Failures.hs create mode 100644 elgenerics-known/test/Helpers.hs create mode 100644 elgenerics-known/test/Spec.hs create mode 100644 fourmolu.yaml diff --git a/.allstar/allstar.yaml b/.allstar/allstar.yaml new file mode 100644 index 0000000..fe48b13 --- /dev/null +++ b/.allstar/allstar.yaml @@ -0,0 +1,2 @@ +optConfig: + optOut: true diff --git a/.allstar/security.yaml b/.allstar/security.yaml new file mode 100644 index 0000000..fe48b13 --- /dev/null +++ b/.allstar/security.yaml @@ -0,0 +1,2 @@ +optConfig: + optOut: true diff --git a/.github/workflows/haskell.yml b/.github/workflows/haskell.yml new file mode 100644 index 0000000..e791bb4 --- /dev/null +++ b/.github/workflows/haskell.yml @@ -0,0 +1,211 @@ +name: Build and Test +on: + push: {branches: ["main"]} + pull_request: + +jobs: + ci-enumerate: + name: Enumerate GHC Versions + runs-on: ubuntu-latest + outputs: + plan: ${{steps.list-ci.outputs.plan}} + steps: + - uses: actions/checkout@v3 + with: + ref: ${{github.event.pull_request.head.sha || github.sha}} + - name: Enumerate CI plans + id: list-ci + uses: actions/github-script@v6 + with: + script: | + const script = require('./ci/scripts/enumerate-ci.js') + await script({github, context, core, glob, io, require}) + + build: + name: Build (${{matrix.plan.name}}) + needs: [ci-enumerate] + continue-on-error: true + strategy: + matrix: + ## TODO: When OSS is ready, use the following line + # plan: ${{fromJSON(needs.ci-enumerate.outputs.plan)}} + + ## TODO: When OSS is ready, delete the following: + plan: + - path: "ci/configs/ghc-9.2.8.project" + name: "ghc-9.2.8" + ghc: "9.2.8" + is_head: false + fail-fast: false + env: + cabal-version: 3.10.2.0 + cabal: "cabal --project-file=${{matrix.plan.path}}" + ghc: ${{matrix.plan.ghc}} + project-file: ${{matrix.plan.path}} + plan: ${{matrix.plan.name}} + artifact-name: "artifact-${{matrix.plan.name}}" + runs-on: ubuntu-latest + outputs: + benchmarks: ${{steps.list-bins.outputs.benchs}} + tests: ${{steps.list-bins.outputs.tests}} + artifact: "artifact-${{matrix.plan.name}}" + steps: + - uses: actions/checkout@v3 + with: + ref: ${{github.event.pull_request.head.sha || github.sha}} + - name: Calculate hash keys + uses: actions/github-script@v6 + id: cache-keys + with: + script: | + const script = require('./ci/scripts/calc-cache-keys.js') + await script({ os: "ubuntu", plan: ${{toJSON(env.plan)}}, path: ${{toJSON(env.project-file)}}, core, glob }) + + - name: Setup Haskell + uses: haskell-actions/setup@v2 + with: + enable-stack: false + cabal-version: ${{env.cabal-version}} + ghc-version: ${{env.ghc}} + - name: Restore ~/.cabal/store + uses: actions/cache/restore@v3 + with: + path: ~/.cabal/store + key: ${{steps.cache-keys.outputs.store}} + restore-keys: ${{steps.cache-keys.outputs.store-restore}} + - name: Restore dist-newstyle + uses: actions/cache/restore@v3 + with: + path: dist-newstyle + key: ${{steps.cache-keys.outputs.dist}} + restore-keys: ${{steps.cache-keys.outputs.dist-restore}} + - name: cabal configure + run: | + ${{env.cabal}} v2-configure --enable-tests --enable-benchmarks --enable-optimisation=2 + ${{env.cabal}} update + - name: Build Dependencies + run: | + ${{env.cabal}} build --only-dependencies all + - name: Save ~/.cabal/store Cache + uses: actions/cache/save@v3 + with: + path: ~/.cabal/store + key: ${{steps.cache-keys.outputs.store}} + - name: Build All + run: | + ${{env.cabal}} build all + - name: Save dist-newstyle Cache + uses: actions/cache/save@v3 + with: + path: dist-newstyle + key: ${{steps.cache-keys.outputs.dist}} + + - name: Collect binaries + continue-on-error: true + run: bash ./ci/scripts/collect-bins.sh "${{env.artifact-name}}" + - name: Upload Aritracts + uses: actions/upload-artifact@v3 + with: + path: ${{env.artifact-name}}.tar.zst + name: ${{env.artifact-name}} + retention-days: 1 + - name: List Binaries + id: list-bins + shell: bash + run: | + echo "benchs=$(jq -cMnR '[inputs]' <"${{env.artifact-name}}"/benchs.list)" >>"${GITHUB_OUTPUT}" + echo "tests=$(jq -cMnR '[inputs]' <"${{env.artifact-name}}"/tests.list)" >>"${GITHUB_OUTPUT}" + + test: + name: Test (${{matrix.plan.name}}) + needs: [ci-enumerate, build] + continue-on-error: ${{matrix.plan.is_head}} + strategy: + matrix: + ## TODO: When OSS is ready, use the following line + # plan: ${{fromJSON(needs.ci-enumerate.outputs.plan)}} + + ## TODO: When OSS is ready, delete the following: + plan: + - path: "ci/configs/ghc-9.2.8.project" + name: "ghc-9.2.8" + ghc: "9.2.8" + is_head: false + fail-fast: false + env: + cabal: 3.12.1.0 + ghc: ${{matrix.plan.ghc}} + project-file: ${{matrix.plan.path}} + plan: ${{matrix.plan.name}} + artifact: artifact-${{matrix.plan.name}} + runs-on: ubuntu-latest + steps: + - name: Fail when Corresponding Build didn't succeed + if: ${{needs.build.result != 'success' }} + run: echo "BUILD FAILED" >&2; exit 1 + - uses: actions/checkout@v3 + with: + ref: ${{github.event.pull_request.head.sha || github.sha}} + - name: Download artifacts + id: download + uses: actions/download-artifact@v3 + - name: Decompress + run: tar xaf ${{env.artifact}}/${{env.artifact}}.tar.zst + - name: Run Tests + shell: bash + run: | + set -euo pipefail + TOTAL=0 + SUCCESS=0 + FAIL=0 + while read -r TEST; do + TOTAL=$((TOTAL + 1)) + echo "--------" + echo "Running: ${TEST}" + set +e + ${{env.artifact}}/tests/"${TEST}" + RESL=$? + set -e + if [ ${RESL} -eq 0 ]; then + SUCCESS=$((SUCCESS + 1)) + echo "Result: Successed" + else + FAIL=$((FAIL + 1)) + echo 'Result: FAILED!' + fi + done <${{env.artifact}}/tests.list + + echo "" + echo "----" + + if [ "${FAIL}" -eq 0 ]; then + echo "All ${TOTAL} tests passed." + else + echo "${FAIL} out of ${TOTAL} tests FAILED"'!' + exit 1 + fi + + fourmolu: + name: Fourmolu + runs-on: ubuntu-latest + steps: + # Note that you must checkout your code before running fourmolu/fourmolu-action + - uses: actions/checkout@v2 + - uses: fourmolu/fourmolu-action@v10 + with: + pattern: | + **/*.hs + !**/Setup.hs + !**/Setup.lhs + !dist-newstyle/** + + cabal-check: + name: Cabal Check + runs-on: ubuntu-latest + steps: + - uses: actions/checkout@v3 + - uses: haskell-actions/setup@v2 + with: + cabal-version: 3.10.2.0 + ghc-version: latest + - run: bash ./ci/scripts/cabal-check-packages.sh diff --git a/.gitignore b/.gitignore new file mode 100644 index 0000000..bbecae9 --- /dev/null +++ b/.gitignore @@ -0,0 +1,180 @@ +### https://raw.github.com/github/gitignore/14f8a8b4c51ecc00b18905a95c117954e6c77b9d/Haskell.gitignore + +dist +dist-* +cabal-dev +*.o +*.hi +*.hie +*.chi +*.chs.h +*.dyn_o +*.dyn_hi +.hpc +.hsenv +.cabal-sandbox/ +cabal.sandbox.config +*.prof +*.aux +*.hp +*.eventlog +.stack-work/ +cabal.project.local +cabal.project.local~ +.HTF/ +.ghc.environment.* +workspace + +### https://raw.github.com/github/gitignore/14f8a8b4c51ecc00b18905a95c117954e6c77b9d/Global/VisualStudioCode.gitignore + +.vscode/* +!.vscode/settings.json +!.vscode/tasks.json +!.vscode/launch.json +!.vscode/extensions.json +*.code-workspace + +# Local History for Visual Studio Code +.history/ + + +### https://raw.github.com/github/gitignore/14f8a8b4c51ecc00b18905a95c117954e6c77b9d/Global/macOS.gitignore + +# General +.DS_Store +.AppleDouble +.LSOverride + +# Icon must end with two \r +Icon + + +# Thumbnails +._* + +# Files that might appear in the root of a volume +.DocumentRevisions-V100 +.fseventsd +.Spotlight-V100 +.TemporaryItems +.Trashes +.VolumeIcon.icns +.com.apple.timemachine.donotpresent + +# Directories potentially created on remote AFP share +.AppleDB +.AppleDesktop +Network Trash Folder +Temporary Items +.apdisk + + +### https://raw.github.com/github/gitignore/14f8a8b4c51ecc00b18905a95c117954e6c77b9d/Global/Linux.gitignore + +*~ + +# temporary files which can be created if a process still has a handle open of a deleted file +.fuse_hidden* + +# KDE directory preferences +.directory + +# Linux trash folder which might appear on any partition or disk +.Trash-* + +# .nfs files are created when an open file is removed but is still being accessed +.nfs* + + +### Generated by gibo (https://github.com/simonwhitaker/gibo) +### https://raw.github.com/github/gitignore/e5323759e387ba347a9d50f8b0ddd16502eb71d4/Haskell.gitignore + +dist +dist-* +cabal-dev +*.o +*.hi +*.hie +*.chi +*.chs.h +*.dyn_o +*.dyn_hi +.hpc +.hsenv +.cabal-sandbox/ +cabal.sandbox.config +*.prof +*.aux +*.hp +*.eventlog +.stack-work/ +cabal.project.local +cabal.project.local~ +.HTF/ +.ghc.environment.* + + +### https://raw.github.com/github/gitignore/e5323759e387ba347a9d50f8b0ddd16502eb71d4/Global/VisualStudioCode.gitignore + +.vscode/* +!.vscode/settings.json +!.vscode/tasks.json +!.vscode/launch.json +!.vscode/extensions.json +!.vscode/*.code-snippets + +# Local History for Visual Studio Code +.history/ + +# Built Visual Studio Code Extensions +*.vsix + + +### https://raw.github.com/github/gitignore/e5323759e387ba347a9d50f8b0ddd16502eb71d4/Global/macOS.gitignore + +# General +.DS_Store +.AppleDouble +.LSOverride + +# Icon must end with two \r +Icon + + +# Thumbnails +._* + +# Files that might appear in the root of a volume +.DocumentRevisions-V100 +.fseventsd +.Spotlight-V100 +.TemporaryItems +.Trashes +.VolumeIcon.icns +.com.apple.timemachine.donotpresent + +# Directories potentially created on remote AFP share +.AppleDB +.AppleDesktop +Network Trash Folder +Temporary Items +.apdisk + + +### https://raw.github.com/github/gitignore/e5323759e387ba347a9d50f8b0ddd16502eb71d4/Global/Linux.gitignore + +*~ + +# temporary files which can be created if a process still has a handle open of a deleted file +.fuse_hidden* + +# KDE directory preferences +.directory + +# Linux trash folder which might appear on any partition or disk +.Trash-* + +# .nfs files are created when an open file is removed but is still being accessed +.nfs* + +workspace diff --git a/.pre-commit-config.yaml b/.pre-commit-config.yaml new file mode 100644 index 0000000..7379f83 --- /dev/null +++ b/.pre-commit-config.yaml @@ -0,0 +1,22 @@ +default_install_hook_types: +- pre-commit +- post-checkout +- pre-commit +repos: +# Prohibits commits to the default branch +# TODO: Revive this after publishing of the first version +# - repo: https://github.com/pre-commit/pre-commit-hooks +# rev: v4.2.0 +# hooks: +# - id: no-commit-to-branch +# args: [--branch, main] +- repo: local + hooks: + - id: pre-commit-run-hpack + name: Generates .cabal files with hpack + always_run: true + verbose: true + stages: [commit] + language: system + pass_filenames: false + entry: bash -c "find . \( -name '**/*.cabal' -or -name '**/cabal.project*' \) -not -path './dist-newstyle/*' | while read -r FILE; do cabal-gild --io "\${FILE}"; done || echo '[warn] no cabal-gild found' >&2" diff --git a/.vscode/extensions.json b/.vscode/extensions.json new file mode 100644 index 0000000..4a50b88 --- /dev/null +++ b/.vscode/extensions.json @@ -0,0 +1,13 @@ +{ + // See https://go.microsoft.com/fwlink/?LinkId=827846 to learn about workspace recommendations. + // Extension identifier format: ${publisher}.${name}. Example: vscode.csharp + + // List of extensions which should be recommended for users of this workspace. + "recommendations": [ + "haskell.haskell", + "emeraldwalk.RunOnSave", + "Swellaby.workspace-config-plus" + ], + // List of extensions recommended by VS Code that should not be recommended for users of this workspace. + "unwantedRecommendations": [] +} diff --git a/.vscode/settings.shared.json b/.vscode/settings.shared.json new file mode 100644 index 0000000..14c9a68 --- /dev/null +++ b/.vscode/settings.shared.json @@ -0,0 +1,15 @@ +{ + "emeraldwalk.runonsave": { + "commands": [ + { + "cmd": "bash -c \"find . \\( -name '**/*.cabal' -or -name '**/cabal.project*' \\) -not -path './dist-newstyle/*' | while read -r FILE; do cabal-gild --io \"\\${FILE}\"; done\"", + "isAsync": true, + "match": "(\\.l?hs)$" + } + ] + }, + "files.associations": { + "**/ci/configs/*.project": "cabal" + }, + "haskell.formattingProvider": "fourmolu" +} diff --git a/CONTRIBUTING.md b/CONTRIBUTING.md new file mode 100644 index 0000000..7ff91de --- /dev/null +++ b/CONTRIBUTING.md @@ -0,0 +1,51 @@ +# Contribution Guidelines + +If you have any issue, please report it to the [GitHub issue tracker for this project][issue]. +When you open an issue, please check whether there is alredy similar one(s). + +We are also accepting [Pull Requests][pulls] - you can feel free to open pull requests for small changes, e.g. typo correction. +If you are planning a considerably big change, however, please first discuss the change you want to make via an issue. + +## Development Tooling + +- For simplicity, we use `cabal-install >= 3.10` for build tool. +- GHC version policy: support the most recent minor releases of at least three major releases. We must support the most-recent Stackage LTS. +- We are using [`cabal-gild`](https://github.com/tfausak/cabal-gild) to format and generate module lists of cabal files. Make sure all the `.cabal` files are formatted. +- We strongly recommend to use the [pre-commit][pre-commit] tool. + It runs hooks shared across the repository in Git's pre-commit hook. + Currently, the following hooks are enabled: + + + A protection rule for `main` branch preventing making commit to protected branch + + Runs cabal-gild if it's in `$PATH`. + +[pre-commit]: https://pre-commit.com + +There is no obligation about editors - you can use any editor of your choice. +We recommend to use [HLS][HLS] as a Language Server when available. + +If you use VSCode, it is recommended to install the following extensions (as included in `.vscode/extensions.json`): + +- [Haskell](https://marketplace.visualstudio.com/items?itemName=haskell.haskell) extension boosts productivity in writing Haskell. +- [Workspace Config+](https://marketplace.visualstudio.com/items?itemName=swellaby.workspace-config-plus) lets you coexist shared settings and local configs. +- [Run On Save](https://marketplace.visualstudio.com/items?itemName=emeraldwalk.RunOnSave) ensures `*.cabal`s to be up-to-date with `package.yaml`. + +All the source code (except `Setup.hs`) MUST be formatted with [Fourmolu][fourmolu]. +HLS supports fourmolu as a formatter, so we strongly recommend to use HLS and enable `Format on Save` in your editor. + +[issue]: https://github.com/deepflowinc/elgenerics/issues +[pulls]: https://github.com/deepflowinc/elgenerics/pulls +[fourmolu]: https://github.com/fourmolu/fourmolu +[HLS]: https://github.com/haskell/haskell-language-server + +## Pull Request Requirements + +To get PRs merged, following criteria must be met: + +- We require [commits to be signed][commit-sign] in order to be merged into main branch. +- The following tests must be all green: + + `Fourmolu` - to enforce consistent formatting + + `Build` and `Test` for non-head GHCs +- It is strongly recommended to write commit messages obeying [Conventional Commit][convcom] guidline. + +[convcom]: https://www.conventionalcommits.org +[commit-sign]: https://docs.github.com/en/authentication/managing-commit-signature-verification/signing-commits diff --git a/README.md b/README.md new file mode 100644 index 0000000..60d6702 --- /dev/null +++ b/README.md @@ -0,0 +1,56 @@ +# elgenerics - Battle-tested type-level programming and extensible record libraries + +## What is this? + +This monorepo contains the type-level programming and extensible record libraries developed at DeepFlow, Inc., and battle-tested for more than five years. +This consists of two libraries: + +- __`elgenerics-known`__ provides various machinery related to singletons for dependently-typed programming in Haskell. + + Central concepts: `Known` (which borrows the name from `KnownNat` and/or `KnownSymbol`) and `Sing` type family. + + Type-level Ordered Map (`Data.TypeLevel.OrdMap`) and Lists (`Data.TypeLevel.List`) and type-checker plugins for automatically solving their constraints. + * OrdMap can be keyed with a type with any kind. +- __`elgenerics-containers`__ provides higher-kinded extensible / anonymous records, heterogeneous lists, and unions. + +## Contribution + +Please feel free to open an issue, but also please search for existing issues to check if there already is a similar one. + +See [CONTRIBUTING.md][CONTRIBUTING] for more details. + +[CONTRIBUTING]: ./CONTRIBUTING.md + +## Matrix Build + +To add/remove a specific ghc version to/from the tested versions, you can just add/remove cabal's freeze file as `ci/configs/ghc-X.X.X.project` and add the following to the header: + +```cabal +import: ../../cabal.project +-- FIXME: Use Appropriate timestamp for index-state +index-state: hackage.haskell.org 2024-03-05T05:41:26Z +``` + +Note that the actual value of `index-state` should be sufficiently new. + +Except this, no modification to Action worklow file is needed in general. +The following is the example command to add the `ghc-9.8.1` with the most recent Stackage Nightly: + +```bash +curl --location https://www.stackage.org/nightly/cabal.config > ./ci/configs/ghc-9.8.1.project +cat <>./ci/configs/ghc-9.8.1.project +import: ../../cabal.project +-- FIXME: Use an appropriate timestamp for index-state +index-state: hackage.haskell.org 2024-03-05T05:41:26Z +EOF +``` + +Note that we might have to edit `with-compiler` stanza of the downloaded freeze file when you want to test GHC version different from Stackage's default version. + +If you want to test some breeding-edge version of GHC but to allow failure, name freeze file as `ghc-X.X.X-head.project`. + +```bash +curl --location https://www.stackage.org/nightly/cabal.config > ./ci/configs/ghc-9.10.1-head.project +``` + +## Copyright + +2019-present (c) DeepFlow, Inc. diff --git a/cabal.project b/cabal.project new file mode 100644 index 0000000..ee69aa1 --- /dev/null +++ b/cabal.project @@ -0,0 +1,3 @@ +packages: */*.cabal +tests: True +benchmarks: True diff --git a/cabal.project.freeze b/cabal.project.freeze new file mode 100644 index 0000000..8cae285 --- /dev/null +++ b/cabal.project.freeze @@ -0,0 +1,3063 @@ +-- NOTE: Due to revisions, this file may not work. See: +-- https://github.com/fpco/stackage-server/issues/232 + +-- Stackage snapshot from: http://www.stackage.org/snapshot/lts-20.26 +-- Please place this file next to your .cabal file as cabal.config +-- To only use tested packages, uncomment the following line: +-- remote-repo: stackage-lts-20.26:http://www.stackage.org/lts-20.26 +with-compiler: ghc-9.2.8 +constraints: abstract-deque ==0.3, + abstract-deque-tests ==0.3, + abstract-par ==0.3.3, + AC-Angle ==1.0, + acc ==0.2.0.1, + ace ==0.6, + acid-state ==0.16.1.2, + action-permutations ==0.0.0.1, + active ==0.2.0.18, + ad ==4.5.4, + ad-delcont ==0.3.0.0, + adjunctions ==4.4.2, + adler32 ==0.1.2.0, + advent-of-code-api ==0.2.8.4, + aern2-mp ==0.2.15.0, + aern2-real ==0.2.11.0, + aeson ==2.0.3.0, + aeson-attoparsec ==0.0.0, + aeson-better-errors ==0.9.1.1, + aeson-casing ==0.2.0.0, + aeson-combinators ==0.1.0.1, + aeson-commit ==1.6.0, + aeson-compat ==0.3.10, + aeson-diff ==1.1.0.13, + aeson-extra ==0.5.1.2, + aeson-generic-compat ==0.0.1.3, + aeson-iproute ==0.3.0, + aeson-optics ==1.2.0.1, + aeson-picker ==0.1.0.6, + aeson-pretty ==0.8.9, + aeson-qq ==0.8.4, + aeson-schemas ==1.4.1.0, + aeson-typescript ==0.4.2.0, + aeson-value-parser ==0.19.7.1, + aeson-yak ==0.1.1.3, + aeson-yaml ==1.1.0.1, + Agda ==2.6.2.2, + agda2lagda ==0.2021.6.1, + airship ==0.9.5, + al ==0.1.4.2, + alarmclock ==0.7.0.6, + alerts ==0.1.2.0, + alex ==3.2.7.4, + alex-meta ==0.3.0.13, + algebra ==4.3.1, + algebraic-graphs ==0.6.1, + Allure ==0.11.0.0, + almost-fix ==0.0.2, + alsa-core ==0.5.0.1, + alsa-mixer ==0.3.0, + alsa-pcm ==0.6.1.1, + alternative-vector ==0.0.0, + alternators ==1.0.0.0, + ALUT ==2.4.0.3, + amqp ==0.22.1, + amqp-utils ==0.6.3.2, + annotated-exception ==0.2.0.4, + annotated-wl-pprint ==0.7.0, + ansi-terminal ==0.11.4, + ansi-terminal-game ==1.8.1.0, + ansi-wl-pprint ==0.6.9, + ANum ==0.2.0.2, + aos-signature ==0.1.1, + apecs ==0.9.5, + apecs-gloss ==0.2.4, + apecs-physics ==0.4.5, + api-field-json-th ==0.1.0.2, + api-maker ==0.1.0.6, + ap-normalize ==0.1.0.1, + appar ==0.1.8, + appendful ==0.1.0.0, + appendful-persistent ==0.1.0.0, + appendmap ==0.1.5, + apply-refact ==0.10.0.0, + apportionment ==0.0.0.4, + approximate ==0.3.5, + approximate-equality ==1.1.0.2, + app-settings ==0.2.0.12, + arbor-lru-cache ==0.1.1.1, + arbtt ==0.12.0.1, + arithmoi ==0.12.1.0, + array installed, + array-memoize ==0.6.0, + arrow-extras ==0.1.0.1, + arrows ==0.4.4.2, + ascii ==1.2.4.0, + ascii-case ==1.0.1.2, + ascii-char ==1.0.0.17, + asciidiagram ==1.3.3.3, + ascii-group ==1.0.0.15, + ascii-numbers ==1.1.0.2, + ascii-predicates ==1.0.1.2, + ascii-progress ==0.3.3.0, + ascii-superset ==1.0.1.15, + ascii-th ==1.0.0.14, + asn1-encoding ==0.9.6, + asn1-parse ==0.9.5, + asn1-types ==0.3.4, + assert-failure ==0.1.2.6, + assoc ==1.0.2, + astro ==0.4.3.0, + async ==2.2.4, + async-extra ==0.2.0.0, + async-pool ==0.9.1, + async-refresh ==0.3.0.0, + async-refresh-tokens ==0.4.0.0, + atom-basic ==0.2.5, + atom-conduit ==0.9.0.1, + atomic-primops ==0.8.4, + atomic-write ==0.2.0.7, + attoparsec ==0.14.4, + attoparsec-base64 ==0.0.0, + attoparsec-binary ==0.2, + attoparsec-data ==1.0.5.3, + attoparsec-expr ==0.1.1.2, + attoparsec-iso8601 ==1.0.2.1, + attoparsec-path ==0.0.0.1, + attoparsec-time ==1.0.3, + aur ==7.0.7, + aura ==3.2.9, + authenticate ==1.3.5.1, + authenticate-oauth ==1.7, + autodocodec ==0.2.0.3, + autodocodec-openapi3 ==0.2.1.1, + autodocodec-schema ==0.1.0.3, + autodocodec-yaml ==0.2.0.3, + autoexporter ==2.0.0.2, + auto-update ==0.1.6, + avro ==0.6.1.2, + aws-cloudfront-signed-cookies ==0.2.0.12, + aws-xray-client ==0.1.0.2, + aws-xray-client-persistent ==0.1.0.5, + aws-xray-client-wai ==0.1.0.2, + backtracking ==0.1.0, + bank-holidays-england ==0.2.0.9, + barbies ==2.0.4.0, + base installed, + base16 ==0.3.2.1, + base16-bytestring ==1.0.2.0, + base32 ==0.2.2.0, + base32string ==0.9.1, + base58-bytestring ==0.1.0, + base58string ==0.10.0, + base64 ==0.4.2.4, + base64-bytestring ==1.2.1.0, + base64-bytestring-type ==1.0.1, + base64-string ==0.2, + base-compat ==0.12.2, + base-compat-batteries ==0.12.2, + basement ==0.0.16, + base-orphans ==0.8.8.2, + base-prelude ==1.6.1, + base-unicode-symbols ==0.2.4.2, + basic-prelude ==0.7.0, + battleship-combinatorics ==0.0.1, + bazel-runfiles ==0.12, + bbdb ==0.8, + bcp47 ==0.2.0.6, + bcp47-orphans ==0.1.0.6, + bcrypt ==0.0.11, + beam-core ==0.9.2.1, + beam-migrate ==0.5.1.2, + beam-postgres ==0.5.2.1, + beam-sqlite ==0.5.1.2, + bech32 ==1.1.3, + bech32-th ==1.1.1, + bench ==1.0.12, + benchpress ==0.2.2.22, + bench-show ==0.3.2, + bencode ==0.6.1.1, + bencoding ==0.4.5.4, + benri-hspec ==0.1.0.1, + between ==0.11.0.0, + bhoogle ==0.1.4.2, + bibtex ==0.1.0.6, + bifunctors ==5.5.15, + bimap ==0.5.0, + bimaps ==0.1.0.2, + bimap-server ==0.1.0.1, + bin ==0.1.2, + binance-exports ==0.1.1.0, + binary installed, + binary-conduit ==1.3.1, + binaryen ==0.0.6.0, + binary-generic-combinators ==0.4.4.0, + binary-ieee754 ==0.1.0.0, + binary-instances ==1.0.4, + binary-list ==1.1.1.2, + binary-orphans ==1.0.4.1, + binary-parser ==0.5.7.3, + binary-search ==2.0.0, + binary-shared ==0.8.3, + binary-tagged ==0.3.1, + bindings-DSL ==1.0.25, + bindings-GLFW ==3.3.2.0, + bindings-libzip ==1.0.1, + bindings-uname ==0.1, + BiobaseEnsembl ==0.2.0.1, + bitarray ==0.0.1.1, + bits ==0.6, + bitset-word8 ==0.1.1.2, + bits-extra ==0.0.2.3, + bitvec ==1.1.4.0, + bitwise-enum ==1.0.1.0, + blake2 ==0.3.0, + Blammo ==1.1.2.0, + blank-canvas ==0.7.3, + blanks ==0.5.0, + blas-carray ==0.1.0.2, + blas-comfort-array ==0.0.0.3, + blas-ffi ==0.1, + blas-hs ==0.1.1.0, + blaze-bootstrap ==0.1.0.1, + blaze-builder ==0.4.2.2, + blaze-html ==0.9.1.2, + blaze-markup ==0.8.2.8, + blaze-svg ==0.3.7, + blaze-textual ==0.2.3.1, + bloodhound ==0.21.0.0, + bm ==0.1.1.0, + bmp ==1.2.6.3, + bnb-staking-csvs ==0.2.1.0, + BNFC ==2.9.4.1, + BNFC-meta ==0.6.1, + bodhi ==0.1.0, + boltzmann-samplers ==0.1.1.0, + bookkeeping ==0.4.0.1, + Boolean ==0.2.4, + boolsimplifier ==0.1.8, + boomerang ==1.4.9, + boots ==0.2.0.1, + bordacount ==0.1.0.0, + boring ==0.2.1, + bound ==2.0.6, + BoundedChan ==1.0.3.0, + bounded-queue ==1.0.0, + boundingboxes ==0.2.3, + bower-json ==1.1.0.0, + boxes ==0.1.5, + breakpoint ==0.1.2.1, + brick ==1.4, + broadcast-chan ==0.2.1.2, + brotli ==0.0.0.1, + brotli-streams ==0.0.0.0, + bsb-http-chunked ==0.0.0.4, + bson ==0.4.0.1, + bson-lens ==0.1.1, + buffer-builder ==0.2.4.8, + buffer-pipe ==0.0, + bugsnag ==1.0.0.1, + bugsnag-haskell ==0.0.4.4, + bugsnag-hs ==0.2.0.9, + bugsnag-wai ==1.0.0.1, + bugsnag-yesod ==1.0.0.1, + bugzilla-redhat ==1.0.1, + burrito ==2.0.1.6, + butcher ==1.3.3.2, + bv ==0.5, + byteable ==0.1.1, + bytebuild ==0.3.13.0, + byte-count-reader ==0.10.1.10, + bytedump ==1.0, + bytehash ==0.1.0.0, + byte-order ==0.1.3.0, + byteorder ==1.0.4, + bytes ==0.17.2, + byteset ==0.1.1.0, + byteslice ==0.2.7.0, + bytesmith ==0.3.9.1, + bytestring installed, + bytestring-builder ==0.10.8.2.0, + bytestring-conversion ==0.3.2, + bytestring-lexing ==0.5.0.10, + bytestring-mmap ==0.2.2, + bytestring-progress ==1.4, + bytestring-strict-builder ==0.4.5.6, + bytestring-to-vector ==0.3.0.1, + bytestring-tree-builder ==0.2.7.10, + bytestring-trie ==0.2.7.2, + bz2 ==1.0.1.0, + bzlib-conduit ==0.3.0.2, + c14n ==0.1.0.2, + c2hs ==0.28.8, + Cabal installed, + cabal2nix ==2.19.1, + cabal2spec ==2.6.3, + cabal-appimage ==0.3.0.5, + cabal-clean ==0.2.20230609, + cabal-debian ==5.2.1, + cabal-doctest ==1.0.9, + cabal-file ==0.1.1, + cabal-file-th ==0.2.7, + cabal-flatpak ==0.1.0.4, + cabal-install ==3.6.2.0, + cabal-plan ==0.7.2.3, + cabal-rpm ==2.0.11.1, + Cabal-syntax ==3.6.0.0, + cache ==0.1.3.0, + cached-json-file ==0.1.1, + cacophony ==0.10.1, + cairo ==0.13.10.0, + calendar-recycling ==0.0.0.1, + call-alloy ==0.4.0.3, + calligraphy ==0.1.4, + call-plantuml ==0.0.1.2, + call-stack ==0.4.0, + can-i-haz ==0.3.1.1, + capability ==0.5.0.1, + ca-province-codes ==1.0.0.0, + cardano-coin-selection ==1.0.1, + carray ==0.1.6.8, + casa-client ==0.0.1, + casa-types ==0.0.2, + cased ==0.1.0.0, + case-insensitive ==1.2.1.0, + cases ==0.1.4.2, + casing ==0.1.4.1, + cassava ==0.5.3.0, + cassava-megaparsec ==2.0.4, + cast ==0.1.0.2, + cayley-client ==0.4.19.2, + cborg ==0.2.9.0, + cborg-json ==0.2.5.0, + cdar-mBound ==0.1.0.4, + c-enum ==0.1.1.3, + cereal ==0.5.8.3, + cereal-conduit ==0.8.0, + cereal-text ==0.1.0.2, + cereal-unordered-containers ==0.1, + cereal-vector ==0.2.0.1, + cfenv ==0.1.0.0, + chan ==0.0.4.1, + character-cases ==0.1.0.6, + charset ==0.3.9, + charsetdetect-ae ==1.1.0.4, + Chart ==1.9.4, + Chart-cairo ==1.9.3, + Chart-diagrams ==1.9.4, + chart-svg ==0.3.3, + ChasingBottoms ==1.3.1.12, + cheapskate ==0.1.1.2, + cheapskate-highlight ==0.1.0.0, + cheapskate-lucid ==0.1.0.0, + check-email ==1.0.2, + checkers ==0.6.0, + checksum ==0.0.0.1, + chimera ==0.3.3.0, + choice ==0.2.2, + chronologique ==0.3.1.3, + chunked-data ==0.3.1, + cipher-aes ==0.2.11, + cipher-camellia ==0.0.2, + cipher-rc4 ==0.1.4, + circle-packing ==0.1.0.6, + circular ==0.4.0.3, + citeproc ==0.8.1, + classy-prelude ==1.5.0.2, + classy-prelude-conduit ==1.5.0, + classy-prelude-yesod ==1.5.0, + cleff ==0.3.3.0, + cleff-plugin ==0.1.0.0, + clientsession ==0.9.1.2, + climb ==0.4.1, + Clipboard ==2.3.2.0, + clock ==0.8.3, + closed ==0.2.0.2, + clumpiness ==0.17.0.2, + ClustalParser ==1.3.0, + cmark ==0.6, + cmark-gfm ==0.2.5, + cmark-lucid ==0.1.0.0, + cmdargs ==0.10.22, + codec-beam ==0.2.0, + code-conjure ==0.5.2, + code-page ==0.2.1, + cointracking-imports ==0.1.0.2, + collect-errors ==0.1.5.0, + co-log-core ==0.3.2.0, + Color ==0.3.3, + colorful-monoids ==0.2.1.3, + colorize-haskell ==1.0.1, + colour ==2.3.6, + columnar ==1.0.0.0, + combinatorial ==0.1.1, + comfort-array ==0.5.2.3, + comfort-array-shape ==0.0, + comfort-fftw ==0.0.0.1, + comfort-graph ==0.0.3.2, + commonmark ==0.2.2, + commonmark-extensions ==0.2.3.4, + commonmark-pandoc ==0.2.1.3, + commutative ==0.0.2, + comonad ==5.0.8, + comonad-extras ==4.0.1, + compactmap ==0.1.4.3, + compensated ==0.8.3, + compiler-warnings ==0.1.0, + componentm ==0.0.0.2, + componentm-devel ==0.0.0.2, + composable-associations ==0.1.0.0, + composite-base ==0.8.2.1, + composite-binary ==0.8.2.1, + composite-ekg ==0.8.2.1, + composite-tuple ==0.1.2.0, + composite-xstep ==0.1.0.0, + composition ==1.0.2.2, + composition-extra ==2.0.0, + composition-prelude ==3.0.0.2, + concise ==0.1.0.1, + concurrency ==1.11.0.3, + concurrent-extra ==0.7.0.12, + concurrent-output ==1.10.18, + concurrent-split ==0.0.1.1, + cond ==0.4.1.1, + conduino ==0.2.2.0, + conduit ==1.3.5, + conduit-aeson ==0.1.0.1, + conduit-algorithms ==0.0.13.0, + conduit-combinators ==1.3.0, + conduit-concurrent-map ==0.1.3, + conduit-extra ==1.3.6, + conduit-parse ==0.2.1.1, + conduit-zstd ==0.0.2.0, + conferer ==1.1.0.0, + conferer-aeson ==1.1.0.2, + ConfigFile ==1.1.4, + config-ini ==0.2.5.0, + configuration-tools ==0.6.1, + configurator ==0.3.0.0, + configurator-export ==0.1.0.1, + configurator-pg ==0.2.7, + connection ==0.3.1, + connection-pool ==0.2.2, + console-style ==0.0.2.1, + constraints ==0.13.4, + constraints-extras ==0.3.2.1, + constraint-tuples ==0.1.2, + construct ==0.3.1.1, + containers installed, + context ==0.2.0.1, + context-http-client ==0.2.0.1, + context-resource ==0.2.0.1, + context-wai-middleware ==0.2.0.1, + contiguous ==0.6.3.0, + contravariant ==1.5.5, + contravariant-extras ==0.3.5.3, + control-bool ==0.2.1, + control-dsl ==0.2.1.3, + control-monad-free ==0.6.2, + control-monad-omega ==0.3.2, + convertible ==1.1.1.1, + cookie ==0.4.6, + copr-api ==0.1.0, + core-data ==0.3.9.1, + core-program ==0.6.8.0, + core-telemetry ==0.2.9.3, + core-text ==0.3.8.1, + countable ==1.2, + country ==0.2.3, + covariance ==0.2.0.1, + cpphs ==1.20.9.1, + cprng-aes ==0.6.1, + cpu ==0.1.2, + cpuinfo ==0.1.0.2, + cql ==4.0.4, + cql-io ==1.1.1, + crackNum ==3.2, + credential-store ==0.1.2, + criterion ==1.5.13.0, + criterion-measurement ==0.1.4.0, + cron ==0.7.0, + crypto-api ==0.13.3, + crypto-api-tests ==0.3, + crypto-cipher-tests ==0.0.11, + crypto-cipher-types ==0.0.9, + cryptocompare ==0.1.2, + crypto-enigma ==0.1.1.6, + cryptohash ==0.11.9, + cryptohash-cryptoapi ==0.1.4, + cryptohash-md5 ==0.11.101.0, + cryptohash-sha1 ==0.11.101.0, + cryptohash-sha256 ==0.11.102.1, + cryptohash-sha512 ==0.11.102.0, + cryptonite ==0.30, + cryptonite-conduit ==0.2.2, + cryptonite-openssl ==0.7, + crypto-pubkey-types ==0.4.3, + crypto-random ==0.0.9, + crypto-random-api ==0.2.0, + cryptostore ==0.2.3.0, + crypt-sha512 ==0, + csp ==1.4.0, + css-text ==0.1.3.0, + c-struct ==0.1.3.0, + csv ==0.1.2, + csv-conduit ==0.7.3.0, + ctrie ==0.2, + cubicbezier ==0.6.0.6, + cubicspline ==0.1.2, + cue-sheet ==2.0.2, + curl ==1.3.8, + curl-runnings ==0.17.0, + currencies ==0.2.0.0, + currency ==0.2.0.0, + currycarbon ==0.2.1.1, + cursor ==0.3.2.0, + cursor-brick ==0.1.0.1, + cursor-fuzzy-time ==0.0.0.0, + cursor-gen ==0.4.0.0, + cyclotomic ==1.1.2, + czipwith ==1.0.1.4, + d10 ==1.0.1.2, + data-accessor ==0.2.3.1, + data-accessor-mtl ==0.2.0.5, + data-accessor-transformers ==0.2.1.8, + data-array-byte ==0.1.0.1, + data-binary-ieee754 ==0.4.4, + data-bword ==0.1.0.2, + data-checked ==0.3, + data-clist ==0.2, + data-default ==0.7.1.1, + data-default-class ==0.1.2.0, + data-default-instances-base ==0.1.0.1, + data-default-instances-bytestring ==0.0.1, + data-default-instances-case-insensitive ==0.0.1, + data-default-instances-containers ==0.0.1, + data-default-instances-dlist ==0.0.1, + data-default-instances-old-locale ==0.0.1, + data-default-instances-text ==0.0.1, + data-default-instances-unordered-containers ==0.0.1, + data-default-instances-vector ==0.0.1, + data-diverse ==4.7.1.0, + datadog ==0.3.0.0, + data-dword ==0.3.2.1, + data-endian ==0.1.1, + data-fix ==0.3.2, + data-forest ==0.1.0.10, + data-functor-logistic ==0.0, + data-has ==0.4.0.0, + data-hash ==0.2.0.1, + data-interval ==2.1.1, + data-inttrie ==0.1.4, + data-lens-light ==0.1.2.3, + data-memocombinators ==0.5.1, + data-msgpack ==0.0.13, + data-msgpack-types ==0.0.3, + data-or ==1.0.0.7, + data-ordlist ==0.4.7.0, + data-ref ==0.0.2, + data-reify ==0.6.3, + data-serializer ==0.3.5, + datasets ==0.4.0, + data-sketches ==0.3.1.0, + data-sketches-core ==0.1.0.0, + data-textual ==0.3.0.3, + data-tree-print ==0.1.0.2, + dataurl ==0.1.0.0, + DAV ==1.3.4, + dawg-ord ==0.5.1.2, + dbcleaner ==0.1.3, + DBFunctor ==0.1.2.1, + dbus ==1.2.29, + dbus-hslogger ==0.1.0.1, + debian ==4.0.4, + debian-build ==0.10.2.1, + debug-trace-var ==0.2.0, + dec ==0.0.5, + Decimal ==0.5.2, + declarative ==0.5.4, + deepseq installed, + deepseq-generics ==0.2.0.0, + deferred-folds ==0.9.18.3, + dejafu ==2.4.0.5, + dense-linear-algebra ==0.1.0.0, + dependent-map ==0.4.0.0, + dependent-sum ==0.7.2.0, + dependent-sum-template ==0.1.1.1, + depq ==0.4.2, + deque ==0.4.4, + deriveJsonNoPrefix ==0.1.0.1, + derive-topdown ==0.0.3.0, + deriving-aeson ==0.2.9, + deriving-compat ==0.6.3, + detour-via-sci ==1.0.0, + df1 ==0.4.1, + dhall ==1.41.2, + dhall-bash ==1.0.40, + dhall-json ==1.7.11, + dhall-yaml ==1.2.12, + di ==1.3, + diagrams ==1.4.0.1, + diagrams-builder ==0.8.0.5, + diagrams-cairo ==1.4.2, + diagrams-canvas ==1.4.1.1, + diagrams-contrib ==1.4.5, + diagrams-core ==1.5.1, + diagrams-lib ==1.4.5.2, + diagrams-postscript ==1.5.1.1, + diagrams-rasterific ==1.4.2.3, + diagrams-solve ==0.1.3, + diagrams-svg ==1.4.3.1, + di-core ==1.0.4, + dictionary-sharing ==0.1.0.0, + di-df1 ==1.2.1, + Diff ==0.4.1, + digest ==0.0.1.7, + digits ==0.3.1, + di-handle ==1.0.1, + dimensional ==1.5, + di-monad ==1.3.1, + directory installed, + directory-tree ==0.12.1, + direct-sqlite ==2.3.28, + dirichlet ==0.1.0.7, + discount ==0.1.1, + discover-instances ==0.1.0.0, + discrimination ==0.5, + disk-free-space ==0.1.0.1, + distribution-nixpkgs ==1.7.0.1, + distribution-opensuse ==1.1.3, + distributive ==0.6.2.1, + diversity ==0.8.1.0, + djinn-lib ==0.0.1.4, + dl-fedora ==0.9.5, + dlist ==1.0, + dlist-instances ==0.1.1.1, + dlist-nonempty ==0.1.2, + dns ==4.1.1, + docker ==0.7.0.1, + dockerfile ==0.2.0, + doclayout ==0.4.0.1, + doctemplates ==0.10.0.2, + doctest ==0.20.1, + doctest-discover ==0.2.0.0, + doctest-driver-gen ==0.3.0.7, + doctest-exitcode-stdio ==0.0, + doctest-lib ==0.1, + doctest-parallel ==0.2.6, + doldol ==0.4.1.2, + do-list ==1.0.1, + domain ==0.1.1.4, + domain-aeson ==0.1.1.1, + domain-cereal ==0.1, + domain-core ==0.1.0.3, + domain-optics ==0.1.0.3, + do-notation ==0.1.0.2, + dot ==0.3, + dotenv ==0.10.0.0, + dotgen ==0.4.3, + dotnet-timespan ==0.0.1.0, + double-conversion ==2.0.4.2, + download ==0.3.2.7, + download-curl ==0.1.4, + DPutils ==0.1.1.0, + drifter ==0.3.0, + drifter-postgresql ==0.2.1, + drifter-sqlite ==0.1.0.0, + dsp ==0.2.5.2, + dual ==0.1.1.1, + dual-tree ==0.2.3.1, + dublincore-xml-conduit ==0.1.0.2, + dunai ==0.9.2, + duration ==0.2.0.0, + dvorak ==0.1.0.0, + dynamic-state ==0.3.1, + dyre ==0.9.2, + eap ==0.9.0.2, + Earley ==0.13.0.1, + easy-file ==0.2.5, + easy-logger ==0.1.0.7, + Ebnf2ps ==1.0.15, + echo ==0.1.4, + ecstasy ==0.2.1.0, + ed25519 ==0.0.5.0, + ede ==0.3.3.0, + edit-distance ==0.2.2.1, + edit-distance-vector ==1.0.0.4, + editor-open ==0.6.0.0, + effectful ==2.2.2.0, + effectful-core ==2.2.2.2, + effectful-plugin ==1.0.0.0, + effectful-th ==1.0.0.1, + either ==5.0.2, + either-both ==0.1.1.1, + either-unwrap ==1.1, + ekg-core ==0.1.1.7, + elerea ==2.9.0, + elf ==0.31, + eliminators ==0.9, + elm2nix ==0.3.0, + elm-bridge ==0.8.2, + elm-core-sources ==1.0.0, + elm-export ==0.6.0.1, + elynx ==0.7.2.1, + elynx-markov ==0.7.2.1, + elynx-nexus ==0.7.2.1, + elynx-seq ==0.7.2.1, + elynx-tools ==0.7.2.1, + elynx-tree ==0.7.2.1, + emacs-module ==0.1.1.1, + email-validate ==2.3.2.18, + emojis ==0.1.2, + enclosed-exceptions ==1.0.3, + ENIG ==0.0.1.0, + entropy ==0.4.1.10, + enummapset ==0.6.0.3, + enumset ==0.1, + enum-text ==0.5.3.0, + envelope ==0.2.2.0, + envparse ==0.5.0, + envy ==2.1.2.0, + eq ==4.3, + equational-reasoning ==0.7.0.1, + equivalence ==0.4.1, + erf ==2.0.0.0, + errata ==0.4.0.0, + error ==1.0.0.0, + errorcall-eq-instance ==0.3.0, + error-or ==0.3.0, + error-or-utils ==0.2.0, + errors ==2.3.0, + errors-ext ==0.4.2, + ersatz ==0.4.13, + esqueleto ==3.5.10.0, + essence-of-live-coding ==0.2.7, + essence-of-live-coding-gloss ==0.2.7, + essence-of-live-coding-pulse ==0.2.7, + essence-of-live-coding-quickcheck ==0.2.7, + essence-of-live-coding-warp ==0.2.7, + event-list ==0.1.2, + eventstore ==1.4.2, + every ==0.0.1, + evm-opcodes ==0.1.2, + exact-combinatorics ==0.2.0.11, + exact-pi ==0.5.0.2, + exception-hierarchy ==0.1.0.8, + exception-mtl ==0.4.0.2, + exceptions installed, + exception-transformers ==0.4.0.11, + executable-hash ==0.2.0.4, + executable-path ==0.0.3.1, + exit-codes ==1.0.0, + exomizer ==1.0.0, + experimenter ==0.1.0.14, + expiring-cache-map ==0.0.6.1, + explainable-predicates ==0.1.2.3, + explicit-exception ==0.1.10.1, + exp-pairs ==0.2.1.0, + express ==1.0.10, + extended-reals ==0.2.4.0, + extensible ==0.9, + extensible-effects ==5.0.0.1, + extensible-exceptions ==0.1.1.4, + extra ==1.7.13, + extractable-singleton ==0.0.1, + extrapolate ==0.4.6, + fail ==4.9.0.0, + failable ==1.2.4.0, + fakedata ==1.0.3, + fakedata-parser ==0.1.0.0, + fakedata-quickcheck ==0.2.0, + fakefs ==0.3.0.2, + fakepull ==0.3.0.2, + faktory ==1.1.2.4, + fasta ==0.10.4.2, + fast-logger ==3.1.2, + fast-math ==1.0.2, + fb ==2.1.1.1, + fclabels ==2.0.5.1, + fdo-notify ==0.3.1, + feature-flags ==0.1.0.1, + fedora-dists ==2.1.1, + fedora-haskell-tools ==1.0, + feed ==1.3.2.1, + FenwickTree ==0.1.2.1, + fft ==0.1.8.7, + fftw-ffi ==0.1, + fgl ==5.7.0.3, + fields-json ==0.4.0.0, + filecache ==0.4.1, + file-embed ==0.0.15.0, + file-embed-lzma ==0.0.1, + filelock ==0.1.1.6, + filemanip ==0.3.6.3, + file-modules ==0.1.2.4, + filepath installed, + filepath-bytestring ==1.4.2.1.12, + file-path-th ==0.1.0.0, + filepattern ==0.1.3, + fileplow ==0.1.0.0, + filter-logger ==0.6.0.0, + filtrable ==0.1.6.0, + fin ==0.2.1, + FindBin ==0.0.5, + fingertree ==0.1.5.0, + finite-typelits ==0.1.6.0, + first-class-families ==0.8.0.1, + first-class-patterns ==0.3.2.5, + fitspec ==0.4.10, + fixed ==0.3, + fixed-length ==0.2.3.1, + fixed-vector ==1.2.2.1, + fixed-vector-hetero ==0.6.1.1, + fix-whitespace ==0.0.11, + flac ==0.2.0, + flac-picture ==0.1.2, + flags-applicative ==0.1.0.3, + flat-mcmc ==1.5.2, + flatparse ==0.3.5.1, + flay ==0.4, + flexible-defaults ==0.0.3, + FloatingHex ==0.5, + floatshow ==0.2.4, + flow ==2.0.0.3, + flush-queue ==1.0.0, + fmlist ==0.9.4, + fmt ==0.6.3.0, + fn ==0.3.0.2, + focus ==1.0.3.1, + focuslist ==0.1.1.0, + foldl ==1.4.14, + folds ==0.7.8, + follow-file ==0.0.3, + FontyFruity ==0.5.3.5, + force-layout ==0.4.0.6, + foreign-store ==0.2, + ForestStructures ==0.0.1.1, + forkable-monad ==0.2.0.3, + forma ==1.2.0, + formatn ==0.2.2, + format-numbers ==0.1.0.1, + formatting ==7.1.3, + fortran-src ==0.12.0, + foundation ==0.0.30, + fourmolu ==0.9.0.0, + freckle-app ==1.3.0.0, + free ==5.1.10, + free-categories ==0.2.0.2, + freenect ==1.2.1, + freer-simple ==1.2.1.2, + freetype2 ==0.2.0, + free-vl ==0.1.4, + friendly-time ==0.4.1, + frisby ==0.2.4, + from-sum ==0.2.3.0, + frontmatter ==0.1.0.2, + fsnotify ==0.3.0.1, + fsnotify-conduit ==0.1.1.1, + ftp-client ==0.5.1.4, + funcmp ==1.9, + function-builder ==0.3.0.1, + functor-classes-compat ==2.0.0.2, + fused-effects ==1.1.2.2, + fusion-plugin ==0.2.6, + fusion-plugin-types ==0.1.0, + fuzzcheck ==0.1.1, + fuzzy ==0.1.0.1, + fuzzy-dates ==0.1.1.2, + fuzzyset ==0.2.3, + fuzzy-time ==0.2.0.3, + gauge ==0.2.5, + gd ==3000.7.3, + gdp ==0.0.3.0, + gemini-exports ==0.1.0.0, + general-games ==1.1.1, + generic-aeson ==0.2.0.14, + generic-arbitrary ==1.0.1, + generic-constraints ==1.1.1.1, + generic-data ==1.0.0.1, + generic-data-surgery ==0.3.0.0, + generic-deriving ==1.14.4, + generic-functor ==1.1.0.0, + generic-lens ==2.2.2.0, + generic-lens-core ==2.2.1.0, + generic-monoid ==0.1.0.1, + generic-optics ==2.2.1.0, + GenericPretty ==1.2.2, + generic-random ==1.5.0.1, + generics-eot ==0.4.0.1, + generics-sop ==0.5.1.3, + generics-sop-lens ==0.2.0.1, + genvalidity ==1.1.0.0, + genvalidity-aeson ==1.0.0.1, + genvalidity-appendful ==0.1.0.0, + genvalidity-bytestring ==1.0.0.1, + genvalidity-case-insensitive ==0.0.0.1, + genvalidity-containers ==1.0.0.1, + genvalidity-criterion ==1.1.0.0, + genvalidity-hspec ==1.0.0.2, + genvalidity-hspec-aeson ==1.0.0.0, + genvalidity-hspec-binary ==1.0.0.0, + genvalidity-hspec-cereal ==1.0.0.0, + genvalidity-hspec-hashable ==1.0.0.0, + genvalidity-hspec-optics ==1.0.0.0, + genvalidity-hspec-persistent ==1.0.0.0, + genvalidity-mergeful ==0.3.0.0, + genvalidity-mergeless ==0.3.0.0, + genvalidity-path ==1.0.0.1, + genvalidity-persistent ==1.0.0.1, + genvalidity-property ==1.0.0.0, + genvalidity-scientific ==1.0.0.0, + genvalidity-sydtest ==1.0.0.0, + genvalidity-sydtest-aeson ==1.0.0.0, + genvalidity-sydtest-hashable ==1.0.0.0, + genvalidity-sydtest-lens ==1.0.0.0, + genvalidity-sydtest-persistent ==1.0.0.0, + genvalidity-text ==1.0.0.1, + genvalidity-time ==1.0.0.1, + genvalidity-typed-uuid ==0.1.0.1, + genvalidity-unordered-containers ==1.0.0.0, + genvalidity-uuid ==1.0.0.1, + genvalidity-vector ==1.0.0.0, + geodetics ==0.1.2, + geojson ==4.1.1, + getopt-generics ==0.13.1.0, + ghc installed, + ghc-bignum installed, + ghc-bignum-orphans ==0.1.1, + ghc-byteorder ==4.11.0.0.10, + ghc-check ==0.5.0.8, + ghc-compact ==0.1.0.0, + ghc-core ==0.5.6, + ghc-events ==0.18.0, + ghc-exactprint ==1.5.0, + ghcid ==0.8.7, + ghci-hexcalc ==0.1.1.0, + ghcjs-codemirror ==0.0.0.2, + ghcjs-perch ==0.3.3.3, + ghc-lib ==9.2.7.20230228, + ghc-lib-parser ==9.2.7.20230228, + ghc-lib-parser-ex ==9.2.0.4, + ghc-parser ==0.2.4.0, + ghc-paths ==0.1.0.12, + ghc-prim installed, + ghc-prof ==1.4.1.12, + ghc-source-gen ==0.4.3.0, + ghc-syntax-highlighter ==0.0.8.0, + ghc-tcplugins-extra ==0.4.4, + ghc-trace-events ==0.1.2.7, + ghc-typelits-extra ==0.4.5, + ghc-typelits-knownnat ==0.7.8, + ghc-typelits-natnormalise ==0.7.8, + ghc-typelits-presburger ==0.6.2.0, + ghost-buster ==0.1.1.0, + gi-atk ==2.0.27, + gi-cairo ==1.0.29, + gi-cairo-connector ==0.1.1, + gi-cairo-render ==0.1.2, + gi-dbusmenu ==0.4.13, + gi-dbusmenugtk3 ==0.4.14, + gi-freetype2 ==2.0.4, + gi-gdk ==3.0.28, + gi-gdkpixbuf ==2.0.31, + gi-gdkx11 ==3.0.15, + gi-gio ==2.0.32, + gi-glib ==2.0.29, + gi-gmodule ==2.0.5, + gi-gobject ==2.0.30, + gi-graphene ==1.0.7, + gi-gtk ==3.0.41, + gi-gtk-hs ==0.3.16, + gi-gtksource ==3.0.28, + gi-harfbuzz ==0.0.9, + gi-javascriptcore ==4.0.27, + gio ==0.13.10.0, + gi-pango ==1.0.29, + githash ==0.1.6.3, + github ==0.28.0.1, + github-release ==2.0.0.6, + github-rest ==1.1.3, + github-types ==0.2.1, + github-webhooks ==0.16.0, + gitlab-haskell ==1.0.0.1, + git-lfs ==1.2.0, + gitlib ==3.1.3, + gitrev ==1.3.1, + gi-vte ==2.91.31, + gi-xlib ==2.0.13, + gl ==0.9, + glasso ==0.1.0, + GLFW-b ==3.3.0.0, + glib ==0.13.10.0, + Glob ==0.10.2, + glob-posix ==0.2.0.1, + gloss ==1.13.2.2, + gloss-algorithms ==1.13.0.3, + gloss-examples ==1.13.0.4, + gloss-raster ==1.13.1.2, + gloss-rendering ==1.13.1.2, + GLURaw ==2.0.0.5, + GLUT ==2.7.0.16, + gmail-simple ==0.1.0.4, + gnuplot ==0.5.7, + goldplate ==0.2.1.1, + google-isbn ==1.0.3, + gopher-proxy ==0.1.1.3, + gotyno-hs ==1.1.0, + gpolyline ==0.1.0.1, + graph-core ==0.3.0.0, + graphite ==0.10.0.1, + graphql-client ==1.2.2, + graphs ==0.7.2, + graphula ==2.0.2.2, + graphviz ==2999.20.1.0, + graph-wrapper ==0.2.6.0, + gravatar ==0.8.1, + gridtables ==0.0.3.0, + groom ==0.1.2.1, + grouped-list ==0.2.3.0, + groups ==0.5.3, + gtk ==0.15.8, + gtk2hs-buildtools ==0.13.10.0, + gtk3 ==0.15.8, + gtk-sni-tray ==0.1.8.1, + gtk-strut ==0.1.3.2, + guarded-allocation ==0.0.1, + hackage-cli ==0.0.3.6, + hackage-db ==2.1.3, + hackage-security ==0.6.2.3, + haddock-library ==1.10.0, + hakyll ==4.15.1.1, + hakyll-convert ==0.3.0.4, + hal ==1.0.0.1, + half ==0.3.1, + hall-symbols ==0.1.0.6, + hamlet ==1.2.0, + hamtsolo ==1.0.4, + HandsomeSoup ==0.4.2, + handwriting ==0.1.0.3, + happstack-hsp ==7.3.7.7, + happstack-jmacro ==7.0.12.5, + happstack-server ==7.7.2, + happstack-server-tls ==7.2.1.3, + happy ==1.20.1.1, + happy-meta ==0.2.1.0, + harp ==0.4.3.6, + HasBigDecimal ==0.2.0.0, + hasbolt ==0.1.6.2, + hashable ==1.4.2.0, + hashids ==1.0.2.7, + hashmap ==1.3.3, + hashtables ==1.3.1, + haskeline ==0.8.2.1, + haskell-gi ==0.26.7, + haskell-gi-base ==0.26.4, + haskell-gi-overloading ==1.0, + haskell-lexer ==1.1.1, + HaskellNet ==0.6.1.2, + HaskellNet-SSL ==0.3.4.4, + haskell-src ==1.0.4, + haskell-src-exts ==1.23.1, + haskell-src-exts-simple ==1.23.0.0, + haskell-src-exts-util ==0.2.5, + haskell-src-meta ==0.8.12, + haskey-btree ==0.3.0.1, + haskintex ==0.8.0.1, + haskoin-core ==0.21.2, + haskoin-store-data ==0.65.5, + hasktags ==0.72.0, + hasql ==1.6.3, + hasql-dynamic-statements ==0.3.1.2, + hasql-implicits ==0.1.1, + hasql-migration ==0.3.0, + hasql-notifications ==0.2.0.5, + hasql-optparse-applicative ==0.5, + hasql-pool ==0.8.0.7, + hasql-queue ==1.2.0.2, + hasql-th ==0.4.0.18, + hasql-transaction ==1.0.1.2, + has-transformers ==0.1.0.4, + hasty-hamiltonian ==1.3.4, + HaTeX ==3.22.3.2, + HaXml ==1.25.12, + haxr ==3000.11.5, + HCodecs ==0.5.2, + hdaemonize ==0.5.6, + HDBC ==2.4.0.4, + HDBC-session ==0.1.2.0, + headed-megaparsec ==0.2.1.1, + heap ==1.0.4, + heaps ==0.4, + heatshrink ==0.1.0.0, + hebrew-time ==0.1.2, + hedgehog ==1.1.2, + hedgehog-classes ==0.2.5.4, + hedgehog-corpus ==0.2.0, + hedgehog-fakedata ==0.0.1.5, + hedgehog-fn ==1.0, + hedgehog-quickcheck ==0.1.1, + hedis ==0.15.2, + hedn ==0.3.0.4, + here ==1.2.13, + heredoc ==0.2.0.0, + heterocephalus ==1.0.5.7, + hex ==0.2.0, + hexml ==0.3.4, + hexml-lens ==0.2.2, + hexpat ==0.20.13, + hex-text ==0.1.0.8, + hformat ==0.3.3.1, + hfsevents ==0.1.6, + hgeometry ==0.14, + hgeometry-combinatorial ==0.14, + hidapi ==0.1.8, + hie-bios ==0.9.1, + hierarchical-clustering ==0.4.7, + hi-file-parser ==0.1.4.0, + highlighting-kate ==0.6.4, + hindent ==5.3.4, + hinfo ==0.0.3.0, + hinotify ==0.4.1, + hint ==0.9.0.7, + hip ==1.5.6.0, + histogram-fill ==0.9.1.0, + hjsmin ==0.2.0.4, + hkd-default ==1.1.0.0, + hkgr ==0.4.2, + hledger ==1.27.1, + hledger-interest ==1.6.5, + hledger-lib ==1.27.1, + hledger-stockquotes ==0.1.2.1, + hledger-ui ==1.27.1, + hledger-web ==1.27.1, + hlibcpuid ==0.2.0, + hlibgit2 ==0.18.0.16, + hlibsass ==0.1.10.1, + hlint ==3.4.1, + hmatrix ==0.20.2, + hmatrix-gsl ==0.19.0.1, + hmatrix-gsl-stats ==0.4.1.8, + hmatrix-morpheus ==0.1.1.2, + hmatrix-repa ==0.1.2.2, + hmatrix-special ==0.19.0.0, + hmatrix-vector-sized ==0.1.3.0, + HMock ==0.5.1.0, + hnock ==0.4.0, + hoauth2 ==2.6.0, + hoogle ==5.0.18.3, + hopenssl ==2.2.5, + hopfli ==0.2.2.1, + horizontal-rule ==0.5.0.0, + hosc ==0.19.1, + hostname ==1.0, + hostname-validate ==1.0.0, + hourglass ==0.2.12, + hourglass-orphans ==0.1.0.0, + hp2pretty ==0.10, + hpack ==0.35.2, + hpack-dhall ==0.5.7, + hpc installed, + hpc-codecov ==0.3.0.0, + hpc-lcov ==1.1.1, + HPDF ==1.6.1, + hpp ==0.6.5, + hpqtypes ==1.9.4.0, + hreader ==1.1.0, + hreader-lens ==0.1.3.0, + hruby ==0.5.0.0, + hsass ==0.8.0, + hs-bibutils ==6.10.0.0, + hsc2hs ==0.68.9, + hscolour ==1.24.4, + hsdns ==1.8, + hse-cpp ==0.2, + hsemail ==2.2.1, + hset ==2.2.0, + hs-GeoIP ==0.3, + hsignal ==0.2.7.5, + hsini ==0.5.1.2, + hsinstall ==2.7, + HSlippyMap ==3.0.1, + hslogger ==1.3.1.0, + hslua ==2.2.1, + hslua-aeson ==2.2.1, + hslua-classes ==2.2.0, + hslua-core ==2.2.1, + hslua-marshalling ==2.2.1, + hslua-module-doclayout ==1.0.4, + hslua-module-path ==1.0.3, + hslua-module-system ==1.0.3, + hslua-module-text ==1.0.3.1, + hslua-module-version ==1.0.3, + hslua-objectorientation ==2.2.1, + hslua-packaging ==2.2.1, + hsndfile ==0.8.0, + hsndfile-vector ==0.5.2, + HsOpenSSL ==0.11.7.5, + HsOpenSSL-x509-system ==0.1.0.4, + hsp ==0.10.0, + hspec ==2.9.7, + hspec-attoparsec ==0.1.0.2, + hspec-checkers ==0.1.0.2, + hspec-contrib ==0.5.2, + hspec-core ==2.9.7, + hspec-discover ==2.9.7, + hspec-expectations ==0.8.2, + hspec-expectations-json ==1.0.0.7, + hspec-expectations-lifted ==0.10.0, + hspec-expectations-pretty-diff ==0.7.2.6, + hspec-golden ==0.2.1.0, + hspec-golden-aeson ==0.9.0.0, + hspec-hedgehog ==0.0.1.2, + hspec-junit-formatter ==1.1.0.2, + hspec-leancheck ==0.0.6, + hspec-megaparsec ==2.2.0, + hspec-meta ==2.9.3, + hspec-need-env ==0.1.0.10, + hspec-parsec ==0, + hspec-smallcheck ==0.5.2, + hspec-tmp-proc ==0.5.1.2, + hspec-wai ==0.11.1, + hspec-wai-json ==0.11.0, + hs-php-session ==0.0.9.3, + hsshellscript ==3.5.0, + hstatistics ==0.3.1, + HStringTemplate ==0.8.8, + HSvm ==0.1.1.3.25, + hsx2hs ==0.14.1.11, + hsx-jmacro ==7.3.8.2, + HsYAML ==0.2.1.1, + HsYAML-aeson ==0.2.0.1, + hsyslog ==5.0.2, + htaglib ==1.2.0, + HTF ==0.15.0.1, + html ==1.0.1.2, + html-conduit ==1.3.2.2, + html-email-validate ==0.2.0.0, + html-entities ==1.1.4.6, + html-entity-map ==0.1.0.0, + htoml-megaparsec ==2.1.0.4, + htoml-parse ==0.1.0.1, + HTTP ==4000.4.1, + http2 ==3.0.3, + http-api-data ==0.4.3, + http-api-data-qq ==0.1.0.0, + http-client ==0.7.13.1, + http-client-openssl ==0.3.3, + http-client-overrides ==0.1.1.0, + http-client-restricted ==0.0.5, + http-client-tls ==0.3.6.1, + http-common ==0.8.3.4, + http-conduit ==2.3.8.1, + http-date ==0.0.11, + http-directory ==0.1.10, + http-download ==0.2.0.0, + httpd-shed ==0.4.1.1, + http-io-streams ==0.1.6.2, + http-link-header ==1.2.1, + http-media ==0.8.0.0, + http-query ==0.1.3, + http-reverse-proxy ==0.6.0.1, + http-streams ==0.8.9.6, + http-types ==0.12.3, + human-readable-duration ==0.2.1.4, + HUnit ==1.6.2.0, + HUnit-approx ==1.1.1.1, + hunit-dejafu ==2.0.0.6, + hvect ==0.4.0.1, + hvega ==0.12.0.3, + hw-balancedparens ==0.4.1.3, + hw-bits ==0.7.2.2, + hw-conduit ==0.2.1.1, + hw-conduit-merges ==0.2.1.0, + hw-diagnostics ==0.0.1.0, + hw-dsv ==0.4.1.1, + hweblib ==0.6.3, + hw-eliasfano ==0.1.2.1, + hw-excess ==0.2.3.0, + hw-fingertree ==0.1.2.1, + hw-fingertree-strict ==0.1.2.1, + hw-hedgehog ==0.1.1.1, + hw-hspec-hedgehog ==0.1.1.1, + hw-int ==0.0.2.0, + hw-ip ==2.4.2.1, + hw-json ==1.3.2.4, + hw-json-simd ==0.1.1.2, + hw-json-simple-cursor ==0.1.1.1, + hw-json-standard-cursor ==0.2.3.2, + hwk ==0.6, + hw-kafka-client ==4.0.3, + hw-mquery ==0.2.1.1, + hworker ==0.1.0.1, + hw-packed-vector ==0.2.1.1, + hw-parser ==0.1.1.0, + hw-prim ==0.6.3.2, + hw-rankselect ==0.13.4.1, + hw-rankselect-base ==0.3.4.1, + hw-simd ==0.1.2.2, + hw-streams ==0.0.1.0, + hw-string-parse ==0.0.0.5, + hw-succinct ==0.1.0.1, + hw-xml ==0.5.1.1, + hxt ==9.3.1.22, + hxt-charproperties ==9.5.0.0, + hxt-css ==0.1.0.3, + hxt-curl ==9.1.1.1, + hxt-expat ==9.1.1, + hxt-http ==9.1.5.2, + hxt-regex-xmlschema ==9.2.0.7, + hxt-tagsoup ==9.1.4, + hxt-unicode ==9.0.2.4, + hybrid-vectors ==0.2.3, + hyperloglog ==0.4.6, + hyphenation ==0.8.2, + identicon ==0.2.2, + ieee754 ==0.8.0, + if ==0.1.0.0, + IfElse ==0.85, + ihaskell ==0.10.3.0, + ihaskell-hvega ==0.5.0.3, + ihs ==0.1.0.3, + ilist ==0.4.0.1, + imagesize-conduit ==1.1, + Imlib ==0.1.2, + immortal ==0.3, + immortal-queue ==0.1.0.1, + inbox ==0.2.0, + include-file ==0.1.0.4, + incremental ==0.3.1, + incremental-parser ==0.5.0.5, + indents ==0.5.0.1, + indexed ==0.1.3, + indexed-containers ==0.1.0.2, + indexed-list-literals ==0.2.1.3, + indexed-profunctors ==0.1.1, + indexed-traversable ==0.1.2.1, + indexed-traversable-instances ==0.1.1.2, + infer-license ==0.2.0, + inflections ==0.4.0.6, + influxdb ==1.9.2.2, + ini ==0.4.2, + inj ==1.0, + inline-c ==0.9.1.8, + inline-c-cpp ==0.5.0.0, + inliterate ==0.1.0, + input-parsers ==0.2.3.2, + insert-ordered-containers ==0.2.5.2, + inspection-testing ==0.4.6.1, + instance-control ==0.1.2.0, + integer-gmp installed, + integer-logarithms ==1.0.3.1, + integer-roots ==1.0.2.0, + integration ==0.2.1, + intern ==0.9.4, + interpolate ==0.2.1, + interpolatedstring-perl6 ==1.0.2, + interpolation ==0.1.1.2, + Interpolation ==0.3.0, + IntervalMap ==0.6.2.1, + intervals ==0.9.2, + intset-imperative ==0.1.0.0, + invariant ==0.6.1, + invert ==1.0.0.2, + invertible-grammar ==0.1.3.4, + io-machine ==0.2.0.0, + io-manager ==0.1.0.4, + io-memoize ==1.1.1.0, + io-region ==0.1.1, + io-storage ==0.3, + io-streams ==1.5.2.2, + io-streams-haproxy ==1.0.1.0, + ip ==1.7.6, + ip6addr ==1.0.3, + iproute ==1.7.12, + IPv6Addr ==2.0.5, + ipynb ==0.2, + ipython-kernel ==0.10.3.0, + irc ==0.6.1.0, + irc-ctcp ==0.1.3.1, + isbn ==1.1.0.4, + islink ==0.1.0.0, + iso3166-country-codes ==0.20140203.8, + iso639 ==0.1.0.3, + iso8601-time ==0.1.5, + isocline ==1.0.9, + isomorphism-class ==0.1.0.9, + iterable ==3.0, + ixset ==1.1.1.2, + ixset-typed ==0.5.1.0, + ixset-typed-binary-instance ==0.1.0.2, + ixset-typed-conversions ==0.1.2.0, + ixset-typed-hashable-instance ==0.1.0.2, + ix-shapable ==0.1.0, + jailbreak-cabal ==1.3.6, + jalaali ==1.0.0.0, + java-adt ==0.2018.11.4, + jira-wiki-markup ==1.4.0, + jl ==0.1.0, + jmacro ==0.6.18, + jose ==0.9, + jose-jwt ==0.9.5, + js-chart ==2.9.4.1, + js-dgtable ==0.5.2, + js-flot ==0.8.3, + js-jquery ==3.3.1, + json ==0.10, + json-feed ==2.0.0.8, + jsonifier ==0.2.1.2, + jsonpath ==0.3.0.0, + json-rpc ==1.0.4, + json-stream ==0.4.5.2, + JuicyPixels ==3.3.7, + JuicyPixels-extra ==0.5.2, + JuicyPixels-scale-dct ==0.1.2, + junit-xml ==0.1.0.2, + justified-containers ==0.3.0.0, + jwt ==0.11.0, + kan-extensions ==5.2.5, + kanji ==3.5.0, + kansas-comet ==0.4.1, + katip ==0.8.7.4, + katip-logstash ==0.1.0.2, + katip-wai ==0.1.2.1, + kazura-queue ==0.1.0.4, + kdt ==0.2.5, + keep-alive ==0.2.1.0, + keycode ==0.2.2, + keys ==3.12.3, + ki ==1.0.1.0, + kind-apply ==0.3.2.1, + kind-generics ==0.4.1.4, + kind-generics-th ==0.2.2.3, + ki-unlifted ==1.0.0.1, + kleene ==0.1, + kmeans ==0.1.3, + knob ==0.2.2, + koji ==0.0.2, + l10n ==0.1.0.1, + labels ==0.3.3, + lackey ==2.0.0.6, + LambdaHack ==0.11.0.0, + lame ==0.2.0, + language-avro ==0.1.4.0, + language-bash ==0.9.2, + language-c ==0.9.2, + language-c-quote ==0.13.0.1, + language-docker ==12.0.0, + language-dot ==0.1.1, + language-glsl ==0.3.0, + language-java ==0.2.9, + language-javascript ==0.7.1.0, + language-nix ==2.2.0, + language-protobuf ==1.0.1, + language-python ==0.5.8, + language-thrift ==0.12.0.1, + lapack-carray ==0.0.3, + lapack-comfort-array ==0.0.1, + lapack-ffi ==0.0.3, + lapack-ffi-tools ==0.1.3.1, + largeword ==1.2.5, + latex ==0.1.0.4, + lattices ==2.0.3, + lawful ==0.1.0.0, + lazy-csv ==0.5.1, + lazyio ==0.1.0.4, + lazysmallcheck ==0.6, + lca ==0.4, + leancheck ==0.9.12, + leancheck-instances ==0.0.5, + leapseconds-announced ==2017.1.0.1, + learn-physics ==0.6.5, + leb128-cereal ==1.2, + lens ==5.1.1, + lens-action ==0.2.6, + lens-aeson ==1.2.2, + lens-csv ==0.1.1.0, + lens-family ==2.1.2, + lens-family-core ==2.1.2, + lens-family-th ==0.5.2.1, + lens-misc ==0.0.2.0, + lens-properties ==4.11.1, + lens-regex ==0.1.3, + lens-regex-pcre ==1.1.0.0, + lentil ==1.5.5.4, + LetsBeRational ==1.0.0.0, + leveldb-haskell ==0.6.5, + lexer-applicative ==2.1.0.2, + libBF ==0.6.5.1, + libffi ==0.2.1, + libgit ==0.3.1, + libgraph ==1.14, + libmpd ==0.10.0.0, + liboath-hs ==0.0.1.2, + libyaml ==0.1.2, + lifted-async ==0.10.2.4, + lifted-base ==0.2.3.12, + lift-generics ==0.2.1, + lift-type ==0.1.1.1, + line ==4.0.1, + linear ==1.21.10, + linear-base ==0.3.1, + linear-generics ==0.2.1, + linebreak ==1.1.0.4, + linenoise ==0.3.2, + linux-capabilities ==0.1.1.0, + linux-file-extents ==0.2.0.0, + linux-namespaces ==0.1.3.0, + List ==0.6.2, + ListLike ==4.7.8, + list-predicate ==0.1.0.1, + listsafe ==0.1.0.1, + list-t ==1.0.5.6, + list-transformer ==1.0.9, + ListTree ==0.2.3, + ListZipper ==1.2.0.2, + literatex ==0.2.1.0, + little-logger ==1.0.1, + little-rio ==1.0.1, + lmdb ==0.2.5, + load-env ==0.2.1.0, + loc ==0.1.4.1, + locators ==0.3.0.3, + loch-th ==0.2.2, + lockfree-queue ==0.2.4, + log-domain ==0.13.2, + logfloat ==0.13.4, + logger-thread ==0.1.0.2, + logging ==3.0.5, + logging-effect ==1.3.13, + logging-facade ==0.3.1, + logging-facade-syslog ==1, + logict ==0.8.0.0, + logstash ==0.1.0.3, + loop ==0.3.0, + lpeg ==1.0.4, + LPFP ==1.1, + lrucache ==1.2.0.1, + lrucaching ==0.3.3, + lsp ==1.6.0.0, + lsp-types ==1.6.0.0, + lua ==2.2.1, + lua-arbitrary ==1.0.1.1, + lucid ==2.11.20230408, + lucid2 ==0.0.20221012, + lucid-cdn ==0.2.2.0, + lucid-extras ==0.2.2, + lukko ==0.1.1.3, + lxd-client-config ==0.1.0.1, + lz4 ==0.2.3.1, + lz4-frame-conduit ==0.1.0.1, + lzma ==0.0.1.0, + lzma-clib ==5.2.2, + lzma-conduit ==1.2.3, + machines ==0.7.3, + magic ==1.1, + mainland-pretty ==0.7.1, + main-tester ==0.2.0.1, + managed ==1.0.10, + mandrill ==0.5.7.0, + map-syntax ==0.3, + markdown ==0.1.17.5, + markdown-unlit ==0.5.1, + markov-chain ==0.0.3.4, + markov-chain-usage-model ==0.0.0, + mason ==0.2.6, + massiv ==1.0.4.0, + massiv-io ==1.0.0.1, + massiv-persist ==1.0.0.3, + massiv-serialise ==1.0.0.2, + massiv-test ==1.0.0.0, + mathexpr ==0.3.1.0, + math-extras ==0.1.1.0, + math-functions ==0.3.4.2, + mathlist ==0.1.0.4, + matplotlib ==0.7.7, + matrices ==0.5.0, + matrix ==0.3.6.1, + matrix-as-xyz ==0.1.2.2, + matrix-market-attoparsec ==0.1.1.3, + matrix-static ==0.3, + maximal-cliques ==0.1.1, + mcmc ==0.8.2.0, + mcmc-types ==1.0.3, + median-stream ==0.7.0.0, + med-module ==0.1.3, + megaparsec ==9.2.2, + megaparsec-tests ==9.2.2, + mega-sdist ==0.4.2.1, + membership ==0.0.1, + memcache ==0.3.0.1, + memfd ==1.0.1.3, + memory ==0.17.0, + MemoTrie ==0.6.10, + mergeful ==0.3.0.0, + mergeful-persistent ==0.1.0.0, + mergeless ==0.4.0.0, + mergeless-persistent ==0.1.0.0, + merkle-tree ==0.1.1, + mersenne-random ==1.0.0.1, + mersenne-random-pure64 ==0.2.2.0, + messagepack ==0.5.5, + metrics ==0.4.1.1, + mfsolve ==0.3.2.1, + microaeson ==0.1.0.1, + microlens ==0.4.12.0, + microlens-aeson ==2.5.0, + microlens-contra ==0.1.0.3, + microlens-ghc ==0.4.13.2, + microlens-mtl ==0.2.0.3, + microlens-platform ==0.4.2.1, + microlens-process ==0.2.0.2, + microlens-th ==0.4.3.13, + microspec ==0.2.1.3, + microstache ==1.0.2.3, + midair ==0.2.0.1, + midi ==0.2.2.4, + midi-music-box ==0.0.1.2, + mighty-metropolis ==2.0.0, + mime-mail ==0.5.1, + mime-mail-ses ==0.4.3, + mime-types ==0.1.0.9, + minimal-configuration ==0.1.4, + minimorph ==0.3.0.1, + minio-hs ==1.6.0, + minisat-solver ==0.1, + miniutter ==0.5.1.2, + min-max-pqueue ==0.1.0.2, + mintty ==0.1.4, + misfortune ==0.1.2.1, + missing-foreign ==0.1.1, + MissingH ==1.5.0.1, + mixed-types-num ==0.5.11, + mmap ==0.5.9, + mmark ==0.0.7.6, + mmark-cli ==0.0.5.1, + mmark-ext ==0.2.1.5, + mmorph ==1.2.0, + mnist-idx ==0.1.3.2, + mnist-idx-conduit ==0.4.0.0, + mockery ==0.3.5, + mock-time ==0.1.0, + mod ==0.1.2.2, + model ==0.5, + modern-uri ==0.3.6.0, + modular ==0.1.0.8, + monad-chronicle ==1.0.1, + monad-control ==1.0.3.1, + monad-coroutine ==0.9.2, + monad-extras ==0.6.0, + monadic-arrays ==0.2.2, + monad-journal ==0.8.1, + monadlist ==0.0.2, + monadloc ==0.7.1, + monad-logger ==0.3.40, + monad-logger-aeson ==0.4.0.4, + monad-logger-json ==0.1.0.0, + monad-logger-logstash ==0.2.0.2, + monad-logger-prefix ==0.1.12, + monad-loops ==0.4.3, + monad-memo ==0.5.4, + monad-metrics ==0.2.2.0, + monadoid ==0.0.3, + monadology ==0.1, + monad-par ==0.3.5, + monad-parallel ==0.8, + monad-par-extras ==0.3.3, + monad-peel ==0.2.1.2, + monad-primitive ==0.1, + monad-products ==4.0.1, + MonadPrompt ==1.0.0.5, + MonadRandom ==0.5.3, + monad-resumption ==0.1.4.0, + monad-schedule ==0.1.2.0, + monad-skeleton ==0.2, + monad-st ==0.2.4.1, + monads-tf ==0.1.0.3, + monad-time ==0.3.1.0, + mongoDB ==2.7.1.2, + monoidal-containers ==0.6.4.0, + monoid-extras ==0.6.2, + monoid-subclasses ==1.1.3, + monoid-transformer ==0.0.4, + monomer ==1.5.1.0, + mono-traversable ==1.0.15.3, + mono-traversable-instances ==0.1.1.0, + mono-traversable-keys ==0.2.0, + more-containers ==0.2.2.2, + morpheus-graphql ==0.27.3, + morpheus-graphql-app ==0.27.3, + morpheus-graphql-client ==0.27.3, + morpheus-graphql-code-gen ==0.27.3, + morpheus-graphql-code-gen-utils ==0.27.3, + morpheus-graphql-core ==0.27.3, + morpheus-graphql-server ==0.27.3, + morpheus-graphql-subscriptions ==0.27.3, + morpheus-graphql-tests ==0.27.3, + moss ==0.2.0.1, + mountpoints ==1.0.2, + mpi-hs ==0.7.2.0, + mpi-hs-binary ==0.1.1.0, + mpi-hs-cereal ==0.1.0.0, + mstate ==0.2.8, + mtl installed, + mtl-compat ==0.2.2, + mtl-prelude ==2.0.3.2, + multiarg ==0.30.0.10, + multi-containers ==0.2, + multimap ==1.2.1, + multiset ==0.3.4.3, + multistate ==0.8.0.4, + murmur3 ==1.0.5, + murmur-hash ==0.1.0.10, + MusicBrainz ==0.4.1, + mustache ==2.4.2, + mutable-containers ==0.3.4.1, + mwc-probability ==2.3.1, + mwc-random ==0.15.0.2, + mwc-random-monad ==0.7.3.1, + mx-state-codes ==1.0.0.0, + mysql ==0.2.1, + mysql-simple ==0.4.9, + n2o ==0.11.1, + n2o-nitro ==0.11.2, + nagios-check ==0.3.2, + named ==0.3.0.1, + names-th ==0.3.0.1, + nano-erl ==0.1.0.1, + NanoID ==3.2.1, + nanospec ==0.2.2, + nanovg ==0.8.1.0, + nats ==1.1.2, + natural-arithmetic ==0.1.4.0, + natural-induction ==0.2.0.0, + natural-sort ==0.1.2, + natural-transformation ==0.4, + ndjson-conduit ==0.1.0.5, + neat-interpolation ==0.5.1.3, + netcode-io ==0.0.3, + netlib-carray ==0.1, + netlib-comfort-array ==0.0.0.2, + netlib-ffi ==0.1.1, + net-mqtt ==0.8.3.0, + net-mqtt-lens ==0.1.1.0, + netpbm ==1.0.4, + netrc ==0.2.0.0, + netwire ==5.0.3, + netwire-input ==0.0.7, + netwire-input-glfw ==0.0.11, + network ==3.1.4.0, + network-bsd ==2.8.1.0, + network-byte-order ==0.1.6, + network-conduit-tls ==1.3.2, + network-info ==0.2.1, + network-ip ==0.3.0.3, + network-messagepack-rpc ==0.1.2.0, + network-messagepack-rpc-websocket ==0.1.1.1, + network-multicast ==0.3.2, + Network-NineP ==0.4.7.2, + network-run ==0.2.5, + network-simple ==0.4.5, + network-simple-tls ==0.4.1, + network-transport ==0.5.6, + network-uri ==2.6.4.2, + network-wait ==0.2.0.0, + newtype ==0.2.2.0, + newtype-generics ==0.6.2, + nfc ==0.1.1, + nicify-lib ==1.0.1, + NineP ==0.0.2.1, + nix-derivation ==1.1.2, + nix-paths ==1.0.1, + NoHoed ==0.1.1, + nonce ==1.0.7, + nondeterminism ==1.5, + non-empty ==0.3.3, + nonempty-containers ==0.3.4.4, + nonemptymap ==0.0.6.0, + non-empty-sequence ==0.2.0.4, + nonempty-vector ==0.2.2.0, + nonempty-zipper ==1.0.0.4, + non-negative ==0.1.2, + normaldistribution ==1.1.0.3, + normalization-insensitive ==2.0.2, + not-gloss ==0.7.7.0, + no-value ==1.0.0.0, + nowdoc ==0.1.1.0, + nqe ==0.6.4, + nsis ==0.3.3, + numbers ==3000.2.0.2, + numeric-extras ==0.1, + numeric-limits ==0.1.0.0, + numeric-prelude ==0.4.4, + numeric-quest ==0.2.0.2, + numhask ==0.10.1.1, + numhask-array ==0.10.2, + numhask-space ==0.10.0.1, + NumInstances ==1.4, + numtype-dk ==0.5.0.3, + nuxeo ==0.3.2, + nvim-hs ==2.3.2.3, + nvim-hs-contrib ==2.0.0.2, + nvim-hs-ghcid ==2.0.1.0, + oauthenticated ==0.3.0.0, + ObjectName ==1.1.0.2, + oblivious-transfer ==0.1.0, + ochintin-daicho ==0.3.4.2, + o-clock ==1.3.0, + ofx ==0.4.4.0, + old-locale ==1.0.0.7, + old-time ==1.1.0.3, + once ==0.4, + one-liner ==2.1, + one-liner-instances ==0.1.3.0, + OneTuple ==0.3.1, + Only ==0.1, + oo-prototypes ==0.1.0.0, + opaleye ==0.9.7.0, + OpenAL ==1.7.0.5, + openapi3 ==3.2.3, + open-browser ==0.2.1.0, + openexr-write ==0.1.0.2, + OpenGL ==3.0.3.0, + OpenGLRaw ==3.3.4.1, + openpgp-asciiarmor ==0.1.2, + opensource ==0.1.1.0, + openssl-streams ==1.2.3.0, + opentelemetry ==0.8.0, + opentelemetry-extra ==0.8.0, + opentelemetry-lightstep ==0.8.0, + opentelemetry-wai ==0.8.0, + open-witness ==0.6, + operational ==0.2.4.2, + operational-class ==0.3.0.0, + opml-conduit ==0.9.0.0, + optics ==0.4.2, + optics-core ==0.4.1, + optics-extra ==0.4.2.1, + optics-th ==0.4.1, + optics-vl ==0.2.1, + optima ==0.4.0.4, + optional-args ==1.0.2, + options ==1.2.1.1, + optparse-applicative ==0.17.1.0, + optparse-enum ==1.0.0.0, + optparse-generic ==1.4.9, + optparse-simple ==0.1.1.4, + optparse-text ==0.1.1.0, + OrderedBits ==0.0.2.0, + ordered-containers ==0.2.3, + ormolu ==0.5.0.1, + overhang ==1.0.0, + packcheck ==0.6.0, + pager ==0.1.1.0, + pagination ==0.2.2, + pagure ==0.1.1, + pagure-cli ==0.2.1, + palette ==0.3.0.2, + pandoc ==2.19.2, + pandoc-csv2table ==1.0.9, + pandoc-dhall-decoder ==0.1.0.1, + pandoc-lua-marshal ==0.1.7, + pandoc-plot ==1.5.5, + pandoc-throw ==0.1.0.0, + pandoc-types ==1.22.2.1, + pango ==0.13.10.0, + pantry ==0.5.7, + parallel ==3.2.2.0, + parallel-io ==0.3.5, + parameterized ==0.5.0.0, + parseargs ==0.2.0.9, + parsec installed, + parsec-class ==1.0.0.0, + parsec-numbers ==0.1.0, + parsec-numeric ==0.1.0.0, + ParsecTools ==0.0.2.0, + parser-combinators ==1.3.0, + parser-combinators-tests ==1.3.0, + parsers ==0.12.11, + partial-handler ==1.0.3, + partial-isomorphisms ==0.2.3.0, + partial-order ==0.2.0.0, + partial-semigroup ==0.6.0.1, + password ==3.0.2.1, + password-instances ==3.0.0.0, + password-types ==1.0.0.0, + path ==0.9.2, + path-binary-instance ==0.1.0.1, + path-dhall-instance ==0.2.1.0, + path-extensions ==0.1.1.0, + path-extra ==0.2.0, + path-formatting ==0.1.0.0, + path-io ==1.7.0, + path-like ==0.2.0.2, + path-pieces ==0.2.1, + path-text-utf8 ==0.0.1.11, + pathtype ==0.8.1.2, + path-utils ==0.1.1.0, + pathwalk ==0.3.1.2, + pattern-arrows ==0.0.2, + pava ==0.1.1.4, + pcf-font ==0.2.2.1, + pcg-random ==0.1.4.0, + pcre2 ==2.1.1.1, + pcre-heavy ==1.0.0.3, + pcre-light ==0.4.1.0, + pcre-utils ==0.1.9, + pdc ==0.1.1, + pdf-toolbox-content ==0.1.1, + pdf-toolbox-core ==0.1.1, + pdf-toolbox-document ==0.1.2, + peano ==0.1.0.1, + pedersen-commitment ==0.2.0, + pem ==0.2.4, + percent-format ==0.0.2, + peregrin ==0.3.3, + perfect-hash-generator ==1.0.0, + persist ==0.1.1.5, + persistent ==2.13.3.5, + persistent-discover ==0.1.0.6, + persistent-documentation ==0.1.0.4, + persistent-iproute ==0.2.5, + persistent-mongoDB ==2.13.0.1, + persistent-mysql ==2.13.1.4, + persistent-pagination ==0.1.1.2, + persistent-postgresql ==2.13.5.2, + persistent-qq ==2.12.0.2, + persistent-redis ==2.13.0.1, + persistent-refs ==0.4, + persistent-sqlite ==2.13.1.1, + persistent-template ==2.12.0.0, + persistent-test ==2.13.1.2, + persistent-typed-db ==0.1.0.7, + pg-harness-client ==0.6.0, + pgp-wordlist ==0.1.0.3, + pg-transact ==0.3.2.0, + phantom-state ==0.2.1.2, + phatsort ==0.5.0.1, + picosat ==0.1.6, + pid1 ==0.1.3.1, + pinch ==0.4.3.0, + pipes ==4.3.16, + pipes-attoparsec ==0.5.1.5, + pipes-bytestring ==2.1.7, + pipes-concurrency ==2.0.14, + pipes-csv ==1.4.3, + pipes-extras ==1.0.15, + pipes-fastx ==0.3.0.0, + pipes-fluid ==0.6.0.1, + pipes-group ==1.0.12, + pipes-mongodb ==0.1.0.0, + pipes-ordered-zip ==1.2.1, + pipes-parse ==3.0.9, + pipes-random ==1.0.0.5, + pipes-safe ==2.3.4, + pipes-text ==1.0.1, + pipes-wai ==3.2.0, + pkgtreediff ==0.6.0, + place-cursor-at ==1.0.1, + placeholders ==0.1, + plaid ==0.1.0.4, + plot ==0.2.3.11, + plotlyhs ==0.2.3, + Plural ==0.0.2, + pointed ==5.0.4, + pointedlist ==0.6.1, + pointless-fun ==1.1.0.8, + poll ==0.0.0.2, + poly ==0.5.1.0, + poly-arity ==0.1.0, + polynomials-bernstein ==1.1.2, + polyparse ==1.13, + polysemy ==1.7.1.0, + polysemy-extra ==0.2.1.0, + polysemy-fs ==0.1.0.0, + polysemy-kvstore ==0.1.3.0, + polysemy-methodology ==0.2.2.0, + polysemy-plugin ==0.4.5.0, + polysemy-several ==0.1.1.0, + polysemy-webserver ==0.2.1.1, + polysemy-zoo ==0.8.1.0, + pontarius-xmpp ==0.5.6.6, + pooled-io ==0.0.2.3, + portable-lines ==0.1, + port-utils ==0.2.1.0, + posix-paths ==0.3.0.0, + posix-pty ==0.2.2, + possibly ==1.0.0.0, + postgres-options ==0.2.0.0, + postgresql-binary ==0.13.1, + postgresql-libpq ==0.9.5.0, + postgresql-libpq-notify ==0.2.0.0, + postgresql-migration ==0.2.1.7, + postgresql-query ==3.10.0, + postgresql-schema ==0.1.14, + postgresql-simple ==0.6.4, + postgresql-simple-url ==0.2.1.0, + postgresql-syntax ==0.4.1, + postgresql-typed ==0.6.2.2, + post-mess-age ==0.2.1.0, + pptable ==0.3.0.0, + pqueue ==1.4.3.0, + prefix-units ==0.2.0, + prelude-compat ==0.0.0.2, + prelude-safeenum ==0.1.1.3, + pretty installed, + pretty-class ==1.0.1.1, + prettyclass ==1.0.0.0, + pretty-diff ==0.4.0.3, + pretty-hex ==1.1, + prettyprinter ==1.7.1, + prettyprinter-ansi-terminal ==1.1.3, + prettyprinter-combinators ==0.1.1.1, + prettyprinter-compat-annotated-wl-pprint ==1.1, + prettyprinter-compat-ansi-wl-pprint ==1.0.2, + prettyprinter-compat-wl-pprint ==1.0.1, + prettyprinter-convert-ansi-wl-pprint ==1.1.2, + pretty-relative-time ==0.3.0.0, + pretty-show ==1.10, + pretty-simple ==4.1.2.0, + pretty-sop ==0.2.0.3, + pretty-terminal ==0.1.0.0, + pretty-types ==0.4.0.0, + primes ==0.2.1.0, + primitive ==0.7.3.0, + primitive-addr ==0.1.0.2, + primitive-extras ==0.10.1.6, + primitive-offset ==0.2.0.0, + primitive-unaligned ==0.1.1.2, + primitive-unlifted ==0.1.3.1, + prim-uniq ==0.2, + print-console-colors ==0.1.0.0, + probability ==0.2.8, + process installed, + process-extras ==0.7.4, + product-profunctors ==0.11.1.1, + profiterole ==0.1, + profiteur ==0.4.6.1, + profunctors ==5.6.2, + projectroot ==0.2.0.1, + project-template ==0.2.1.0, + prometheus ==2.2.3, + prometheus-client ==1.1.0, + prometheus-metrics-ghc ==1.0.1.2, + prometheus-wai-middleware ==1.0.1.0, + promises ==0.3, + prompt ==0.1.1.2, + prospect ==0.1.0.0, + protobuf ==0.2.1.3, + protobuf-simple ==0.1.1.1, + protocol-radius ==0.0.1.1, + protocol-radius-test ==0.1.0.1, + proto-lens ==0.7.1.3, + proto-lens-arbitrary ==0.1.2.11, + proto-lens-optparse ==0.1.1.10, + proto-lens-protobuf-types ==0.7.1.2, + proto-lens-protoc ==0.7.1.1, + proto-lens-runtime ==0.7.0.4, + proto-lens-setup ==0.4.0.6, + protolude ==0.3.3, + proxied ==0.3.1, + psql-helpers ==0.1.0.0, + psqueues ==0.2.7.3, + pthread ==0.2.1, + ptr ==0.16.8.4, + ptr-poker ==0.1.2.8, + pulse-simple ==0.1.14, + pureMD5 ==2.1.4, + purescript-bridge ==0.14.0.0, + pusher-http-haskell ==2.1.0.13, + pvar ==1.0.0.0, + pwstore-fast ==2.4.4, + PyF ==0.11.1.1, + qchas ==1.1.0.1, + qm-interpolated-string ==0.3.1.0, + qrcode-core ==0.9.8, + qrcode-juicypixels ==0.8.5, + quadratic-irrational ==0.1.1, + QuasiText ==0.1.2.6, + QuickCheck ==2.14.3, + quickcheck-arbitrary-adt ==0.3.1.0, + quickcheck-assertions ==0.3.0, + quickcheck-classes ==0.6.5.0, + quickcheck-classes-base ==0.6.2.0, + quickcheck-higherorder ==0.1.0.1, + quickcheck-instances ==0.3.29.1, + quickcheck-io ==0.2.0, + quickcheck-simple ==0.1.1.1, + quickcheck-special ==0.1.0.6, + quickcheck-state-machine ==0.7.3, + quickcheck-text ==0.1.2.1, + quickcheck-transformer ==0.3.1.2, + quickcheck-unicode ==1.0.1.0, + quicklz ==1.5.0.11, + quiet ==0.2, + quote-quot ==0.2.1.0, + radius ==0.7.1.0, + rainbow ==0.34.2.2, + rainbox ==0.26.0.0, + ral ==0.2.1, + rampart ==2.0.0.6, + ramus ==0.1.2, + rando ==0.0.0.4, + random ==1.2.1.1, + random-bytestring ==0.1.4, + random-fu ==0.3.0.1, + random-shuffle ==0.0.4, + random-tree ==0.6.0.5, + range ==0.3.0.2, + ranged-list ==0.1.2.0, + Ranged-sets ==0.4.0, + ranges ==0.2.4, + range-set-list ==0.1.3.1, + rank1dynamic ==0.4.1, + rank2classes ==1.4.6, + Rasterific ==0.7.5.4, + rasterific-svg ==0.3.3.2, + ratel ==2.0.0.8, + ratel-wai ==2.0.0.4, + ratio-int ==0.1.2, + rattle ==0.2, + rattletrap ==11.2.14, + Rattus ==0.5.1, + rawfilepath ==1.0.1, + rawstring-qm ==0.2.3.0, + raw-strings-qq ==1.1, + rcu ==0.2.6, + rdtsc ==1.3.0.1, + re2 ==0.3, + reactive-banana ==1.3.2.0, + read-editor ==0.1.0.2, + read-env-var ==1.0.0.0, + rebase ==1.16.1, + rec-def ==0.2.1, + record-dot-preprocessor ==0.2.16, + record-hasfield ==1.0, + rec-smallarray ==0.1.0.0, + recursion-schemes ==5.2.2.4, + recv ==0.0.0, + redact ==0.4.0.0, + reddit-scrape ==0.0.1, + redis-resp ==1.0.0, + reducers ==3.12.4, + refact ==0.3.0.2, + ref-fd ==0.5.0.1, + refined ==0.8.1, + reflection ==2.1.7, + reform ==0.2.7.5, + reform-blaze ==0.2.4.4, + reform-hamlet ==0.0.5.3, + reform-happstack ==0.2.5.6, + reform-hsp ==0.2.7.2, + RefSerialize ==0.4.0, + ref-tf ==0.5.0.1, + regex ==1.1.0.2, + regex-applicative ==0.3.4, + regex-applicative-text ==0.1.0.1, + regex-base ==0.94.0.2, + regex-compat ==0.95.2.1, + regex-pcre ==0.95.0.0, + regex-pcre-builtin ==0.95.2.3.8.44, + regex-posix ==0.96.0.1, + regex-posix-clib ==2.7, + regex-tdfa ==1.3.2.1, + regex-with-pcre ==1.1.0.2, + registry ==0.3.3.4, + registry-aeson ==0.2.3.3, + registry-hedgehog ==0.7.2.0, + registry-hedgehog-aeson ==0.2.0.0, + registry-options ==0.1.0.0, + reinterpret-cast ==0.1.0, + rel8 ==1.4.1.0, + relapse ==1.0.0.1, + reliable-io ==0.0.2, + relude ==1.1.0.0, + renderable ==0.2.0.1, + reorder-expression ==0.1.0.0, + repa ==3.4.1.5, + repa-algorithms ==3.4.1.5, + repa-io ==3.4.1.2, + replace-attoparsec ==1.4.5.0, + replace-megaparsec ==1.4.5.0, + repline ==0.4.2.0, + req ==3.13.0, + req-conduit ==1.0.1, + rerebase ==1.16.1, + reroute ==0.7.0.0, + resolv ==0.1.2.0, + resource-pool ==0.2.3.2, + resourcet ==1.2.6, + result ==0.2.6.0, + retry ==0.9.3.1, + rev-state ==0.1.2, + rex ==0.6.2, + rfc1751 ==0.1.3, + rfc5051 ==0.2, + rg ==1.4.0.0, + rhbzquery ==0.4.4, + riak-protobuf ==0.25.0.0, + rio ==0.1.22.0, + rio-orphans ==0.1.2.0, + rio-prettyprint ==0.1.3.0, + rng-utils ==0.3.1, + roc-id ==0.1.0.0, + rocksdb-haskell ==1.0.1, + rocksdb-haskell-jprupp ==2.1.4, + rocksdb-query ==0.4.2, + roles ==0.2.1.0, + rollbar ==1.1.3, + rosezipper ==0.2, + rot13 ==0.2.0.1, + rpmbuild-order ==0.4.10, + rpm-nvr ==0.1.2, + rp-tree ==0.7.1, + rrb-vector ==0.1.1.0, + RSA ==2.4.1, + rss ==3000.2.0.7, + rss-conduit ==0.6.0.1, + run-haskell-module ==0.0.2, + runmemo ==1.0.0.1, + run-st ==0.1.3.0, + rvar ==0.3.0.2, + s3-signer ==0.5.0.0, + safe ==0.3.19, + safe-coloured-text ==0.2.0.1, + safe-coloured-text-gen ==0.0.0.1, + safe-coloured-text-layout ==0.0.0.0, + safe-coloured-text-layout-gen ==0.0.0.0, + safe-coloured-text-terminfo ==0.1.0.0, + safecopy ==0.10.4.2, + safe-decimal ==0.2.1.0, + safe-exceptions ==0.1.7.3, + safe-exceptions-checked ==0.1.0, + safe-foldable ==0.1.0.0, + safeio ==0.0.5.0, + safe-json ==1.1.3.1, + safe-money ==0.9.1, + SafeSemaphore ==0.10.1, + salve ==2.0.0.3, + sample-frame ==0.0.4, + sample-frame-np ==0.0.5, + sampling ==0.3.5, + sandi ==0.5, + sandwich ==0.1.4.0, + sandwich-hedgehog ==0.1.3.0, + sandwich-quickcheck ==0.1.0.7, + sandwich-slack ==0.1.1.0, + sandwich-webdriver ==0.1.2.0, + say ==0.1.0.1, + sbp ==4.9.0, + sbv ==9.0, + scalpel ==0.6.2.1, + scalpel-core ==0.6.2.1, + scanf ==0.1.0.0, + scanner ==0.3.1, + scheduler ==2.0.0.1, + SciBaseTypes ==0.1.1.0, + scientific ==0.3.7.0, + scientist ==0.0.0.0, + scotty ==0.12.1, + scrypt ==0.5.0, + sdl2 ==2.5.5.0, + sdl2-gfx ==0.3.0.0, + sdl2-image ==2.1.0.0, + sdl2-mixer ==1.2.0.0, + sdl2-ttf ==2.1.3, + search-algorithms ==0.3.2, + secp256k1-haskell ==0.6.1, + securemem ==0.1.10, + selda ==0.5.2.0, + selda-json ==0.1.1.1, + selda-sqlite ==0.1.7.2, + selections ==0.3.0.0, + selective ==0.5, + semialign ==1.2.0.1, + semialign-indexed ==1.2, + semialign-optics ==1.2, + semigroupoid-extras ==5, + semigroupoids ==5.3.7, + semigroups ==0.20, + semirings ==0.6, + semiring-simple ==1.0.0.1, + semver ==0.4.0.1, + sendfile ==0.7.11.4, + sendgrid-v3 ==1.0.0.1, + seqalign ==0.2.0.4, + seqid ==0.6.2, + seqid-streams ==0.7.2, + sequence-formats ==1.6.6.1, + sequenceTools ==1.5.2, + serf ==0.1.1.0, + serialise ==0.2.6.0, + servant ==0.19.1, + servant-auth ==0.4.1.0, + servant-auth-client ==0.4.1.0, + servant-auth-docs ==0.2.10.0, + servant-auth-server ==0.4.7.0, + servant-auth-swagger ==0.2.10.1, + servant-auth-wordpress ==1.0.0.2, + servant-blaze ==0.9.1, + servant-cassava ==0.10.2, + servant-checked-exceptions ==2.2.0.1, + servant-checked-exceptions-core ==2.2.0.1, + servant-client ==0.19, + servant-client-core ==0.19, + servant-conduit ==0.15.1, + servant-docs ==0.12, + servant-elm ==0.7.3, + servant-exceptions ==0.2.1, + servant-exceptions-server ==0.2.1, + servant-foreign ==0.15.4, + servant-http-streams ==0.18.4, + servant-JuicyPixels ==0.3.1.0, + servant-lucid ==0.9.0.6, + servant-machines ==0.15.1, + servant-multipart ==0.12.1, + servant-multipart-api ==0.12.1, + servant-multipart-client ==0.12.1, + servant-openapi3 ==2.0.1.6, + servant-pipes ==0.15.3, + servant-rate-limit ==0.2.0.0, + servant-rawm ==1.0.0.0, + servant-ruby ==0.9.0.0, + servant-server ==0.19.2, + servant-static-th ==1.0.0.0, + servant-subscriber ==0.7.0.0, + servant-swagger ==1.1.11, + servant-swagger-ui ==0.3.5.5.0.0, + servant-swagger-ui-core ==0.3.5, + servant-swagger-ui-redoc ==0.3.4.1.22.3, + servant-websockets ==2.0.0, + servant-xml ==1.0.1.4, + serversession ==1.0.3, + serversession-backend-persistent ==2.0.1, + serversession-backend-redis ==1.0.5, + serversession-frontend-wai ==1.0.1, + serversession-frontend-yesod ==1.0.1, + servius ==1.2.3.0, + ses-html ==0.4.0.0, + set-cover ==0.1.1, + setenv ==0.1.1.3, + setlocale ==1.0.0.10, + set-monad ==0.3.0.0, + sets ==0.0.6.2, + sexp-grammar ==2.3.4.1, + sexpr-parser ==0.2.2.0, + SHA ==1.6.4.4, + shake ==0.19.7, + shake-language-c ==0.12.0, + shake-plus ==0.3.4.0, + shake-plus-extended ==0.4.1.0, + shakespeare ==2.0.30, + shakespeare-text ==1.1.0, + shared-memory ==0.2.0.1, + ShellCheck ==0.8.0, + shell-conduit ==5.0.0, + shell-escape ==0.2.0, + shellmet ==0.0.4.1, + shelltestrunner ==1.9, + shell-utility ==0.1, + shellwords ==0.1.3.1, + shelly ==1.10.0.1, + shikensu ==0.4.1, + should-not-typecheck ==2.1.0, + show-combinators ==0.2.0.0, + siggy-chardust ==1.0.0, + signal ==0.1.0.4, + silently ==1.2.5.3, + simple-affine-space ==0.1.1, + simple-cabal ==0.1.3.1, + simple-cmd ==0.2.7, + simple-cmd-args ==0.1.8, + simple-media-timestamp ==0.2.1.0, + simple-media-timestamp-attoparsec ==0.1.0.0, + simple-media-timestamp-formatting ==0.1.1.0, + simple-prompt ==0.1.0, + simple-reflect ==0.3.3, + simple-sendfile ==0.2.31, + simple-vec3 ==0.6.0.1, + since ==0.0.0, + singleton-bool ==0.1.6, + singleton-nats ==0.4.6, + singletons ==3.0.1, + singletons-base ==3.1, + singletons-presburger ==0.6.1.0, + singletons-th ==3.1, + Sit ==0.2022.3.18, + sitemap-gen ==0.1.0.0, + size-based ==0.1.3.1, + sized ==1.0.0.2, + skein ==1.0.9.4, + skews ==0.1.0.3, + skip-var ==0.1.1.0, + skylighting ==0.13.2.1, + skylighting-core ==0.13.2.1, + skylighting-format-ansi ==0.1, + skylighting-format-blaze-html ==0.1.1, + skylighting-format-context ==0.1.0.2, + skylighting-format-latex ==0.1, + slack-progressbar ==0.1.0.1, + slave-thread ==1.1.0.2, + slynx ==0.7.2.1, + smallcheck ==1.2.1.1, + smtp-mail ==0.3.0.0, + snowflake ==0.1.1.1, + socket ==0.8.3.0, + socks ==0.6.1, + solana-staking-csvs ==0.1.2.0, + some ==1.0.4.1, + some-dict-of ==0.1.0.2, + sop-core ==0.5.0.2, + sort ==1.0.0.0, + sorted-list ==0.2.1.0, + sourcemap ==0.1.7, + sox ==0.2.3.2, + spacecookie ==1.0.0.2, + sparse-linear-algebra ==0.3.1, + spatial-math ==0.2.7.0, + spdx ==1.0.0.3, + special-values ==0.1.0.0, + speculate ==0.4.14, + speedy-slice ==0.3.2, + Spintax ==0.3.6, + splice ==0.6.1.1, + split ==0.2.3.5, + splitmix ==0.1.0.4, + splitmix-distributions ==1.0.0, + Spock ==0.14.0.0, + Spock-api ==0.14.0.0, + Spock-api-server ==0.14.0.0, + Spock-core ==0.14.0.1, + Spock-lucid ==0.4.0.1, + Spock-worker ==0.3.1.0, + spoon ==0.3.1, + spreadsheet ==0.1.3.9, + sqlcli ==0.2.2.0, + sqlcli-odbc ==0.2.0.1, + sqlite-simple ==0.4.18.2, + sql-words ==0.1.6.4, + squeather ==0.8.0.0, + srcloc ==0.6.0.1, + srt ==0.1.2.0, + srt-attoparsec ==0.1.0.0, + srt-formatting ==0.1.0.0, + stache ==2.3.3, + stack ==2.9.1, + stack-all ==0.4.1, + stack-clean-old ==0.4.6, + stack-templatizer ==0.1.1.0, + state-codes ==0.1.3, + stateref ==0.3, + statestack ==0.3.1.1, + StateVar ==1.2.2, + stateWriter ==0.3.0, + static-text ==0.2.0.7, + statistics ==0.16.2.0, + status-notifier-item ==0.3.1.0, + stb-image-redux ==0.2.1.2, + step-function ==0.2.0.1, + stitch ==0.6.0.0, + stm installed, + stm-chans ==3.0.0.9, + stm-conduit ==4.0.1, + stm-containers ==1.2.0.2, + stm-delay ==0.1.1.1, + stm-extras ==0.1.0.3, + stm-hamt ==1.2.0.11, + stm-lifted ==2.5.0.0, + STMonadTrans ==0.4.7, + stm-split ==0.0.2.1, + stopwatch ==0.1.0.6, + storable-complex ==0.2.3.0, + storable-endian ==0.2.6.1, + storable-record ==0.0.7, + storable-tuple ==0.0.3.3, + storablevector ==0.2.13.1, + store ==0.7.16, + store-core ==0.4.4.4, + store-streaming ==0.2.0.3, + stratosphere ==0.60.0, + Stream ==0.4.7.2, + streaming ==0.2.3.1, + streaming-attoparsec ==1.0.0.1, + streaming-bytestring ==0.2.4, + streaming-cassava ==0.2.0.0, + streaming-commons ==0.2.2.6, + streaming-wai ==0.1.1, + streamly ==0.8.1.1, + streams ==3.3.2, + streamt ==0.5.0.1, + strict ==0.4.0.1, + strict-base-types ==0.7, + strict-concurrency ==0.2.4.3, + strict-lens ==0.4.0.2, + strict-list ==0.1.7.1, + strict-tuple ==0.1.5.2, + strict-wrapper ==0.0.0.0, + stringable ==0.1.3, + stringbuilder ==0.5.1, + string-class ==0.1.7.0, + string-combinators ==0.6.0.5, + string-conv ==0.2.0, + string-conversions ==0.4.0.1, + string-interpolate ==0.3.2.1, + stringprep ==1.0.0, + string-qq ==0.0.4, + string-random ==0.1.4.3, + stringsearch ==0.3.6.6, + string-transform ==1.1.1, + stripe-concepts ==1.0.3.2, + stripe-scotty ==1.1.0.3, + stripe-signature ==1.0.0.15, + stripe-wreq ==1.0.1.15, + strive ==6.0.0.7, + strongweak ==0.3.2, + structs ==0.1.8, + structured ==0.1.1, + structured-cli ==2.7.0.1, + stylish-haskell ==0.14.3.0, + subcategories ==0.2.0.1, + sundown ==0.6, + superbuffer ==0.3.1.2, + svg-builder ==0.1.1, + SVGFonts ==1.8.0.1, + svg-tree ==0.6.2.4, + swagger2 ==2.8.7, + swish ==0.10.4.0, + syb ==0.7.2.3, + syb-with-class ==0.6.1.14, + sydtest ==0.13.0.4, + sydtest-aeson ==0.1.0.0, + sydtest-amqp ==0.1.0.0, + sydtest-autodocodec ==0.0.0.0, + sydtest-discover ==0.0.0.3, + sydtest-hedgehog ==0.3.0.1, + sydtest-hedis ==0.0.0.0, + sydtest-hspec ==0.3.0.2, + sydtest-mongo ==0.0.0.0, + sydtest-persistent ==0.0.0.1, + sydtest-persistent-postgresql ==0.2.0.2, + sydtest-persistent-sqlite ==0.2.0.2, + sydtest-process ==0.0.0.0, + sydtest-rabbitmq ==0.1.0.0, + sydtest-servant ==0.2.0.2, + sydtest-typed-process ==0.0.0.0, + sydtest-wai ==0.2.0.0, + sydtest-yesod ==0.3.0.1, + symbol ==0.2.4, + symengine ==0.1.2.0, + symmetry-operations-symbols ==0.0.2.1, + synthesizer-core ==0.8.3, + sysinfo ==0.1.1, + system-argv0 ==0.1.1, + systemd ==2.3.0, + system-fileio ==0.3.16.4, + system-filepath ==0.4.14, + system-info ==0.5.2, + tabular ==0.2.2.8, + tagged ==0.8.6.1, + tagged-binary ==0.2.0.1, + tagged-identity ==0.1.3, + tagged-transformer ==0.8.2, + tagshare ==0.0, + tagsoup ==0.14.8, + tagstream-conduit ==0.5.6, + tao ==1.0.0, + tao-example ==1.0.0, + tar ==0.5.1.1, + tar-conduit ==0.3.2, + tardis ==0.4.4.0, + tasty ==1.4.3, + tasty-ant-xml ==1.1.8, + tasty-autocollect ==0.3.2.0, + tasty-bench ==0.3.4, + tasty-dejafu ==2.1.0.0, + tasty-discover ==4.2.2, + tasty-expected-failure ==0.12.3, + tasty-fail-fast ==0.0.3, + tasty-focus ==1.0.1, + tasty-golden ==2.3.5, + tasty-hedgehog ==1.3.1.0, + tasty-hslua ==1.0.2, + tasty-hspec ==1.2.0.2, + tasty-html ==0.4.2.1, + tasty-hunit ==0.10.0.3, + tasty-hunit-compat ==0.2.0.1, + tasty-inspection-testing ==0.1.0.1, + tasty-kat ==0.0.3, + tasty-leancheck ==0.0.2, + tasty-lua ==1.0.2, + tasty-program ==1.0.5, + tasty-quickcheck ==0.10.2, + tasty-rerun ==1.1.18, + tasty-silver ==3.3.1.1, + tasty-smallcheck ==0.8.2, + tasty-tap ==0.1.0, + tasty-test-reporter ==0.1.1.4, + tasty-th ==0.1.7, + tasty-wai ==0.1.2.0, + tce-conf ==1.3, + tcp-streams ==1.0.1.1, + tdigest ==0.2.1.1, + teardown ==0.5.0.1, + telegram-bot-simple ==0.6.2, + template ==0.2.0.10, + template-haskell installed, + template-haskell-compat-v0208 ==0.1.9.2, + temporary ==1.3, + temporary-rc ==1.2.0.3, + temporary-resourcet ==0.1.0.1, + tensorflow-test ==0.1.0.0, + tensors ==0.1.5, + termbox ==1.1.0.1, + termbox-banana ==1.0.0, + termbox-bindings-c ==0.1.0, + termbox-bindings-hs ==0.1.0, + termbox-tea ==0.1.0, + terminal-progress-bar ==0.4.2, + terminal-size ==0.3.4, + terminfo installed, + termonad ==4.4.0.0, + test-framework ==0.8.2.0, + test-framework-hunit ==0.3.0.2, + test-framework-leancheck ==0.0.4, + test-framework-quickcheck2 ==0.3.0.5, + test-framework-smallcheck ==0.2, + test-fun ==0.1.0.0, + testing-feat ==1.1.1.1, + testing-type-modifiers ==0.1.0.1, + texmath ==0.12.5.5, + text installed, + text-ansi ==0.2.1.1, + text-binary ==0.2.1.1, + text-builder ==0.6.7, + text-builder-dev ==0.3.3.2, + text-conversions ==0.3.1.1, + text-icu ==0.8.0.2, + text-latin1 ==0.3.1, + text-ldap ==0.1.1.14, + textlocal ==0.1.0.5, + text-manipulate ==0.3.1.0, + text-metrics ==0.3.2, + text-postgresql ==0.0.3.1, + text-printer ==0.5.0.2, + text-regex-replace ==0.1.1.5, + text-rope ==0.2, + text-short ==0.1.5, + text-show ==3.10.3, + text-show-instances ==3.9.5, + text-zipper ==0.12, + tfp ==1.0.2, + tf-random ==0.5, + th-abstraction ==0.4.5.0, + th-bang-compat ==0.0.1.0, + th-compat ==0.1.4, + th-constraint-compat ==0.0.1.0, + th-data-compat ==0.1.2.0, + th-desugar ==1.13.1, + th-env ==0.1.1, + these ==1.1.1.1, + these-lens ==1.0.1.2, + these-optics ==1.0.1.2, + these-skinny ==0.7.5, + th-expand-syns ==0.4.11.0, + th-extras ==0.0.0.6, + th-lego ==0.3.0.2, + th-lift ==0.8.3, + th-lift-instances ==0.1.20, + th-nowq ==0.1.0.5, + th-orphans ==0.13.14, + th-printf ==0.7, + thread-hierarchy ==0.3.0.2, + thread-local-storage ==0.2, + threads ==0.5.1.7, + threads-extras ==0.1.0.3, + thread-supervisor ==0.2.0.0, + th-reify-compat ==0.0.1.5, + th-reify-many ==0.1.10, + through-text ==0.1.0.0, + th-strict-compat ==0.1.0.1, + th-test-utils ==1.2.1, + th-utilities ==0.2.5.0, + tidal ==1.9.2, + tidal-link ==1.0.1, + tile ==0.3.0.0, + time installed, + time-compat ==1.9.6.1, + time-domain ==0.1.0.2, + timeit ==2.0, + time-lens ==0.4.0.2, + timelens ==0.2.0.2, + time-locale-compat ==0.1.1.5, + time-locale-vietnamese ==1.0.0.0, + time-manager ==0.0.0, + time-parsers ==0.1.2.1, + timerep ==2.1.0.0, + timers-tick ==0.5.0.4, + timer-wheel ==0.4.0.1, + timespan ==0.4.0.0, + time-units ==1.0.0, + time-units-types ==0.2.0.1, + timezone-olson ==0.2.1, + timezone-olson-th ==0.1.0.11, + timezone-series ==0.1.13, + titlecase ==1.0.1, + tldr ==0.9.2, + tls ==1.5.8, + tls-debug ==0.4.8, + tls-session-manager ==0.0.4, + tlynx ==0.7.2.1, + tmapchan ==0.0.3, + tmapmvar ==0.0.4, + tmp-postgres ==1.34.1.0, + tmp-proc ==0.5.1.3, + tmp-proc-postgres ==0.5.2.2, + tmp-proc-rabbitmq ==0.5.1.2, + tmp-proc-redis ==0.5.1.2, + toml-reader ==0.2.1.0, + tophat ==1.0.5.1, + topograph ==1.0.0.2, + torrent ==10000.1.3, + torsor ==0.1, + tostring ==0.2.1.1, + tracing ==0.0.7.3, + tracing-control ==0.0.7.3, + transaction ==0.1.1.4, + transformers installed, + transformers-base ==0.4.6, + transformers-compat ==0.7.2, + transformers-either ==0.1.4, + transformers-fix ==1.0, + transient ==0.7.0.0, + traverse-with-class ==1.0.1.1, + tree-diff ==0.2.2, + tree-fun ==0.8.1.0, + tree-view ==0.5.1, + trifecta ==2.1.2, + trimdent ==0.1.0.0, + triplesec ==0.2.2.1, + trivial-constraint ==0.7.0.0, + tsv2csv ==0.1.0.2, + ttc ==1.2.1.0, + ttrie ==0.1.2.2, + tuple ==0.3.0.2, + tuples ==0.1.0.0, + tuples-homogenous-h98 ==0.1.1.0, + tuple-sop ==0.3.1.0, + tuple-th ==0.2.5, + turtle ==1.5.25, + twitter-conduit ==0.6.1, + twitter-types ==0.11.0, + twitter-types-lens ==0.11.0, + typecheck-plugin-nat-simple ==0.1.0.7, + typed-process ==0.2.11.0, + typed-uuid ==0.2.0.0, + type-equality ==1, + type-errors ==0.2.0.2, + type-fun ==0.1.3, + type-hint ==0.1, + type-level-integers ==0.0.1, + type-level-kv-list ==2.0.2.0, + type-level-natural-number ==2.0, + type-level-numbers ==0.1.1.2, + type-map ==0.1.7.0, + type-natural ==1.1.0.1, + typenums ==0.1.4, + type-of-html ==1.6.2.0, + type-of-html-static ==0.1.0.2, + type-operators ==0.2.0.0, + type-rig ==0.1, + type-spec ==0.4.0.0, + typography-geometry ==1.0.1.0, + tz ==0.1.3.6, + tzdata ==0.2.20230322.0, + tztime ==0.1.0.0, + ua-parser ==0.7.7.0, + uglymemo ==0.1.0.1, + ulid ==0.3.2.0, + unagi-chan ==0.4.1.4, + unbounded-delays ==0.1.1.1, + unbound-generics ==0.4.3, + unboxed-ref ==0.4.0.0, + unboxing-vector ==0.2.0.0, + uncaught-exception ==0.1.0, + unconstrained ==0.1.0.2, + unexceptionalio ==0.5.1, + unexceptionalio-trans ==0.5.1, + unfork ==1.0.0.1, + unicode ==0.0.1.1, + unicode-collation ==0.1.3.4, + unicode-data ==0.3.1, + unicode-show ==0.1.1.1, + unicode-transforms ==0.4.0.1, + unidecode ==0.1.0.4, + unification-fd ==0.11.2, + union-angle ==0.1.0.1, + union-find ==0.2, + unipatterns ==0.0.0.0, + uniplate ==1.6.13, + uniq-deep ==1.2.1, + unique ==0.0.1, + unique-logic ==0.4.0.1, + unique-logic-tf ==0.5.1, + unit-constraint ==0.0.0, + units-parser ==0.1.1.4, + universe ==1.2.2, + universe-base ==1.1.3.1, + universe-dependent-sum ==1.3, + universe-instances-extended ==1.1.3, + universe-reverse-instances ==1.1.1, + universe-some ==1.2.1, + universum ==1.8.1.1, + unix installed, + unix-bytestring ==0.3.7.8, + unix-compat ==0.5.4, + unix-time ==0.4.9, + unjson ==0.15.4, + unliftio ==0.2.25.0, + unliftio-core ==0.2.1.0, + unliftio-path ==0.0.2.0, + unliftio-pool ==0.2.2.0, + unliftio-streams ==0.1.1.1, + unlit ==0.4.0.0, + unordered-containers ==0.2.19.1, + unsafe ==0.0, + urbit-hob ==0.3.3, + uri-bytestring ==0.3.3.1, + uri-bytestring-aeson ==0.1.0.8, + uri-encode ==1.5.0.7, + url ==2.1.3, + userid ==0.1.3.7, + users ==0.5.0.0, + users-postgresql-simple ==0.5.0.2, + users-test ==0.5.0.1, + utf8-string ==1.0.2, + utility-ht ==0.0.17, + uuid ==1.3.15, + uuid-types ==1.0.5, + valida ==1.1.0, + valida-base ==0.2.0, + validate-input ==0.5.0.0, + validation ==1.1.2, + validationt ==0.3.0, + validity ==0.12.0.1, + validity-aeson ==0.2.0.5, + validity-bytestring ==0.4.1.1, + validity-case-insensitive ==0.0.0.0, + validity-containers ==0.5.0.4, + validity-path ==0.4.0.1, + validity-persistent ==0.0.0.0, + validity-primitive ==0.0.0.1, + validity-scientific ==0.2.0.3, + validity-text ==0.3.1.3, + validity-time ==0.5.0.0, + validity-unordered-containers ==0.2.0.3, + validity-uuid ==0.1.0.3, + validity-vector ==0.2.0.3, + valor ==1.0.0.0, + variable-media-field ==0.1.0.0, + variable-media-field-dhall ==0.1.0.0, + variable-media-field-optics ==0.1.0.0, + varying ==0.8.1.0, + vault ==0.3.1.5, + vcs-ignore ==0.0.2.0, + vec ==0.4.1, + vector ==0.12.3.1, + vector-algorithms ==0.8.0.4, + vector-binary-instances ==0.2.5.2, + vector-buffer ==0.4.1, + vector-builder ==0.3.8.4, + vector-bytes-instances ==0.1.1, + vector-circular ==0.1.4, + vector-extras ==0.2.8, + vector-hashtables ==0.1.1.3, + vector-instances ==3.4.2, + vector-mmap ==0.0.3, + vector-rotcev ==0.1.0.2, + vector-sized ==1.5.0, + vector-space ==0.16, + vector-split ==1.0.0.3, + vector-stream ==0.1.0.0, + vector-th-unbox ==0.2.2, + verbosity ==0.4.0.0, + versions ==5.0.5, + vformat ==0.14.1.0, + vformat-time ==0.1.0.0, + ViennaRNAParser ==1.3.3, + vinyl ==0.14.3, + vinyl-loeb ==0.0.1.0, + vivid ==0.5.2.0, + vivid-osc ==0.5.0.0, + vivid-supercollider ==0.4.1.2, + void ==0.7.3, + vty ==5.37, + wai ==3.2.3, + wai-app-static ==3.1.7.4, + wai-cli ==0.2.3, + wai-conduit ==3.0.0.4, + wai-cors ==0.2.7, + wai-enforce-https ==1.0.0.0, + wai-eventsource ==3.0.0, + wai-extra ==3.1.13.0, + wai-feature-flags ==0.1.0.4, + wai-handler-launch ==3.0.3.1, + wai-logger ==2.4.0, + wai-middleware-bearer ==1.0.3, + wai-middleware-caching ==0.1.0.2, + wai-middleware-caching-lru ==0.1.0.0, + wai-middleware-caching-redis ==0.2.0.0, + wai-middleware-clacks ==0.1.0.1, + wai-middleware-delegate ==0.1.3.1, + wai-middleware-metrics ==0.2.4, + wai-middleware-prometheus ==1.0.0.1, + wai-middleware-static ==0.9.2, + wai-rate-limit ==0.3.0.0, + wai-rate-limit-redis ==0.2.0.1, + wai-saml2 ==0.3.0.1, + wai-session ==0.3.3, + wai-session-postgresql ==0.2.1.3, + wai-session-redis ==0.1.0.5, + wai-slack-middleware ==0.2.0, + wai-websockets ==3.0.1.2, + wakame ==0.1.0.0, + warp ==3.3.23, + warp-tls ==3.3.4, + warp-tls-uid ==0.2.0.6, + wave ==0.2.0, + wcwidth ==0.0.2, + webby ==1.1.1, + webdriver ==0.10.0.1, + webex-teams-api ==0.2.0.1, + webex-teams-conduit ==0.2.0.1, + webgear-core ==1.0.5, + webgear-openapi ==1.0.5, + webgear-server ==1.0.5, + webpage ==0.0.5.1, + web-plugins ==0.4.1, + web-routes ==0.27.15, + web-routes-boomerang ==0.28.4.4, + web-routes-happstack ==0.23.12.3, + web-routes-hsp ==0.24.6.2, + web-routes-th ==0.22.8.1, + web-routes-wai ==0.24.3.2, + webrtc-vad ==0.1.0.3, + websockets ==0.12.7.3, + weigh ==0.0.16, + wide-word ==0.1.5.0, + Win32 ==2.12.0.1, + Win32-notify ==0.3.0.3, + windns ==0.1.0.1, + witch ==1.1.6.1, + withdependencies ==0.3.0, + witherable ==0.4.2, + within ==0.2.0.1, + with-location ==0.1.0, + with-utf8 ==1.0.2.4, + witness ==0.6.1, + wizards ==1.0.3, + wl-pprint ==1.2.1, + wl-pprint-annotated ==0.1.0.1, + wl-pprint-text ==1.2.0.2, + word8 ==0.1.3, + word-compat ==0.0.6, + wordpress-auth ==1.0.0.1, + word-trie ==0.3.0, + word-wrap ==0.5, + world-peace ==1.0.2.0, + wrap ==0.0.0, + wreq ==0.5.4.0, + wreq-stringless ==0.5.9.1, + writer-cps-exceptions ==0.1.0.1, + writer-cps-mtl ==0.1.1.6, + writer-cps-transformers ==0.5.6.1, + wss-client ==0.3.0.0, + wuss ==2.0.1.3, + X11 ==1.10.3, + X11-xft ==0.3.4, + x11-xim ==0.0.9.0, + x509 ==1.7.7, + x509-store ==1.6.9, + x509-system ==1.6.7, + x509-validation ==1.6.12, + Xauth ==0.1, + xdg-basedir ==0.2.2, + xdg-desktop-entry ==0.1.1.1, + xdg-userdirs ==0.1.0.2, + xeno ==0.6, + xhtml installed, + xlsx ==1.0.0.1, + xlsx-tabular ==0.2.2.1, + xml ==1.3.14, + xml-basic ==0.1.3.2, + xmlbf ==0.6.2, + xmlbf-xeno ==0.2.1, + xmlbf-xmlhtml ==0.2, + xml-conduit ==1.9.1.2, + xml-conduit-writer ==0.1.1.2, + xmlgen ==0.6.2.2, + xml-hamlet ==0.5.0.2, + xml-helpers ==1.0.0, + xmlhtml ==0.2.5.4, + xml-html-qq ==0.1.0.1, + xml-indexed-cursor ==0.1.1.0, + xml-lens ==0.3.1, + xml-parser ==0.1.1.1, + xml-picklers ==0.3.6, + xml-to-json-fast ==2.0.0, + xml-types ==0.3.8, + xmonad ==0.17.2, + xmonad-contrib ==0.17.1, + xmonad-extras ==0.17.0, + xor ==0.0.1.1, + xss-sanitize ==0.3.7.2, + xxhash-ffi ==0.2.0.0, + yaml ==0.11.11.1, + yaml-unscrambler ==0.1.0.13, + Yampa ==0.13.7, + yarn-lock ==0.6.5, + yeshql-core ==4.2.0.0, + yesod ==1.6.2.1, + yesod-alerts ==0.1.3.0, + yesod-auth ==1.6.11.1, + yesod-auth-basic ==0.1.0.3, + yesod-auth-hashdb ==1.7.1.7, + yesod-auth-oauth2 ==0.7.1.0, + yesod-bin ==1.6.2.2, + yesod-core ==1.6.24.2, + yesod-eventsource ==1.6.0.1, + yesod-fb ==0.6.1, + yesod-form ==1.7.4, + yesod-form-bootstrap4 ==3.0.1, + yesod-gitrepo ==0.3.0, + yesod-gitrev ==0.2.2, + yesod-markdown ==0.12.6.13, + yesod-newsfeed ==1.7.0.0, + yesod-page-cursor ==2.0.1.0, + yesod-paginator ==1.1.2.2, + yesod-persistent ==1.6.0.8, + yesod-recaptcha2 ==1.0.2, + yesod-routes-flow ==3.0.0.2, + yesod-sitemap ==1.6.0, + yesod-static ==1.6.1.0, + yesod-test ==1.6.15, + yesod-websockets ==0.3.0.3, + yes-precure5-command ==5.5.3, + yi-rope ==0.11, + yjsvg ==0.2.0.1, + yjtools ==0.9.18, + yoga ==0.0.0.5, + zenacy-html ==2.0.7, + zenacy-unicode ==1.0.2, + zeromq4-haskell ==0.8.0, + zeromq4-patterns ==0.3.1.0, + zigzag ==0.0.1.0, + zim-parser ==0.2.1.0, + zio ==0.1.0.2, + zip ==1.7.2, + zip-archive ==0.4.3, + zipper-extra ==0.1.3.2, + zippers ==0.3.2, + zip-stream ==0.2.2.0, + zlib ==0.6.3.0, + zlib-bindings ==0.1.1.5, + zot ==0.0.3, + zstd ==0.1.3.0, + ztail ==1.2.0.3 diff --git a/ci/configs/ghc-9.2.8.project b/ci/configs/ghc-9.2.8.project new file mode 100644 index 0000000..bb34a91 --- /dev/null +++ b/ci/configs/ghc-9.2.8.project @@ -0,0 +1,3067 @@ +import: ../../cabal.project +with-compiler: ghc-9.2.8 +index-state: hackage.haskell.org 2024-03-05T05:41:26Z +-- NOTE: Due to revisions, this file may not work. See: +-- https://github.com/fpco/stackage-server/issues/232 + +-- Stackage snapshot from: http://www.stackage.org/snapshot/lts-20.26 +-- Please place this file next to your .cabal file as cabal.config +-- To only use tested packages, uncomment the following line: +-- remote-repo: stackage-lts-20.26:http://www.stackage.org/lts-20.26 +with-compiler: ghc-9.2.8 +constraints: abstract-deque ==0.3, + abstract-deque-tests ==0.3, + abstract-par ==0.3.3, + AC-Angle ==1.0, + acc ==0.2.0.1, + ace ==0.6, + acid-state ==0.16.1.2, + action-permutations ==0.0.0.1, + active ==0.2.0.18, + ad ==4.5.4, + ad-delcont ==0.3.0.0, + adjunctions ==4.4.2, + adler32 ==0.1.2.0, + advent-of-code-api ==0.2.8.4, + aern2-mp ==0.2.15.0, + aern2-real ==0.2.11.0, + aeson ==2.0.3.0, + aeson-attoparsec ==0.0.0, + aeson-better-errors ==0.9.1.1, + aeson-casing ==0.2.0.0, + aeson-combinators ==0.1.0.1, + aeson-commit ==1.6.0, + aeson-compat ==0.3.10, + aeson-diff ==1.1.0.13, + aeson-extra ==0.5.1.2, + aeson-generic-compat ==0.0.1.3, + aeson-iproute ==0.3.0, + aeson-optics ==1.2.0.1, + aeson-picker ==0.1.0.6, + aeson-pretty ==0.8.9, + aeson-qq ==0.8.4, + aeson-schemas ==1.4.1.0, + aeson-typescript ==0.4.2.0, + aeson-value-parser ==0.19.7.1, + aeson-yak ==0.1.1.3, + aeson-yaml ==1.1.0.1, + Agda ==2.6.2.2, + agda2lagda ==0.2021.6.1, + airship ==0.9.5, + al ==0.1.4.2, + alarmclock ==0.7.0.6, + alerts ==0.1.2.0, + alex ==3.2.7.4, + alex-meta ==0.3.0.13, + algebra ==4.3.1, + algebraic-graphs ==0.6.1, + Allure ==0.11.0.0, + almost-fix ==0.0.2, + alsa-core ==0.5.0.1, + alsa-mixer ==0.3.0, + alsa-pcm ==0.6.1.1, + alternative-vector ==0.0.0, + alternators ==1.0.0.0, + ALUT ==2.4.0.3, + amqp ==0.22.1, + amqp-utils ==0.6.3.2, + annotated-exception ==0.2.0.4, + annotated-wl-pprint ==0.7.0, + ansi-terminal ==0.11.4, + ansi-terminal-game ==1.8.1.0, + ansi-wl-pprint ==0.6.9, + ANum ==0.2.0.2, + aos-signature ==0.1.1, + apecs ==0.9.5, + apecs-gloss ==0.2.4, + apecs-physics ==0.4.5, + api-field-json-th ==0.1.0.2, + api-maker ==0.1.0.6, + ap-normalize ==0.1.0.1, + appar ==0.1.8, + appendful ==0.1.0.0, + appendful-persistent ==0.1.0.0, + appendmap ==0.1.5, + apply-refact ==0.10.0.0, + apportionment ==0.0.0.4, + approximate ==0.3.5, + approximate-equality ==1.1.0.2, + app-settings ==0.2.0.12, + arbor-lru-cache ==0.1.1.1, + arbtt ==0.12.0.1, + arithmoi ==0.12.1.0, + array installed, + array-memoize ==0.6.0, + arrow-extras ==0.1.0.1, + arrows ==0.4.4.2, + ascii ==1.2.4.0, + ascii-case ==1.0.1.2, + ascii-char ==1.0.0.17, + asciidiagram ==1.3.3.3, + ascii-group ==1.0.0.15, + ascii-numbers ==1.1.0.2, + ascii-predicates ==1.0.1.2, + ascii-progress ==0.3.3.0, + ascii-superset ==1.0.1.15, + ascii-th ==1.0.0.14, + asn1-encoding ==0.9.6, + asn1-parse ==0.9.5, + asn1-types ==0.3.4, + assert-failure ==0.1.2.6, + assoc ==1.0.2, + astro ==0.4.3.0, + async ==2.2.4, + async-extra ==0.2.0.0, + async-pool ==0.9.1, + async-refresh ==0.3.0.0, + async-refresh-tokens ==0.4.0.0, + atom-basic ==0.2.5, + atom-conduit ==0.9.0.1, + atomic-primops ==0.8.4, + atomic-write ==0.2.0.7, + attoparsec ==0.14.4, + attoparsec-base64 ==0.0.0, + attoparsec-binary ==0.2, + attoparsec-data ==1.0.5.3, + attoparsec-expr ==0.1.1.2, + attoparsec-iso8601 ==1.0.2.1, + attoparsec-path ==0.0.0.1, + attoparsec-time ==1.0.3, + aur ==7.0.7, + aura ==3.2.9, + authenticate ==1.3.5.1, + authenticate-oauth ==1.7, + autodocodec ==0.2.0.3, + autodocodec-openapi3 ==0.2.1.1, + autodocodec-schema ==0.1.0.3, + autodocodec-yaml ==0.2.0.3, + autoexporter ==2.0.0.2, + auto-update ==0.1.6, + avro ==0.6.1.2, + aws-cloudfront-signed-cookies ==0.2.0.12, + aws-xray-client ==0.1.0.2, + aws-xray-client-persistent ==0.1.0.5, + aws-xray-client-wai ==0.1.0.2, + backtracking ==0.1.0, + bank-holidays-england ==0.2.0.9, + barbies ==2.0.4.0, + base installed, + base16 ==0.3.2.1, + base16-bytestring ==1.0.2.0, + base32 ==0.2.2.0, + base32string ==0.9.1, + base58-bytestring ==0.1.0, + base58string ==0.10.0, + base64 ==0.4.2.4, + base64-bytestring ==1.2.1.0, + base64-bytestring-type ==1.0.1, + base64-string ==0.2, + base-compat ==0.12.2, + base-compat-batteries ==0.12.2, + basement ==0.0.16, + base-orphans ==0.8.8.2, + base-prelude ==1.6.1, + base-unicode-symbols ==0.2.4.2, + basic-prelude ==0.7.0, + battleship-combinatorics ==0.0.1, + bazel-runfiles ==0.12, + bbdb ==0.8, + bcp47 ==0.2.0.6, + bcp47-orphans ==0.1.0.6, + bcrypt ==0.0.11, + beam-core ==0.9.2.1, + beam-migrate ==0.5.1.2, + beam-postgres ==0.5.2.1, + beam-sqlite ==0.5.1.2, + bech32 ==1.1.3, + bech32-th ==1.1.1, + bench ==1.0.12, + benchpress ==0.2.2.22, + bench-show ==0.3.2, + bencode ==0.6.1.1, + bencoding ==0.4.5.4, + benri-hspec ==0.1.0.1, + between ==0.11.0.0, + bhoogle ==0.1.4.2, + bibtex ==0.1.0.6, + bifunctors ==5.5.15, + bimap ==0.5.0, + bimaps ==0.1.0.2, + bimap-server ==0.1.0.1, + bin ==0.1.2, + binance-exports ==0.1.1.0, + binary installed, + binary-conduit ==1.3.1, + binaryen ==0.0.6.0, + binary-generic-combinators ==0.4.4.0, + binary-ieee754 ==0.1.0.0, + binary-instances ==1.0.4, + binary-list ==1.1.1.2, + binary-orphans ==1.0.4.1, + binary-parser ==0.5.7.3, + binary-search ==2.0.0, + binary-shared ==0.8.3, + binary-tagged ==0.3.1, + bindings-DSL ==1.0.25, + bindings-GLFW ==3.3.2.0, + bindings-libzip ==1.0.1, + bindings-uname ==0.1, + BiobaseEnsembl ==0.2.0.1, + bitarray ==0.0.1.1, + bits ==0.6, + bitset-word8 ==0.1.1.2, + bits-extra ==0.0.2.3, + bitvec ==1.1.4.0, + bitwise-enum ==1.0.1.0, + blake2 ==0.3.0, + Blammo ==1.1.2.0, + blank-canvas ==0.7.3, + blanks ==0.5.0, + blas-carray ==0.1.0.2, + blas-comfort-array ==0.0.0.3, + blas-ffi ==0.1, + blas-hs ==0.1.1.0, + blaze-bootstrap ==0.1.0.1, + blaze-builder ==0.4.2.2, + blaze-html ==0.9.1.2, + blaze-markup ==0.8.2.8, + blaze-svg ==0.3.7, + blaze-textual ==0.2.3.1, + bloodhound ==0.21.0.0, + bm ==0.1.1.0, + bmp ==1.2.6.3, + bnb-staking-csvs ==0.2.1.0, + BNFC ==2.9.4.1, + BNFC-meta ==0.6.1, + bodhi ==0.1.0, + boltzmann-samplers ==0.1.1.0, + bookkeeping ==0.4.0.1, + Boolean ==0.2.4, + boolsimplifier ==0.1.8, + boomerang ==1.4.9, + boots ==0.2.0.1, + bordacount ==0.1.0.0, + boring ==0.2.1, + bound ==2.0.6, + BoundedChan ==1.0.3.0, + bounded-queue ==1.0.0, + boundingboxes ==0.2.3, + bower-json ==1.1.0.0, + boxes ==0.1.5, + breakpoint ==0.1.2.1, + brick ==1.4, + broadcast-chan ==0.2.1.2, + brotli ==0.0.0.1, + brotli-streams ==0.0.0.0, + bsb-http-chunked ==0.0.0.4, + bson ==0.4.0.1, + bson-lens ==0.1.1, + buffer-builder ==0.2.4.8, + buffer-pipe ==0.0, + bugsnag ==1.0.0.1, + bugsnag-haskell ==0.0.4.4, + bugsnag-hs ==0.2.0.9, + bugsnag-wai ==1.0.0.1, + bugsnag-yesod ==1.0.0.1, + bugzilla-redhat ==1.0.1, + burrito ==2.0.1.6, + butcher ==1.3.3.2, + bv ==0.5, + byteable ==0.1.1, + bytebuild ==0.3.13.0, + byte-count-reader ==0.10.1.10, + bytedump ==1.0, + bytehash ==0.1.0.0, + byte-order ==0.1.3.0, + byteorder ==1.0.4, + bytes ==0.17.2, + byteset ==0.1.1.0, + byteslice ==0.2.7.0, + bytesmith ==0.3.9.1, + bytestring installed, + bytestring-builder ==0.10.8.2.0, + bytestring-conversion ==0.3.2, + bytestring-lexing ==0.5.0.10, + bytestring-mmap ==0.2.2, + bytestring-progress ==1.4, + bytestring-strict-builder ==0.4.5.6, + bytestring-to-vector ==0.3.0.1, + bytestring-tree-builder ==0.2.7.10, + bytestring-trie ==0.2.7.2, + bz2 ==1.0.1.0, + bzlib-conduit ==0.3.0.2, + c14n ==0.1.0.2, + c2hs ==0.28.8, + Cabal installed, + cabal2nix ==2.19.1, + cabal2spec ==2.6.3, + cabal-appimage ==0.3.0.5, + cabal-clean ==0.2.20230609, + cabal-debian ==5.2.1, + cabal-doctest ==1.0.9, + cabal-file ==0.1.1, + cabal-file-th ==0.2.7, + cabal-flatpak ==0.1.0.4, + cabal-install ==3.6.2.0, + cabal-plan ==0.7.2.3, + cabal-rpm ==2.0.11.1, + Cabal-syntax ==3.6.0.0, + cache ==0.1.3.0, + cached-json-file ==0.1.1, + cacophony ==0.10.1, + cairo ==0.13.10.0, + calendar-recycling ==0.0.0.1, + call-alloy ==0.4.0.3, + calligraphy ==0.1.4, + call-plantuml ==0.0.1.2, + call-stack ==0.4.0, + can-i-haz ==0.3.1.1, + capability ==0.5.0.1, + ca-province-codes ==1.0.0.0, + cardano-coin-selection ==1.0.1, + carray ==0.1.6.8, + casa-client ==0.0.1, + casa-types ==0.0.2, + cased ==0.1.0.0, + case-insensitive ==1.2.1.0, + cases ==0.1.4.2, + casing ==0.1.4.1, + cassava ==0.5.3.0, + cassava-megaparsec ==2.0.4, + cast ==0.1.0.2, + cayley-client ==0.4.19.2, + cborg ==0.2.9.0, + cborg-json ==0.2.5.0, + cdar-mBound ==0.1.0.4, + c-enum ==0.1.1.3, + cereal ==0.5.8.3, + cereal-conduit ==0.8.0, + cereal-text ==0.1.0.2, + cereal-unordered-containers ==0.1, + cereal-vector ==0.2.0.1, + cfenv ==0.1.0.0, + chan ==0.0.4.1, + character-cases ==0.1.0.6, + charset ==0.3.9, + charsetdetect-ae ==1.1.0.4, + Chart ==1.9.4, + Chart-cairo ==1.9.3, + Chart-diagrams ==1.9.4, + chart-svg ==0.3.3, + ChasingBottoms ==1.3.1.12, + cheapskate ==0.1.1.2, + cheapskate-highlight ==0.1.0.0, + cheapskate-lucid ==0.1.0.0, + check-email ==1.0.2, + checkers ==0.6.0, + checksum ==0.0.0.1, + chimera ==0.3.3.0, + choice ==0.2.2, + chronologique ==0.3.1.3, + chunked-data ==0.3.1, + cipher-aes ==0.2.11, + cipher-camellia ==0.0.2, + cipher-rc4 ==0.1.4, + circle-packing ==0.1.0.6, + circular ==0.4.0.3, + citeproc ==0.8.1, + classy-prelude ==1.5.0.2, + classy-prelude-conduit ==1.5.0, + classy-prelude-yesod ==1.5.0, + cleff ==0.3.3.0, + cleff-plugin ==0.1.0.0, + clientsession ==0.9.1.2, + climb ==0.4.1, + Clipboard ==2.3.2.0, + clock ==0.8.3, + closed ==0.2.0.2, + clumpiness ==0.17.0.2, + ClustalParser ==1.3.0, + cmark ==0.6, + cmark-gfm ==0.2.5, + cmark-lucid ==0.1.0.0, + cmdargs ==0.10.22, + codec-beam ==0.2.0, + code-conjure ==0.5.2, + code-page ==0.2.1, + cointracking-imports ==0.1.0.2, + collect-errors ==0.1.5.0, + co-log-core ==0.3.2.0, + Color ==0.3.3, + colorful-monoids ==0.2.1.3, + colorize-haskell ==1.0.1, + colour ==2.3.6, + columnar ==1.0.0.0, + combinatorial ==0.1.1, + comfort-array ==0.5.2.3, + comfort-array-shape ==0.0, + comfort-fftw ==0.0.0.1, + comfort-graph ==0.0.3.2, + commonmark ==0.2.2, + commonmark-extensions ==0.2.3.4, + commonmark-pandoc ==0.2.1.3, + commutative ==0.0.2, + comonad ==5.0.8, + comonad-extras ==4.0.1, + compactmap ==0.1.4.3, + compensated ==0.8.3, + compiler-warnings ==0.1.0, + componentm ==0.0.0.2, + componentm-devel ==0.0.0.2, + composable-associations ==0.1.0.0, + composite-base ==0.8.2.1, + composite-binary ==0.8.2.1, + composite-ekg ==0.8.2.1, + composite-tuple ==0.1.2.0, + composite-xstep ==0.1.0.0, + composition ==1.0.2.2, + composition-extra ==2.0.0, + composition-prelude ==3.0.0.2, + concise ==0.1.0.1, + concurrency ==1.11.0.3, + concurrent-extra ==0.7.0.12, + concurrent-output ==1.10.18, + concurrent-split ==0.0.1.1, + cond ==0.4.1.1, + conduino ==0.2.2.0, + conduit ==1.3.5, + conduit-aeson ==0.1.0.1, + conduit-algorithms ==0.0.13.0, + conduit-combinators ==1.3.0, + conduit-concurrent-map ==0.1.3, + conduit-extra ==1.3.6, + conduit-parse ==0.2.1.1, + conduit-zstd ==0.0.2.0, + conferer ==1.1.0.0, + conferer-aeson ==1.1.0.2, + ConfigFile ==1.1.4, + config-ini ==0.2.5.0, + configuration-tools ==0.6.1, + configurator ==0.3.0.0, + configurator-export ==0.1.0.1, + configurator-pg ==0.2.7, + connection ==0.3.1, + connection-pool ==0.2.2, + console-style ==0.0.2.1, + constraints ==0.13.4, + constraints-extras ==0.3.2.1, + constraint-tuples ==0.1.2, + construct ==0.3.1.1, + containers installed, + context ==0.2.0.1, + context-http-client ==0.2.0.1, + context-resource ==0.2.0.1, + context-wai-middleware ==0.2.0.1, + contiguous ==0.6.3.0, + contravariant ==1.5.5, + contravariant-extras ==0.3.5.3, + control-bool ==0.2.1, + control-dsl ==0.2.1.3, + control-monad-free ==0.6.2, + control-monad-omega ==0.3.2, + convertible ==1.1.1.1, + cookie ==0.4.6, + copr-api ==0.1.0, + core-data ==0.3.9.1, + core-program ==0.6.8.0, + core-telemetry ==0.2.9.3, + core-text ==0.3.8.1, + countable ==1.2, + country ==0.2.3, + covariance ==0.2.0.1, + cpphs ==1.20.9.1, + cprng-aes ==0.6.1, + cpu ==0.1.2, + cpuinfo ==0.1.0.2, + cql ==4.0.4, + cql-io ==1.1.1, + crackNum ==3.2, + credential-store ==0.1.2, + criterion ==1.5.13.0, + criterion-measurement ==0.1.4.0, + cron ==0.7.0, + crypto-api ==0.13.3, + crypto-api-tests ==0.3, + crypto-cipher-tests ==0.0.11, + crypto-cipher-types ==0.0.9, + cryptocompare ==0.1.2, + crypto-enigma ==0.1.1.6, + cryptohash ==0.11.9, + cryptohash-cryptoapi ==0.1.4, + cryptohash-md5 ==0.11.101.0, + cryptohash-sha1 ==0.11.101.0, + cryptohash-sha256 ==0.11.102.1, + cryptohash-sha512 ==0.11.102.0, + cryptonite ==0.30, + cryptonite-conduit ==0.2.2, + cryptonite-openssl ==0.7, + crypto-pubkey-types ==0.4.3, + crypto-random ==0.0.9, + crypto-random-api ==0.2.0, + cryptostore ==0.2.3.0, + crypt-sha512 ==0, + csp ==1.4.0, + css-text ==0.1.3.0, + c-struct ==0.1.3.0, + csv ==0.1.2, + csv-conduit ==0.7.3.0, + ctrie ==0.2, + cubicbezier ==0.6.0.6, + cubicspline ==0.1.2, + cue-sheet ==2.0.2, + curl ==1.3.8, + curl-runnings ==0.17.0, + currencies ==0.2.0.0, + currency ==0.2.0.0, + currycarbon ==0.2.1.1, + cursor ==0.3.2.0, + cursor-brick ==0.1.0.1, + cursor-fuzzy-time ==0.0.0.0, + cursor-gen ==0.4.0.0, + cyclotomic ==1.1.2, + czipwith ==1.0.1.4, + d10 ==1.0.1.2, + data-accessor ==0.2.3.1, + data-accessor-mtl ==0.2.0.5, + data-accessor-transformers ==0.2.1.8, + data-array-byte ==0.1.0.1, + data-binary-ieee754 ==0.4.4, + data-bword ==0.1.0.2, + data-checked ==0.3, + data-clist ==0.2, + data-default ==0.7.1.1, + data-default-class ==0.1.2.0, + data-default-instances-base ==0.1.0.1, + data-default-instances-bytestring ==0.0.1, + data-default-instances-case-insensitive ==0.0.1, + data-default-instances-containers ==0.0.1, + data-default-instances-dlist ==0.0.1, + data-default-instances-old-locale ==0.0.1, + data-default-instances-text ==0.0.1, + data-default-instances-unordered-containers ==0.0.1, + data-default-instances-vector ==0.0.1, + data-diverse ==4.7.1.0, + datadog ==0.3.0.0, + data-dword ==0.3.2.1, + data-endian ==0.1.1, + data-fix ==0.3.2, + data-forest ==0.1.0.10, + data-functor-logistic ==0.0, + data-has ==0.4.0.0, + data-hash ==0.2.0.1, + data-interval ==2.1.1, + data-inttrie ==0.1.4, + data-lens-light ==0.1.2.3, + data-memocombinators ==0.5.1, + data-msgpack ==0.0.13, + data-msgpack-types ==0.0.3, + data-or ==1.0.0.7, + data-ordlist ==0.4.7.0, + data-ref ==0.0.2, + data-reify ==0.6.3, + data-serializer ==0.3.5, + datasets ==0.4.0, + data-sketches ==0.3.1.0, + data-sketches-core ==0.1.0.0, + data-textual ==0.3.0.3, + data-tree-print ==0.1.0.2, + dataurl ==0.1.0.0, + DAV ==1.3.4, + dawg-ord ==0.5.1.2, + dbcleaner ==0.1.3, + DBFunctor ==0.1.2.1, + dbus ==1.2.29, + dbus-hslogger ==0.1.0.1, + debian ==4.0.4, + debian-build ==0.10.2.1, + debug-trace-var ==0.2.0, + dec ==0.0.5, + Decimal ==0.5.2, + declarative ==0.5.4, + deepseq installed, + deepseq-generics ==0.2.0.0, + deferred-folds ==0.9.18.3, + dejafu ==2.4.0.5, + dense-linear-algebra ==0.1.0.0, + dependent-map ==0.4.0.0, + dependent-sum ==0.7.2.0, + dependent-sum-template ==0.1.1.1, + depq ==0.4.2, + deque ==0.4.4, + deriveJsonNoPrefix ==0.1.0.1, + derive-topdown ==0.0.3.0, + deriving-aeson ==0.2.9, + deriving-compat ==0.6.3, + detour-via-sci ==1.0.0, + df1 ==0.4.1, + dhall ==1.41.2, + dhall-bash ==1.0.40, + dhall-json ==1.7.11, + dhall-yaml ==1.2.12, + di ==1.3, + diagrams ==1.4.0.1, + diagrams-builder ==0.8.0.5, + diagrams-cairo ==1.4.2, + diagrams-canvas ==1.4.1.1, + diagrams-contrib ==1.4.5, + diagrams-core ==1.5.1, + diagrams-lib ==1.4.5.2, + diagrams-postscript ==1.5.1.1, + diagrams-rasterific ==1.4.2.3, + diagrams-solve ==0.1.3, + diagrams-svg ==1.4.3.1, + di-core ==1.0.4, + dictionary-sharing ==0.1.0.0, + di-df1 ==1.2.1, + Diff ==0.4.1, + digest ==0.0.1.7, + digits ==0.3.1, + di-handle ==1.0.1, + dimensional ==1.5, + di-monad ==1.3.1, + directory installed, + directory-tree ==0.12.1, + direct-sqlite ==2.3.28, + dirichlet ==0.1.0.7, + discount ==0.1.1, + discover-instances ==0.1.0.0, + discrimination ==0.5, + disk-free-space ==0.1.0.1, + distribution-nixpkgs ==1.7.0.1, + distribution-opensuse ==1.1.3, + distributive ==0.6.2.1, + diversity ==0.8.1.0, + djinn-lib ==0.0.1.4, + dl-fedora ==0.9.5, + dlist ==1.0, + dlist-instances ==0.1.1.1, + dlist-nonempty ==0.1.2, + dns ==4.1.1, + docker ==0.7.0.1, + dockerfile ==0.2.0, + doclayout ==0.4.0.1, + doctemplates ==0.10.0.2, + doctest ==0.20.1, + doctest-discover ==0.2.0.0, + doctest-driver-gen ==0.3.0.7, + doctest-exitcode-stdio ==0.0, + doctest-lib ==0.1, + doctest-parallel ==0.2.6, + doldol ==0.4.1.2, + do-list ==1.0.1, + domain ==0.1.1.4, + domain-aeson ==0.1.1.1, + domain-cereal ==0.1, + domain-core ==0.1.0.3, + domain-optics ==0.1.0.3, + do-notation ==0.1.0.2, + dot ==0.3, + dotenv ==0.10.0.0, + dotgen ==0.4.3, + dotnet-timespan ==0.0.1.0, + double-conversion ==2.0.4.2, + download ==0.3.2.7, + download-curl ==0.1.4, + DPutils ==0.1.1.0, + drifter ==0.3.0, + drifter-postgresql ==0.2.1, + drifter-sqlite ==0.1.0.0, + dsp ==0.2.5.2, + dual ==0.1.1.1, + dual-tree ==0.2.3.1, + dublincore-xml-conduit ==0.1.0.2, + dunai ==0.9.2, + duration ==0.2.0.0, + dvorak ==0.1.0.0, + dynamic-state ==0.3.1, + dyre ==0.9.2, + eap ==0.9.0.2, + Earley ==0.13.0.1, + easy-file ==0.2.5, + easy-logger ==0.1.0.7, + Ebnf2ps ==1.0.15, + echo ==0.1.4, + ecstasy ==0.2.1.0, + ed25519 ==0.0.5.0, + ede ==0.3.3.0, + edit-distance ==0.2.2.1, + edit-distance-vector ==1.0.0.4, + editor-open ==0.6.0.0, + effectful ==2.2.2.0, + effectful-core ==2.2.2.2, + effectful-plugin ==1.0.0.0, + effectful-th ==1.0.0.1, + either ==5.0.2, + either-both ==0.1.1.1, + either-unwrap ==1.1, + ekg-core ==0.1.1.7, + elerea ==2.9.0, + elf ==0.31, + eliminators ==0.9, + elm2nix ==0.3.0, + elm-bridge ==0.8.2, + elm-core-sources ==1.0.0, + elm-export ==0.6.0.1, + elynx ==0.7.2.1, + elynx-markov ==0.7.2.1, + elynx-nexus ==0.7.2.1, + elynx-seq ==0.7.2.1, + elynx-tools ==0.7.2.1, + elynx-tree ==0.7.2.1, + emacs-module ==0.1.1.1, + email-validate ==2.3.2.18, + emojis ==0.1.2, + enclosed-exceptions ==1.0.3, + ENIG ==0.0.1.0, + entropy ==0.4.1.10, + enummapset ==0.6.0.3, + enumset ==0.1, + enum-text ==0.5.3.0, + envelope ==0.2.2.0, + envparse ==0.5.0, + envy ==2.1.2.0, + eq ==4.3, + equational-reasoning ==0.7.0.1, + equivalence ==0.4.1, + erf ==2.0.0.0, + errata ==0.4.0.0, + error ==1.0.0.0, + errorcall-eq-instance ==0.3.0, + error-or ==0.3.0, + error-or-utils ==0.2.0, + errors ==2.3.0, + errors-ext ==0.4.2, + ersatz ==0.4.13, + esqueleto ==3.5.10.0, + essence-of-live-coding ==0.2.7, + essence-of-live-coding-gloss ==0.2.7, + essence-of-live-coding-pulse ==0.2.7, + essence-of-live-coding-quickcheck ==0.2.7, + essence-of-live-coding-warp ==0.2.7, + event-list ==0.1.2, + eventstore ==1.4.2, + every ==0.0.1, + evm-opcodes ==0.1.2, + exact-combinatorics ==0.2.0.11, + exact-pi ==0.5.0.2, + exception-hierarchy ==0.1.0.8, + exception-mtl ==0.4.0.2, + exceptions installed, + exception-transformers ==0.4.0.11, + executable-hash ==0.2.0.4, + executable-path ==0.0.3.1, + exit-codes ==1.0.0, + exomizer ==1.0.0, + experimenter ==0.1.0.14, + expiring-cache-map ==0.0.6.1, + explainable-predicates ==0.1.2.3, + explicit-exception ==0.1.10.1, + exp-pairs ==0.2.1.0, + express ==1.0.10, + extended-reals ==0.2.4.0, + extensible ==0.9, + extensible-effects ==5.0.0.1, + extensible-exceptions ==0.1.1.4, + extra ==1.7.13, + extractable-singleton ==0.0.1, + extrapolate ==0.4.6, + fail ==4.9.0.0, + failable ==1.2.4.0, + fakedata ==1.0.3, + fakedata-parser ==0.1.0.0, + fakedata-quickcheck ==0.2.0, + fakefs ==0.3.0.2, + fakepull ==0.3.0.2, + faktory ==1.1.2.4, + fasta ==0.10.4.2, + fast-logger ==3.1.2, + fast-math ==1.0.2, + fb ==2.1.1.1, + fclabels ==2.0.5.1, + fdo-notify ==0.3.1, + feature-flags ==0.1.0.1, + fedora-dists ==2.1.1, + fedora-haskell-tools ==1.0, + feed ==1.3.2.1, + FenwickTree ==0.1.2.1, + fft ==0.1.8.7, + fftw-ffi ==0.1, + fgl ==5.7.0.3, + fields-json ==0.4.0.0, + filecache ==0.4.1, + file-embed ==0.0.15.0, + file-embed-lzma ==0.0.1, + filelock ==0.1.1.6, + filemanip ==0.3.6.3, + file-modules ==0.1.2.4, + filepath installed, + filepath-bytestring ==1.4.2.1.12, + file-path-th ==0.1.0.0, + filepattern ==0.1.3, + fileplow ==0.1.0.0, + filter-logger ==0.6.0.0, + filtrable ==0.1.6.0, + fin ==0.2.1, + FindBin ==0.0.5, + fingertree ==0.1.5.0, + finite-typelits ==0.1.6.0, + first-class-families ==0.8.0.1, + first-class-patterns ==0.3.2.5, + fitspec ==0.4.10, + fixed ==0.3, + fixed-length ==0.2.3.1, + fixed-vector ==1.2.2.1, + fixed-vector-hetero ==0.6.1.1, + fix-whitespace ==0.0.11, + flac ==0.2.0, + flac-picture ==0.1.2, + flags-applicative ==0.1.0.3, + flat-mcmc ==1.5.2, + flatparse ==0.3.5.1, + flay ==0.4, + flexible-defaults ==0.0.3, + FloatingHex ==0.5, + floatshow ==0.2.4, + flow ==2.0.0.3, + flush-queue ==1.0.0, + fmlist ==0.9.4, + fmt ==0.6.3.0, + fn ==0.3.0.2, + focus ==1.0.3.1, + focuslist ==0.1.1.0, + foldl ==1.4.14, + folds ==0.7.8, + follow-file ==0.0.3, + FontyFruity ==0.5.3.5, + force-layout ==0.4.0.6, + foreign-store ==0.2, + ForestStructures ==0.0.1.1, + forkable-monad ==0.2.0.3, + forma ==1.2.0, + formatn ==0.2.2, + format-numbers ==0.1.0.1, + formatting ==7.1.3, + fortran-src ==0.12.0, + foundation ==0.0.30, + fourmolu ==0.9.0.0, + freckle-app ==1.3.0.0, + free ==5.1.10, + free-categories ==0.2.0.2, + freenect ==1.2.1, + freer-simple ==1.2.1.2, + freetype2 ==0.2.0, + free-vl ==0.1.4, + friendly-time ==0.4.1, + frisby ==0.2.4, + from-sum ==0.2.3.0, + frontmatter ==0.1.0.2, + fsnotify ==0.3.0.1, + fsnotify-conduit ==0.1.1.1, + ftp-client ==0.5.1.4, + funcmp ==1.9, + function-builder ==0.3.0.1, + functor-classes-compat ==2.0.0.2, + fused-effects ==1.1.2.2, + fusion-plugin ==0.2.6, + fusion-plugin-types ==0.1.0, + fuzzcheck ==0.1.1, + fuzzy ==0.1.0.1, + fuzzy-dates ==0.1.1.2, + fuzzyset ==0.2.3, + fuzzy-time ==0.2.0.3, + gauge ==0.2.5, + gd ==3000.7.3, + gdp ==0.0.3.0, + gemini-exports ==0.1.0.0, + general-games ==1.1.1, + generic-aeson ==0.2.0.14, + generic-arbitrary ==1.0.1, + generic-constraints ==1.1.1.1, + generic-data ==1.0.0.1, + generic-data-surgery ==0.3.0.0, + generic-deriving ==1.14.4, + generic-functor ==1.1.0.0, + generic-lens ==2.2.2.0, + generic-lens-core ==2.2.1.0, + generic-monoid ==0.1.0.1, + generic-optics ==2.2.1.0, + GenericPretty ==1.2.2, + generic-random ==1.5.0.1, + generics-eot ==0.4.0.1, + generics-sop ==0.5.1.3, + generics-sop-lens ==0.2.0.1, + genvalidity ==1.1.0.0, + genvalidity-aeson ==1.0.0.1, + genvalidity-appendful ==0.1.0.0, + genvalidity-bytestring ==1.0.0.1, + genvalidity-case-insensitive ==0.0.0.1, + genvalidity-containers ==1.0.0.1, + genvalidity-criterion ==1.1.0.0, + genvalidity-hspec ==1.0.0.2, + genvalidity-hspec-aeson ==1.0.0.0, + genvalidity-hspec-binary ==1.0.0.0, + genvalidity-hspec-cereal ==1.0.0.0, + genvalidity-hspec-hashable ==1.0.0.0, + genvalidity-hspec-optics ==1.0.0.0, + genvalidity-hspec-persistent ==1.0.0.0, + genvalidity-mergeful ==0.3.0.0, + genvalidity-mergeless ==0.3.0.0, + genvalidity-path ==1.0.0.1, + genvalidity-persistent ==1.0.0.1, + genvalidity-property ==1.0.0.0, + genvalidity-scientific ==1.0.0.0, + genvalidity-sydtest ==1.0.0.0, + genvalidity-sydtest-aeson ==1.0.0.0, + genvalidity-sydtest-hashable ==1.0.0.0, + genvalidity-sydtest-lens ==1.0.0.0, + genvalidity-sydtest-persistent ==1.0.0.0, + genvalidity-text ==1.0.0.1, + genvalidity-time ==1.0.0.1, + genvalidity-typed-uuid ==0.1.0.1, + genvalidity-unordered-containers ==1.0.0.0, + genvalidity-uuid ==1.0.0.1, + genvalidity-vector ==1.0.0.0, + geodetics ==0.1.2, + geojson ==4.1.1, + getopt-generics ==0.13.1.0, + ghc installed, + ghc-bignum installed, + ghc-bignum-orphans ==0.1.1, + ghc-byteorder ==4.11.0.0.10, + ghc-check ==0.5.0.8, + ghc-compact ==0.1.0.0, + ghc-core ==0.5.6, + ghc-events ==0.18.0, + ghc-exactprint ==1.5.0, + ghcid ==0.8.7, + ghci-hexcalc ==0.1.1.0, + ghcjs-codemirror ==0.0.0.2, + ghcjs-perch ==0.3.3.3, + ghc-lib ==9.2.7.20230228, + ghc-lib-parser ==9.2.7.20230228, + ghc-lib-parser-ex ==9.2.0.4, + ghc-parser ==0.2.4.0, + ghc-paths ==0.1.0.12, + ghc-prim installed, + ghc-prof ==1.4.1.12, + ghc-source-gen ==0.4.3.0, + ghc-syntax-highlighter ==0.0.8.0, + ghc-tcplugins-extra ==0.4.4, + ghc-trace-events ==0.1.2.7, + ghc-typelits-extra ==0.4.5, + ghc-typelits-knownnat ==0.7.8, + ghc-typelits-natnormalise ==0.7.8, + ghc-typelits-presburger ==0.6.2.0, + ghost-buster ==0.1.1.0, + gi-atk ==2.0.27, + gi-cairo ==1.0.29, + gi-cairo-connector ==0.1.1, + gi-cairo-render ==0.1.2, + gi-dbusmenu ==0.4.13, + gi-dbusmenugtk3 ==0.4.14, + gi-freetype2 ==2.0.4, + gi-gdk ==3.0.28, + gi-gdkpixbuf ==2.0.31, + gi-gdkx11 ==3.0.15, + gi-gio ==2.0.32, + gi-glib ==2.0.29, + gi-gmodule ==2.0.5, + gi-gobject ==2.0.30, + gi-graphene ==1.0.7, + gi-gtk ==3.0.41, + gi-gtk-hs ==0.3.16, + gi-gtksource ==3.0.28, + gi-harfbuzz ==0.0.9, + gi-javascriptcore ==4.0.27, + gio ==0.13.10.0, + gi-pango ==1.0.29, + githash ==0.1.6.3, + github ==0.28.0.1, + github-release ==2.0.0.6, + github-rest ==1.1.3, + github-types ==0.2.1, + github-webhooks ==0.16.0, + gitlab-haskell ==1.0.0.1, + git-lfs ==1.2.0, + gitlib ==3.1.3, + gitrev ==1.3.1, + gi-vte ==2.91.31, + gi-xlib ==2.0.13, + gl ==0.9, + glasso ==0.1.0, + GLFW-b ==3.3.0.0, + glib ==0.13.10.0, + Glob ==0.10.2, + glob-posix ==0.2.0.1, + gloss ==1.13.2.2, + gloss-algorithms ==1.13.0.3, + gloss-examples ==1.13.0.4, + gloss-raster ==1.13.1.2, + gloss-rendering ==1.13.1.2, + GLURaw ==2.0.0.5, + GLUT ==2.7.0.16, + gmail-simple ==0.1.0.4, + gnuplot ==0.5.7, + goldplate ==0.2.1.1, + google-isbn ==1.0.3, + gopher-proxy ==0.1.1.3, + gotyno-hs ==1.1.0, + gpolyline ==0.1.0.1, + graph-core ==0.3.0.0, + graphite ==0.10.0.1, + graphql-client ==1.2.2, + graphs ==0.7.2, + graphula ==2.0.2.2, + graphviz ==2999.20.1.0, + graph-wrapper ==0.2.6.0, + gravatar ==0.8.1, + gridtables ==0.0.3.0, + groom ==0.1.2.1, + grouped-list ==0.2.3.0, + groups ==0.5.3, + gtk ==0.15.8, + gtk2hs-buildtools ==0.13.10.0, + gtk3 ==0.15.8, + gtk-sni-tray ==0.1.8.1, + gtk-strut ==0.1.3.2, + guarded-allocation ==0.0.1, + hackage-cli ==0.0.3.6, + hackage-db ==2.1.3, + hackage-security ==0.6.2.3, + haddock-library ==1.10.0, + hakyll ==4.15.1.1, + hakyll-convert ==0.3.0.4, + hal ==1.0.0.1, + half ==0.3.1, + hall-symbols ==0.1.0.6, + hamlet ==1.2.0, + hamtsolo ==1.0.4, + HandsomeSoup ==0.4.2, + handwriting ==0.1.0.3, + happstack-hsp ==7.3.7.7, + happstack-jmacro ==7.0.12.5, + happstack-server ==7.7.2, + happstack-server-tls ==7.2.1.3, + happy ==1.20.1.1, + happy-meta ==0.2.1.0, + harp ==0.4.3.6, + HasBigDecimal ==0.2.0.0, + hasbolt ==0.1.6.2, + hashable ==1.4.2.0, + hashids ==1.0.2.7, + hashmap ==1.3.3, + hashtables ==1.3.1, + haskeline ==0.8.2.1, + haskell-gi ==0.26.7, + haskell-gi-base ==0.26.4, + haskell-gi-overloading ==1.0, + haskell-lexer ==1.1.1, + HaskellNet ==0.6.1.2, + HaskellNet-SSL ==0.3.4.4, + haskell-src ==1.0.4, + haskell-src-exts ==1.23.1, + haskell-src-exts-simple ==1.23.0.0, + haskell-src-exts-util ==0.2.5, + haskell-src-meta ==0.8.12, + haskey-btree ==0.3.0.1, + haskintex ==0.8.0.1, + haskoin-core ==0.21.2, + haskoin-store-data ==0.65.5, + hasktags ==0.72.0, + hasql ==1.6.3, + hasql-dynamic-statements ==0.3.1.2, + hasql-implicits ==0.1.1, + hasql-migration ==0.3.0, + hasql-notifications ==0.2.0.5, + hasql-optparse-applicative ==0.5, + hasql-pool ==0.8.0.7, + hasql-queue ==1.2.0.2, + hasql-th ==0.4.0.18, + hasql-transaction ==1.0.1.2, + has-transformers ==0.1.0.4, + hasty-hamiltonian ==1.3.4, + HaTeX ==3.22.3.2, + HaXml ==1.25.12, + haxr ==3000.11.5, + HCodecs ==0.5.2, + hdaemonize ==0.5.6, + HDBC ==2.4.0.4, + HDBC-session ==0.1.2.0, + headed-megaparsec ==0.2.1.1, + heap ==1.0.4, + heaps ==0.4, + heatshrink ==0.1.0.0, + hebrew-time ==0.1.2, + hedgehog ==1.1.2, + hedgehog-classes ==0.2.5.4, + hedgehog-corpus ==0.2.0, + hedgehog-fakedata ==0.0.1.5, + hedgehog-fn ==1.0, + hedgehog-quickcheck ==0.1.1, + hedis ==0.15.2, + hedn ==0.3.0.4, + here ==1.2.13, + heredoc ==0.2.0.0, + heterocephalus ==1.0.5.7, + hex ==0.2.0, + hexml ==0.3.4, + hexml-lens ==0.2.2, + hexpat ==0.20.13, + hex-text ==0.1.0.8, + hformat ==0.3.3.1, + hfsevents ==0.1.6, + hgeometry ==0.14, + hgeometry-combinatorial ==0.14, + hidapi ==0.1.8, + hie-bios ==0.9.1, + hierarchical-clustering ==0.4.7, + hi-file-parser ==0.1.4.0, + highlighting-kate ==0.6.4, + hindent ==5.3.4, + hinfo ==0.0.3.0, + hinotify ==0.4.1, + hint ==0.9.0.7, + hip ==1.5.6.0, + histogram-fill ==0.9.1.0, + hjsmin ==0.2.0.4, + hkd-default ==1.1.0.0, + hkgr ==0.4.2, + hledger ==1.27.1, + hledger-interest ==1.6.5, + hledger-lib ==1.27.1, + hledger-stockquotes ==0.1.2.1, + hledger-ui ==1.27.1, + hledger-web ==1.27.1, + hlibcpuid ==0.2.0, + hlibgit2 ==0.18.0.16, + hlibsass ==0.1.10.1, + hlint ==3.4.1, + hmatrix ==0.20.2, + hmatrix-gsl ==0.19.0.1, + hmatrix-gsl-stats ==0.4.1.8, + hmatrix-morpheus ==0.1.1.2, + hmatrix-repa ==0.1.2.2, + hmatrix-special ==0.19.0.0, + hmatrix-vector-sized ==0.1.3.0, + HMock ==0.5.1.0, + hnock ==0.4.0, + hoauth2 ==2.6.0, + hoogle ==5.0.18.3, + hopenssl ==2.2.5, + hopfli ==0.2.2.1, + horizontal-rule ==0.5.0.0, + hosc ==0.19.1, + hostname ==1.0, + hostname-validate ==1.0.0, + hourglass ==0.2.12, + hourglass-orphans ==0.1.0.0, + hp2pretty ==0.10, + hpack ==0.35.2, + hpack-dhall ==0.5.7, + hpc installed, + hpc-codecov ==0.3.0.0, + hpc-lcov ==1.1.1, + HPDF ==1.6.1, + hpp ==0.6.5, + hpqtypes ==1.9.4.0, + hreader ==1.1.0, + hreader-lens ==0.1.3.0, + hruby ==0.5.0.0, + hsass ==0.8.0, + hs-bibutils ==6.10.0.0, + hsc2hs ==0.68.9, + hscolour ==1.24.4, + hsdns ==1.8, + hse-cpp ==0.2, + hsemail ==2.2.1, + hset ==2.2.0, + hs-GeoIP ==0.3, + hsignal ==0.2.7.5, + hsini ==0.5.1.2, + hsinstall ==2.7, + HSlippyMap ==3.0.1, + hslogger ==1.3.1.0, + hslua ==2.2.1, + hslua-aeson ==2.2.1, + hslua-classes ==2.2.0, + hslua-core ==2.2.1, + hslua-marshalling ==2.2.1, + hslua-module-doclayout ==1.0.4, + hslua-module-path ==1.0.3, + hslua-module-system ==1.0.3, + hslua-module-text ==1.0.3.1, + hslua-module-version ==1.0.3, + hslua-objectorientation ==2.2.1, + hslua-packaging ==2.2.1, + hsndfile ==0.8.0, + hsndfile-vector ==0.5.2, + HsOpenSSL ==0.11.7.5, + HsOpenSSL-x509-system ==0.1.0.4, + hsp ==0.10.0, + hspec ==2.9.7, + hspec-attoparsec ==0.1.0.2, + hspec-checkers ==0.1.0.2, + hspec-contrib ==0.5.2, + hspec-core ==2.9.7, + hspec-discover ==2.9.7, + hspec-expectations ==0.8.2, + hspec-expectations-json ==1.0.0.7, + hspec-expectations-lifted ==0.10.0, + hspec-expectations-pretty-diff ==0.7.2.6, + hspec-golden ==0.2.1.0, + hspec-golden-aeson ==0.9.0.0, + hspec-hedgehog ==0.0.1.2, + hspec-junit-formatter ==1.1.0.2, + hspec-leancheck ==0.0.6, + hspec-megaparsec ==2.2.0, + hspec-meta ==2.9.3, + hspec-need-env ==0.1.0.10, + hspec-parsec ==0, + hspec-smallcheck ==0.5.2, + hspec-tmp-proc ==0.5.1.2, + hspec-wai ==0.11.1, + hspec-wai-json ==0.11.0, + hs-php-session ==0.0.9.3, + hsshellscript ==3.5.0, + hstatistics ==0.3.1, + HStringTemplate ==0.8.8, + HSvm ==0.1.1.3.25, + hsx2hs ==0.14.1.11, + hsx-jmacro ==7.3.8.2, + HsYAML ==0.2.1.1, + HsYAML-aeson ==0.2.0.1, + hsyslog ==5.0.2, + htaglib ==1.2.0, + HTF ==0.15.0.1, + html ==1.0.1.2, + html-conduit ==1.3.2.2, + html-email-validate ==0.2.0.0, + html-entities ==1.1.4.6, + html-entity-map ==0.1.0.0, + htoml-megaparsec ==2.1.0.4, + htoml-parse ==0.1.0.1, + HTTP ==4000.4.1, + http2 ==3.0.3, + http-api-data ==0.4.3, + http-api-data-qq ==0.1.0.0, + http-client ==0.7.13.1, + http-client-openssl ==0.3.3, + http-client-overrides ==0.1.1.0, + http-client-restricted ==0.0.5, + http-client-tls ==0.3.6.1, + http-common ==0.8.3.4, + http-conduit ==2.3.8.1, + http-date ==0.0.11, + http-directory ==0.1.10, + http-download ==0.2.0.0, + httpd-shed ==0.4.1.1, + http-io-streams ==0.1.6.2, + http-link-header ==1.2.1, + http-media ==0.8.0.0, + http-query ==0.1.3, + http-reverse-proxy ==0.6.0.1, + http-streams ==0.8.9.6, + http-types ==0.12.3, + human-readable-duration ==0.2.1.4, + HUnit ==1.6.2.0, + HUnit-approx ==1.1.1.1, + hunit-dejafu ==2.0.0.6, + hvect ==0.4.0.1, + hvega ==0.12.0.3, + hw-balancedparens ==0.4.1.3, + hw-bits ==0.7.2.2, + hw-conduit ==0.2.1.1, + hw-conduit-merges ==0.2.1.0, + hw-diagnostics ==0.0.1.0, + hw-dsv ==0.4.1.1, + hweblib ==0.6.3, + hw-eliasfano ==0.1.2.1, + hw-excess ==0.2.3.0, + hw-fingertree ==0.1.2.1, + hw-fingertree-strict ==0.1.2.1, + hw-hedgehog ==0.1.1.1, + hw-hspec-hedgehog ==0.1.1.1, + hw-int ==0.0.2.0, + hw-ip ==2.4.2.1, + hw-json ==1.3.2.4, + hw-json-simd ==0.1.1.2, + hw-json-simple-cursor ==0.1.1.1, + hw-json-standard-cursor ==0.2.3.2, + hwk ==0.6, + hw-kafka-client ==4.0.3, + hw-mquery ==0.2.1.1, + hworker ==0.1.0.1, + hw-packed-vector ==0.2.1.1, + hw-parser ==0.1.1.0, + hw-prim ==0.6.3.2, + hw-rankselect ==0.13.4.1, + hw-rankselect-base ==0.3.4.1, + hw-simd ==0.1.2.2, + hw-streams ==0.0.1.0, + hw-string-parse ==0.0.0.5, + hw-succinct ==0.1.0.1, + hw-xml ==0.5.1.1, + hxt ==9.3.1.22, + hxt-charproperties ==9.5.0.0, + hxt-css ==0.1.0.3, + hxt-curl ==9.1.1.1, + hxt-expat ==9.1.1, + hxt-http ==9.1.5.2, + hxt-regex-xmlschema ==9.2.0.7, + hxt-tagsoup ==9.1.4, + hxt-unicode ==9.0.2.4, + hybrid-vectors ==0.2.3, + hyperloglog ==0.4.6, + hyphenation ==0.8.2, + identicon ==0.2.2, + ieee754 ==0.8.0, + if ==0.1.0.0, + IfElse ==0.85, + ihaskell ==0.10.3.0, + ihaskell-hvega ==0.5.0.3, + ihs ==0.1.0.3, + ilist ==0.4.0.1, + imagesize-conduit ==1.1, + Imlib ==0.1.2, + immortal ==0.3, + immortal-queue ==0.1.0.1, + inbox ==0.2.0, + include-file ==0.1.0.4, + incremental ==0.3.1, + incremental-parser ==0.5.0.5, + indents ==0.5.0.1, + indexed ==0.1.3, + indexed-containers ==0.1.0.2, + indexed-list-literals ==0.2.1.3, + indexed-profunctors ==0.1.1, + indexed-traversable ==0.1.2.1, + indexed-traversable-instances ==0.1.1.2, + infer-license ==0.2.0, + inflections ==0.4.0.6, + influxdb ==1.9.2.2, + ini ==0.4.2, + inj ==1.0, + inline-c ==0.9.1.8, + inline-c-cpp ==0.5.0.0, + inliterate ==0.1.0, + input-parsers ==0.2.3.2, + insert-ordered-containers ==0.2.5.2, + inspection-testing ==0.4.6.1, + instance-control ==0.1.2.0, + integer-gmp installed, + integer-logarithms ==1.0.3.1, + integer-roots ==1.0.2.0, + integration ==0.2.1, + intern ==0.9.4, + interpolate ==0.2.1, + interpolatedstring-perl6 ==1.0.2, + interpolation ==0.1.1.2, + Interpolation ==0.3.0, + IntervalMap ==0.6.2.1, + intervals ==0.9.2, + intset-imperative ==0.1.0.0, + invariant ==0.6.1, + invert ==1.0.0.2, + invertible-grammar ==0.1.3.4, + io-machine ==0.2.0.0, + io-manager ==0.1.0.4, + io-memoize ==1.1.1.0, + io-region ==0.1.1, + io-storage ==0.3, + io-streams ==1.5.2.2, + io-streams-haproxy ==1.0.1.0, + ip ==1.7.6, + ip6addr ==1.0.3, + iproute ==1.7.12, + IPv6Addr ==2.0.5, + ipynb ==0.2, + ipython-kernel ==0.10.3.0, + irc ==0.6.1.0, + irc-ctcp ==0.1.3.1, + isbn ==1.1.0.4, + islink ==0.1.0.0, + iso3166-country-codes ==0.20140203.8, + iso639 ==0.1.0.3, + iso8601-time ==0.1.5, + isocline ==1.0.9, + isomorphism-class ==0.1.0.9, + iterable ==3.0, + ixset ==1.1.1.2, + ixset-typed ==0.5.1.0, + ixset-typed-binary-instance ==0.1.0.2, + ixset-typed-conversions ==0.1.2.0, + ixset-typed-hashable-instance ==0.1.0.2, + ix-shapable ==0.1.0, + jailbreak-cabal ==1.3.6, + jalaali ==1.0.0.0, + java-adt ==0.2018.11.4, + jira-wiki-markup ==1.4.0, + jl ==0.1.0, + jmacro ==0.6.18, + jose ==0.9, + jose-jwt ==0.9.5, + js-chart ==2.9.4.1, + js-dgtable ==0.5.2, + js-flot ==0.8.3, + js-jquery ==3.3.1, + json ==0.10, + json-feed ==2.0.0.8, + jsonifier ==0.2.1.2, + jsonpath ==0.3.0.0, + json-rpc ==1.0.4, + json-stream ==0.4.5.2, + JuicyPixels ==3.3.7, + JuicyPixels-extra ==0.5.2, + JuicyPixels-scale-dct ==0.1.2, + junit-xml ==0.1.0.2, + justified-containers ==0.3.0.0, + jwt ==0.11.0, + kan-extensions ==5.2.5, + kanji ==3.5.0, + kansas-comet ==0.4.1, + katip ==0.8.7.4, + katip-logstash ==0.1.0.2, + katip-wai ==0.1.2.1, + kazura-queue ==0.1.0.4, + kdt ==0.2.5, + keep-alive ==0.2.1.0, + keycode ==0.2.2, + keys ==3.12.3, + ki ==1.0.1.0, + kind-apply ==0.3.2.1, + kind-generics ==0.4.1.4, + kind-generics-th ==0.2.2.3, + ki-unlifted ==1.0.0.1, + kleene ==0.1, + kmeans ==0.1.3, + knob ==0.2.2, + koji ==0.0.2, + l10n ==0.1.0.1, + labels ==0.3.3, + lackey ==2.0.0.6, + LambdaHack ==0.11.0.0, + lame ==0.2.0, + language-avro ==0.1.4.0, + language-bash ==0.9.2, + language-c ==0.9.2, + language-c-quote ==0.13.0.1, + language-docker ==12.0.0, + language-dot ==0.1.1, + language-glsl ==0.3.0, + language-java ==0.2.9, + language-javascript ==0.7.1.0, + language-nix ==2.2.0, + language-protobuf ==1.0.1, + language-python ==0.5.8, + language-thrift ==0.12.0.1, + lapack-carray ==0.0.3, + lapack-comfort-array ==0.0.1, + lapack-ffi ==0.0.3, + lapack-ffi-tools ==0.1.3.1, + largeword ==1.2.5, + latex ==0.1.0.4, + lattices ==2.0.3, + lawful ==0.1.0.0, + lazy-csv ==0.5.1, + lazyio ==0.1.0.4, + lazysmallcheck ==0.6, + lca ==0.4, + leancheck ==0.9.12, + leancheck-instances ==0.0.5, + leapseconds-announced ==2017.1.0.1, + learn-physics ==0.6.5, + leb128-cereal ==1.2, + lens ==5.1.1, + lens-action ==0.2.6, + lens-aeson ==1.2.2, + lens-csv ==0.1.1.0, + lens-family ==2.1.2, + lens-family-core ==2.1.2, + lens-family-th ==0.5.2.1, + lens-misc ==0.0.2.0, + lens-properties ==4.11.1, + lens-regex ==0.1.3, + lens-regex-pcre ==1.1.0.0, + lentil ==1.5.5.4, + LetsBeRational ==1.0.0.0, + leveldb-haskell ==0.6.5, + lexer-applicative ==2.1.0.2, + libBF ==0.6.5.1, + libffi ==0.2.1, + libgit ==0.3.1, + libgraph ==1.14, + libmpd ==0.10.0.0, + liboath-hs ==0.0.1.2, + libyaml ==0.1.2, + lifted-async ==0.10.2.4, + lifted-base ==0.2.3.12, + lift-generics ==0.2.1, + lift-type ==0.1.1.1, + line ==4.0.1, + linear ==1.21.10, + linear-base ==0.3.1, + linear-generics ==0.2.1, + linebreak ==1.1.0.4, + linenoise ==0.3.2, + linux-capabilities ==0.1.1.0, + linux-file-extents ==0.2.0.0, + linux-namespaces ==0.1.3.0, + List ==0.6.2, + ListLike ==4.7.8, + list-predicate ==0.1.0.1, + listsafe ==0.1.0.1, + list-t ==1.0.5.6, + list-transformer ==1.0.9, + ListTree ==0.2.3, + ListZipper ==1.2.0.2, + literatex ==0.2.1.0, + little-logger ==1.0.1, + little-rio ==1.0.1, + lmdb ==0.2.5, + load-env ==0.2.1.0, + loc ==0.1.4.1, + locators ==0.3.0.3, + loch-th ==0.2.2, + lockfree-queue ==0.2.4, + log-domain ==0.13.2, + logfloat ==0.13.4, + logger-thread ==0.1.0.2, + logging ==3.0.5, + logging-effect ==1.3.13, + logging-facade ==0.3.1, + logging-facade-syslog ==1, + logict ==0.8.0.0, + logstash ==0.1.0.3, + loop ==0.3.0, + lpeg ==1.0.4, + LPFP ==1.1, + lrucache ==1.2.0.1, + lrucaching ==0.3.3, + lsp ==1.6.0.0, + lsp-types ==1.6.0.0, + lua ==2.2.1, + lua-arbitrary ==1.0.1.1, + lucid ==2.11.20230408, + lucid2 ==0.0.20221012, + lucid-cdn ==0.2.2.0, + lucid-extras ==0.2.2, + lukko ==0.1.1.3, + lxd-client-config ==0.1.0.1, + lz4 ==0.2.3.1, + lz4-frame-conduit ==0.1.0.1, + lzma ==0.0.1.0, + lzma-clib ==5.2.2, + lzma-conduit ==1.2.3, + machines ==0.7.3, + magic ==1.1, + mainland-pretty ==0.7.1, + main-tester ==0.2.0.1, + managed ==1.0.10, + mandrill ==0.5.7.0, + map-syntax ==0.3, + markdown ==0.1.17.5, + markdown-unlit ==0.5.1, + markov-chain ==0.0.3.4, + markov-chain-usage-model ==0.0.0, + mason ==0.2.6, + massiv ==1.0.4.0, + massiv-io ==1.0.0.1, + massiv-persist ==1.0.0.3, + massiv-serialise ==1.0.0.2, + massiv-test ==1.0.0.0, + mathexpr ==0.3.1.0, + math-extras ==0.1.1.0, + math-functions ==0.3.4.2, + mathlist ==0.1.0.4, + matplotlib ==0.7.7, + matrices ==0.5.0, + matrix ==0.3.6.1, + matrix-as-xyz ==0.1.2.2, + matrix-market-attoparsec ==0.1.1.3, + matrix-static ==0.3, + maximal-cliques ==0.1.1, + mcmc ==0.8.2.0, + mcmc-types ==1.0.3, + median-stream ==0.7.0.0, + med-module ==0.1.3, + megaparsec ==9.2.2, + megaparsec-tests ==9.2.2, + mega-sdist ==0.4.2.1, + membership ==0.0.1, + memcache ==0.3.0.1, + memfd ==1.0.1.3, + memory ==0.17.0, + MemoTrie ==0.6.10, + mergeful ==0.3.0.0, + mergeful-persistent ==0.1.0.0, + mergeless ==0.4.0.0, + mergeless-persistent ==0.1.0.0, + merkle-tree ==0.1.1, + mersenne-random ==1.0.0.1, + mersenne-random-pure64 ==0.2.2.0, + messagepack ==0.5.5, + metrics ==0.4.1.1, + mfsolve ==0.3.2.1, + microaeson ==0.1.0.1, + microlens ==0.4.12.0, + microlens-aeson ==2.5.0, + microlens-contra ==0.1.0.3, + microlens-ghc ==0.4.13.2, + microlens-mtl ==0.2.0.3, + microlens-platform ==0.4.2.1, + microlens-process ==0.2.0.2, + microlens-th ==0.4.3.13, + microspec ==0.2.1.3, + microstache ==1.0.2.3, + midair ==0.2.0.1, + midi ==0.2.2.4, + midi-music-box ==0.0.1.2, + mighty-metropolis ==2.0.0, + mime-mail ==0.5.1, + mime-mail-ses ==0.4.3, + mime-types ==0.1.0.9, + minimal-configuration ==0.1.4, + minimorph ==0.3.0.1, + minio-hs ==1.6.0, + minisat-solver ==0.1, + miniutter ==0.5.1.2, + min-max-pqueue ==0.1.0.2, + mintty ==0.1.4, + misfortune ==0.1.2.1, + missing-foreign ==0.1.1, + MissingH ==1.5.0.1, + mixed-types-num ==0.5.11, + mmap ==0.5.9, + mmark ==0.0.7.6, + mmark-cli ==0.0.5.1, + mmark-ext ==0.2.1.5, + mmorph ==1.2.0, + mnist-idx ==0.1.3.2, + mnist-idx-conduit ==0.4.0.0, + mockery ==0.3.5, + mock-time ==0.1.0, + mod ==0.1.2.2, + model ==0.5, + modern-uri ==0.3.6.0, + modular ==0.1.0.8, + monad-chronicle ==1.0.1, + monad-control ==1.0.3.1, + monad-coroutine ==0.9.2, + monad-extras ==0.6.0, + monadic-arrays ==0.2.2, + monad-journal ==0.8.1, + monadlist ==0.0.2, + monadloc ==0.7.1, + monad-logger ==0.3.40, + monad-logger-aeson ==0.4.0.4, + monad-logger-json ==0.1.0.0, + monad-logger-logstash ==0.2.0.2, + monad-logger-prefix ==0.1.12, + monad-loops ==0.4.3, + monad-memo ==0.5.4, + monad-metrics ==0.2.2.0, + monadoid ==0.0.3, + monadology ==0.1, + monad-par ==0.3.5, + monad-parallel ==0.8, + monad-par-extras ==0.3.3, + monad-peel ==0.2.1.2, + monad-primitive ==0.1, + monad-products ==4.0.1, + MonadPrompt ==1.0.0.5, + MonadRandom ==0.5.3, + monad-resumption ==0.1.4.0, + monad-schedule ==0.1.2.0, + monad-skeleton ==0.2, + monad-st ==0.2.4.1, + monads-tf ==0.1.0.3, + monad-time ==0.3.1.0, + mongoDB ==2.7.1.2, + monoidal-containers ==0.6.4.0, + monoid-extras ==0.6.2, + monoid-subclasses ==1.1.3, + monoid-transformer ==0.0.4, + monomer ==1.5.1.0, + mono-traversable ==1.0.15.3, + mono-traversable-instances ==0.1.1.0, + mono-traversable-keys ==0.2.0, + more-containers ==0.2.2.2, + morpheus-graphql ==0.27.3, + morpheus-graphql-app ==0.27.3, + morpheus-graphql-client ==0.27.3, + morpheus-graphql-code-gen ==0.27.3, + morpheus-graphql-code-gen-utils ==0.27.3, + morpheus-graphql-core ==0.27.3, + morpheus-graphql-server ==0.27.3, + morpheus-graphql-subscriptions ==0.27.3, + morpheus-graphql-tests ==0.27.3, + moss ==0.2.0.1, + mountpoints ==1.0.2, + mpi-hs ==0.7.2.0, + mpi-hs-binary ==0.1.1.0, + mpi-hs-cereal ==0.1.0.0, + mstate ==0.2.8, + mtl installed, + mtl-compat ==0.2.2, + mtl-prelude ==2.0.3.2, + multiarg ==0.30.0.10, + multi-containers ==0.2, + multimap ==1.2.1, + multiset ==0.3.4.3, + multistate ==0.8.0.4, + murmur3 ==1.0.5, + murmur-hash ==0.1.0.10, + MusicBrainz ==0.4.1, + mustache ==2.4.2, + mutable-containers ==0.3.4.1, + mwc-probability ==2.3.1, + mwc-random ==0.15.0.2, + mwc-random-monad ==0.7.3.1, + mx-state-codes ==1.0.0.0, + mysql ==0.2.1, + mysql-simple ==0.4.9, + n2o ==0.11.1, + n2o-nitro ==0.11.2, + nagios-check ==0.3.2, + named ==0.3.0.1, + names-th ==0.3.0.1, + nano-erl ==0.1.0.1, + NanoID ==3.2.1, + nanospec ==0.2.2, + nanovg ==0.8.1.0, + nats ==1.1.2, + natural-arithmetic ==0.1.4.0, + natural-induction ==0.2.0.0, + natural-sort ==0.1.2, + natural-transformation ==0.4, + ndjson-conduit ==0.1.0.5, + neat-interpolation ==0.5.1.3, + netcode-io ==0.0.3, + netlib-carray ==0.1, + netlib-comfort-array ==0.0.0.2, + netlib-ffi ==0.1.1, + net-mqtt ==0.8.3.0, + net-mqtt-lens ==0.1.1.0, + netpbm ==1.0.4, + netrc ==0.2.0.0, + netwire ==5.0.3, + netwire-input ==0.0.7, + netwire-input-glfw ==0.0.11, + network ==3.1.4.0, + network-bsd ==2.8.1.0, + network-byte-order ==0.1.6, + network-conduit-tls ==1.3.2, + network-info ==0.2.1, + network-ip ==0.3.0.3, + network-messagepack-rpc ==0.1.2.0, + network-messagepack-rpc-websocket ==0.1.1.1, + network-multicast ==0.3.2, + Network-NineP ==0.4.7.2, + network-run ==0.2.5, + network-simple ==0.4.5, + network-simple-tls ==0.4.1, + network-transport ==0.5.6, + network-uri ==2.6.4.2, + network-wait ==0.2.0.0, + newtype ==0.2.2.0, + newtype-generics ==0.6.2, + nfc ==0.1.1, + nicify-lib ==1.0.1, + NineP ==0.0.2.1, + nix-derivation ==1.1.2, + nix-paths ==1.0.1, + NoHoed ==0.1.1, + nonce ==1.0.7, + nondeterminism ==1.5, + non-empty ==0.3.3, + nonempty-containers ==0.3.4.4, + nonemptymap ==0.0.6.0, + non-empty-sequence ==0.2.0.4, + nonempty-vector ==0.2.2.0, + nonempty-zipper ==1.0.0.4, + non-negative ==0.1.2, + normaldistribution ==1.1.0.3, + normalization-insensitive ==2.0.2, + not-gloss ==0.7.7.0, + no-value ==1.0.0.0, + nowdoc ==0.1.1.0, + nqe ==0.6.4, + nsis ==0.3.3, + numbers ==3000.2.0.2, + numeric-extras ==0.1, + numeric-limits ==0.1.0.0, + numeric-prelude ==0.4.4, + numeric-quest ==0.2.0.2, + numhask ==0.10.1.1, + numhask-array ==0.10.2, + numhask-space ==0.10.0.1, + NumInstances ==1.4, + numtype-dk ==0.5.0.3, + nuxeo ==0.3.2, + nvim-hs ==2.3.2.3, + nvim-hs-contrib ==2.0.0.2, + nvim-hs-ghcid ==2.0.1.0, + oauthenticated ==0.3.0.0, + ObjectName ==1.1.0.2, + oblivious-transfer ==0.1.0, + ochintin-daicho ==0.3.4.2, + o-clock ==1.3.0, + ofx ==0.4.4.0, + old-locale ==1.0.0.7, + old-time ==1.1.0.3, + once ==0.4, + one-liner ==2.1, + one-liner-instances ==0.1.3.0, + OneTuple ==0.3.1, + Only ==0.1, + oo-prototypes ==0.1.0.0, + opaleye ==0.9.7.0, + OpenAL ==1.7.0.5, + openapi3 ==3.2.3, + open-browser ==0.2.1.0, + openexr-write ==0.1.0.2, + OpenGL ==3.0.3.0, + OpenGLRaw ==3.3.4.1, + openpgp-asciiarmor ==0.1.2, + opensource ==0.1.1.0, + openssl-streams ==1.2.3.0, + opentelemetry ==0.8.0, + opentelemetry-extra ==0.8.0, + opentelemetry-lightstep ==0.8.0, + opentelemetry-wai ==0.8.0, + open-witness ==0.6, + operational ==0.2.4.2, + operational-class ==0.3.0.0, + opml-conduit ==0.9.0.0, + optics ==0.4.2, + optics-core ==0.4.1, + optics-extra ==0.4.2.1, + optics-th ==0.4.1, + optics-vl ==0.2.1, + optima ==0.4.0.4, + optional-args ==1.0.2, + options ==1.2.1.1, + optparse-applicative ==0.17.1.0, + optparse-enum ==1.0.0.0, + optparse-generic ==1.4.9, + optparse-simple ==0.1.1.4, + optparse-text ==0.1.1.0, + OrderedBits ==0.0.2.0, + ordered-containers ==0.2.3, + ormolu ==0.5.0.1, + overhang ==1.0.0, + packcheck ==0.6.0, + pager ==0.1.1.0, + pagination ==0.2.2, + pagure ==0.1.1, + pagure-cli ==0.2.1, + palette ==0.3.0.2, + pandoc ==2.19.2, + pandoc-csv2table ==1.0.9, + pandoc-dhall-decoder ==0.1.0.1, + pandoc-lua-marshal ==0.1.7, + pandoc-plot ==1.5.5, + pandoc-throw ==0.1.0.0, + pandoc-types ==1.22.2.1, + pango ==0.13.10.0, + pantry ==0.5.7, + parallel ==3.2.2.0, + parallel-io ==0.3.5, + parameterized ==0.5.0.0, + parseargs ==0.2.0.9, + parsec installed, + parsec-class ==1.0.0.0, + parsec-numbers ==0.1.0, + parsec-numeric ==0.1.0.0, + ParsecTools ==0.0.2.0, + parser-combinators ==1.3.0, + parser-combinators-tests ==1.3.0, + parsers ==0.12.11, + partial-handler ==1.0.3, + partial-isomorphisms ==0.2.3.0, + partial-order ==0.2.0.0, + partial-semigroup ==0.6.0.1, + password ==3.0.2.1, + password-instances ==3.0.0.0, + password-types ==1.0.0.0, + path ==0.9.2, + path-binary-instance ==0.1.0.1, + path-dhall-instance ==0.2.1.0, + path-extensions ==0.1.1.0, + path-extra ==0.2.0, + path-formatting ==0.1.0.0, + path-io ==1.7.0, + path-like ==0.2.0.2, + path-pieces ==0.2.1, + path-text-utf8 ==0.0.1.11, + pathtype ==0.8.1.2, + path-utils ==0.1.1.0, + pathwalk ==0.3.1.2, + pattern-arrows ==0.0.2, + pava ==0.1.1.4, + pcf-font ==0.2.2.1, + pcg-random ==0.1.4.0, + pcre2 ==2.1.1.1, + pcre-heavy ==1.0.0.3, + pcre-light ==0.4.1.0, + pcre-utils ==0.1.9, + pdc ==0.1.1, + pdf-toolbox-content ==0.1.1, + pdf-toolbox-core ==0.1.1, + pdf-toolbox-document ==0.1.2, + peano ==0.1.0.1, + pedersen-commitment ==0.2.0, + pem ==0.2.4, + percent-format ==0.0.2, + peregrin ==0.3.3, + perfect-hash-generator ==1.0.0, + persist ==0.1.1.5, + persistent ==2.13.3.5, + persistent-discover ==0.1.0.6, + persistent-documentation ==0.1.0.4, + persistent-iproute ==0.2.5, + persistent-mongoDB ==2.13.0.1, + persistent-mysql ==2.13.1.4, + persistent-pagination ==0.1.1.2, + persistent-postgresql ==2.13.5.2, + persistent-qq ==2.12.0.2, + persistent-redis ==2.13.0.1, + persistent-refs ==0.4, + persistent-sqlite ==2.13.1.1, + persistent-template ==2.12.0.0, + persistent-test ==2.13.1.2, + persistent-typed-db ==0.1.0.7, + pg-harness-client ==0.6.0, + pgp-wordlist ==0.1.0.3, + pg-transact ==0.3.2.0, + phantom-state ==0.2.1.2, + phatsort ==0.5.0.1, + picosat ==0.1.6, + pid1 ==0.1.3.1, + pinch ==0.4.3.0, + pipes ==4.3.16, + pipes-attoparsec ==0.5.1.5, + pipes-bytestring ==2.1.7, + pipes-concurrency ==2.0.14, + pipes-csv ==1.4.3, + pipes-extras ==1.0.15, + pipes-fastx ==0.3.0.0, + pipes-fluid ==0.6.0.1, + pipes-group ==1.0.12, + pipes-mongodb ==0.1.0.0, + pipes-ordered-zip ==1.2.1, + pipes-parse ==3.0.9, + pipes-random ==1.0.0.5, + pipes-safe ==2.3.4, + pipes-text ==1.0.1, + pipes-wai ==3.2.0, + pkgtreediff ==0.6.0, + place-cursor-at ==1.0.1, + placeholders ==0.1, + plaid ==0.1.0.4, + plot ==0.2.3.11, + plotlyhs ==0.2.3, + Plural ==0.0.2, + pointed ==5.0.4, + pointedlist ==0.6.1, + pointless-fun ==1.1.0.8, + poll ==0.0.0.2, + poly ==0.5.1.0, + poly-arity ==0.1.0, + polynomials-bernstein ==1.1.2, + polyparse ==1.13, + polysemy ==1.7.1.0, + polysemy-extra ==0.2.1.0, + polysemy-fs ==0.1.0.0, + polysemy-kvstore ==0.1.3.0, + polysemy-methodology ==0.2.2.0, + polysemy-plugin ==0.4.5.0, + polysemy-several ==0.1.1.0, + polysemy-webserver ==0.2.1.1, + polysemy-zoo ==0.8.1.0, + pontarius-xmpp ==0.5.6.6, + pooled-io ==0.0.2.3, + portable-lines ==0.1, + port-utils ==0.2.1.0, + posix-paths ==0.3.0.0, + posix-pty ==0.2.2, + possibly ==1.0.0.0, + postgres-options ==0.2.0.0, + postgresql-binary ==0.13.1, + postgresql-libpq ==0.9.5.0, + postgresql-libpq-notify ==0.2.0.0, + postgresql-migration ==0.2.1.7, + postgresql-query ==3.10.0, + postgresql-schema ==0.1.14, + postgresql-simple ==0.6.4, + postgresql-simple-url ==0.2.1.0, + postgresql-syntax ==0.4.1, + postgresql-typed ==0.6.2.2, + post-mess-age ==0.2.1.0, + pptable ==0.3.0.0, + pqueue ==1.4.3.0, + prefix-units ==0.2.0, + prelude-compat ==0.0.0.2, + prelude-safeenum ==0.1.1.3, + pretty installed, + pretty-class ==1.0.1.1, + prettyclass ==1.0.0.0, + pretty-diff ==0.4.0.3, + pretty-hex ==1.1, + prettyprinter ==1.7.1, + prettyprinter-ansi-terminal ==1.1.3, + prettyprinter-combinators ==0.1.1.1, + prettyprinter-compat-annotated-wl-pprint ==1.1, + prettyprinter-compat-ansi-wl-pprint ==1.0.2, + prettyprinter-compat-wl-pprint ==1.0.1, + prettyprinter-convert-ansi-wl-pprint ==1.1.2, + pretty-relative-time ==0.3.0.0, + pretty-show ==1.10, + pretty-simple ==4.1.2.0, + pretty-sop ==0.2.0.3, + pretty-terminal ==0.1.0.0, + pretty-types ==0.4.0.0, + primes ==0.2.1.0, + primitive ==0.7.3.0, + primitive-addr ==0.1.0.2, + primitive-extras ==0.10.1.6, + primitive-offset ==0.2.0.0, + primitive-unaligned ==0.1.1.2, + primitive-unlifted ==0.1.3.1, + prim-uniq ==0.2, + print-console-colors ==0.1.0.0, + probability ==0.2.8, + process installed, + process-extras ==0.7.4, + product-profunctors ==0.11.1.1, + profiterole ==0.1, + profiteur ==0.4.6.1, + profunctors ==5.6.2, + projectroot ==0.2.0.1, + project-template ==0.2.1.0, + prometheus ==2.2.3, + prometheus-client ==1.1.0, + prometheus-metrics-ghc ==1.0.1.2, + prometheus-wai-middleware ==1.0.1.0, + promises ==0.3, + prompt ==0.1.1.2, + prospect ==0.1.0.0, + protobuf ==0.2.1.3, + protobuf-simple ==0.1.1.1, + protocol-radius ==0.0.1.1, + protocol-radius-test ==0.1.0.1, + proto-lens ==0.7.1.3, + proto-lens-arbitrary ==0.1.2.11, + proto-lens-optparse ==0.1.1.10, + proto-lens-protobuf-types ==0.7.1.2, + proto-lens-protoc ==0.7.1.1, + proto-lens-runtime ==0.7.0.4, + proto-lens-setup ==0.4.0.6, + protolude ==0.3.3, + proxied ==0.3.1, + psql-helpers ==0.1.0.0, + psqueues ==0.2.7.3, + pthread ==0.2.1, + ptr ==0.16.8.4, + ptr-poker ==0.1.2.8, + pulse-simple ==0.1.14, + pureMD5 ==2.1.4, + purescript-bridge ==0.14.0.0, + pusher-http-haskell ==2.1.0.13, + pvar ==1.0.0.0, + pwstore-fast ==2.4.4, + PyF ==0.11.1.1, + qchas ==1.1.0.1, + qm-interpolated-string ==0.3.1.0, + qrcode-core ==0.9.8, + qrcode-juicypixels ==0.8.5, + quadratic-irrational ==0.1.1, + QuasiText ==0.1.2.6, + QuickCheck ==2.14.3, + quickcheck-arbitrary-adt ==0.3.1.0, + quickcheck-assertions ==0.3.0, + quickcheck-classes ==0.6.5.0, + quickcheck-classes-base ==0.6.2.0, + quickcheck-higherorder ==0.1.0.1, + quickcheck-instances ==0.3.29.1, + quickcheck-io ==0.2.0, + quickcheck-simple ==0.1.1.1, + quickcheck-special ==0.1.0.6, + quickcheck-state-machine ==0.7.3, + quickcheck-text ==0.1.2.1, + quickcheck-transformer ==0.3.1.2, + quickcheck-unicode ==1.0.1.0, + quicklz ==1.5.0.11, + quiet ==0.2, + quote-quot ==0.2.1.0, + radius ==0.7.1.0, + rainbow ==0.34.2.2, + rainbox ==0.26.0.0, + ral ==0.2.1, + rampart ==2.0.0.6, + ramus ==0.1.2, + rando ==0.0.0.4, + random ==1.2.1.1, + random-bytestring ==0.1.4, + random-fu ==0.3.0.1, + random-shuffle ==0.0.4, + random-tree ==0.6.0.5, + range ==0.3.0.2, + ranged-list ==0.1.2.0, + Ranged-sets ==0.4.0, + ranges ==0.2.4, + range-set-list ==0.1.3.1, + rank1dynamic ==0.4.1, + rank2classes ==1.4.6, + Rasterific ==0.7.5.4, + rasterific-svg ==0.3.3.2, + ratel ==2.0.0.8, + ratel-wai ==2.0.0.4, + ratio-int ==0.1.2, + rattle ==0.2, + rattletrap ==11.2.14, + Rattus ==0.5.1, + rawfilepath ==1.0.1, + rawstring-qm ==0.2.3.0, + raw-strings-qq ==1.1, + rcu ==0.2.6, + rdtsc ==1.3.0.1, + re2 ==0.3, + reactive-banana ==1.3.2.0, + read-editor ==0.1.0.2, + read-env-var ==1.0.0.0, + rebase ==1.16.1, + rec-def ==0.2.1, + record-dot-preprocessor ==0.2.16, + record-hasfield ==1.0, + rec-smallarray ==0.1.0.0, + recursion-schemes ==5.2.2.4, + recv ==0.0.0, + redact ==0.4.0.0, + reddit-scrape ==0.0.1, + redis-resp ==1.0.0, + reducers ==3.12.4, + refact ==0.3.0.2, + ref-fd ==0.5.0.1, + refined ==0.8.1, + reflection ==2.1.7, + reform ==0.2.7.5, + reform-blaze ==0.2.4.4, + reform-hamlet ==0.0.5.3, + reform-happstack ==0.2.5.6, + reform-hsp ==0.2.7.2, + RefSerialize ==0.4.0, + ref-tf ==0.5.0.1, + regex ==1.1.0.2, + regex-applicative ==0.3.4, + regex-applicative-text ==0.1.0.1, + regex-base ==0.94.0.2, + regex-compat ==0.95.2.1, + regex-pcre ==0.95.0.0, + regex-pcre-builtin ==0.95.2.3.8.44, + regex-posix ==0.96.0.1, + regex-posix-clib ==2.7, + regex-tdfa ==1.3.2.1, + regex-with-pcre ==1.1.0.2, + registry ==0.3.3.4, + registry-aeson ==0.2.3.3, + registry-hedgehog ==0.7.2.0, + registry-hedgehog-aeson ==0.2.0.0, + registry-options ==0.1.0.0, + reinterpret-cast ==0.1.0, + rel8 ==1.4.1.0, + relapse ==1.0.0.1, + reliable-io ==0.0.2, + relude ==1.1.0.0, + renderable ==0.2.0.1, + reorder-expression ==0.1.0.0, + repa ==3.4.1.5, + repa-algorithms ==3.4.1.5, + repa-io ==3.4.1.2, + replace-attoparsec ==1.4.5.0, + replace-megaparsec ==1.4.5.0, + repline ==0.4.2.0, + req ==3.13.0, + req-conduit ==1.0.1, + rerebase ==1.16.1, + reroute ==0.7.0.0, + resolv ==0.1.2.0, + resource-pool ==0.2.3.2, + resourcet ==1.2.6, + result ==0.2.6.0, + retry ==0.9.3.1, + rev-state ==0.1.2, + rex ==0.6.2, + rfc1751 ==0.1.3, + rfc5051 ==0.2, + rg ==1.4.0.0, + rhbzquery ==0.4.4, + riak-protobuf ==0.25.0.0, + rio ==0.1.22.0, + rio-orphans ==0.1.2.0, + rio-prettyprint ==0.1.3.0, + rng-utils ==0.3.1, + roc-id ==0.1.0.0, + rocksdb-haskell ==1.0.1, + rocksdb-haskell-jprupp ==2.1.4, + rocksdb-query ==0.4.2, + roles ==0.2.1.0, + rollbar ==1.1.3, + rosezipper ==0.2, + rot13 ==0.2.0.1, + rpmbuild-order ==0.4.10, + rpm-nvr ==0.1.2, + rp-tree ==0.7.1, + rrb-vector ==0.1.1.0, + RSA ==2.4.1, + rss ==3000.2.0.7, + rss-conduit ==0.6.0.1, + run-haskell-module ==0.0.2, + runmemo ==1.0.0.1, + run-st ==0.1.3.0, + rvar ==0.3.0.2, + s3-signer ==0.5.0.0, + safe ==0.3.19, + safe-coloured-text ==0.2.0.1, + safe-coloured-text-gen ==0.0.0.1, + safe-coloured-text-layout ==0.0.0.0, + safe-coloured-text-layout-gen ==0.0.0.0, + safe-coloured-text-terminfo ==0.1.0.0, + safecopy ==0.10.4.2, + safe-decimal ==0.2.1.0, + safe-exceptions ==0.1.7.3, + safe-exceptions-checked ==0.1.0, + safe-foldable ==0.1.0.0, + safeio ==0.0.5.0, + safe-json ==1.1.3.1, + safe-money ==0.9.1, + SafeSemaphore ==0.10.1, + salve ==2.0.0.3, + sample-frame ==0.0.4, + sample-frame-np ==0.0.5, + sampling ==0.3.5, + sandi ==0.5, + sandwich ==0.1.4.0, + sandwich-hedgehog ==0.1.3.0, + sandwich-quickcheck ==0.1.0.7, + sandwich-slack ==0.1.1.0, + sandwich-webdriver ==0.1.2.0, + say ==0.1.0.1, + sbp ==4.9.0, + sbv ==9.0, + scalpel ==0.6.2.1, + scalpel-core ==0.6.2.1, + scanf ==0.1.0.0, + scanner ==0.3.1, + scheduler ==2.0.0.1, + SciBaseTypes ==0.1.1.0, + scientific ==0.3.7.0, + scientist ==0.0.0.0, + scotty ==0.12.1, + scrypt ==0.5.0, + sdl2 ==2.5.5.0, + sdl2-gfx ==0.3.0.0, + sdl2-image ==2.1.0.0, + sdl2-mixer ==1.2.0.0, + sdl2-ttf ==2.1.3, + search-algorithms ==0.3.2, + secp256k1-haskell ==0.6.1, + securemem ==0.1.10, + selda ==0.5.2.0, + selda-json ==0.1.1.1, + selda-sqlite ==0.1.7.2, + selections ==0.3.0.0, + selective ==0.5, + semialign ==1.2.0.1, + semialign-indexed ==1.2, + semialign-optics ==1.2, + semigroupoid-extras ==5, + semigroupoids ==5.3.7, + semigroups ==0.20, + semirings ==0.6, + semiring-simple ==1.0.0.1, + semver ==0.4.0.1, + sendfile ==0.7.11.4, + sendgrid-v3 ==1.0.0.1, + seqalign ==0.2.0.4, + seqid ==0.6.2, + seqid-streams ==0.7.2, + sequence-formats ==1.6.6.1, + sequenceTools ==1.5.2, + serf ==0.1.1.0, + serialise ==0.2.6.0, + servant ==0.19.1, + servant-auth ==0.4.1.0, + servant-auth-client ==0.4.1.0, + servant-auth-docs ==0.2.10.0, + servant-auth-server ==0.4.7.0, + servant-auth-swagger ==0.2.10.1, + servant-auth-wordpress ==1.0.0.2, + servant-blaze ==0.9.1, + servant-cassava ==0.10.2, + servant-checked-exceptions ==2.2.0.1, + servant-checked-exceptions-core ==2.2.0.1, + servant-client ==0.19, + servant-client-core ==0.19, + servant-conduit ==0.15.1, + servant-docs ==0.12, + servant-elm ==0.7.3, + servant-exceptions ==0.2.1, + servant-exceptions-server ==0.2.1, + servant-foreign ==0.15.4, + servant-http-streams ==0.18.4, + servant-JuicyPixels ==0.3.1.0, + servant-lucid ==0.9.0.6, + servant-machines ==0.15.1, + servant-multipart ==0.12.1, + servant-multipart-api ==0.12.1, + servant-multipart-client ==0.12.1, + servant-openapi3 ==2.0.1.6, + servant-pipes ==0.15.3, + servant-rate-limit ==0.2.0.0, + servant-rawm ==1.0.0.0, + servant-ruby ==0.9.0.0, + servant-server ==0.19.2, + servant-static-th ==1.0.0.0, + servant-subscriber ==0.7.0.0, + servant-swagger ==1.1.11, + servant-swagger-ui ==0.3.5.5.0.0, + servant-swagger-ui-core ==0.3.5, + servant-swagger-ui-redoc ==0.3.4.1.22.3, + servant-websockets ==2.0.0, + servant-xml ==1.0.1.4, + serversession ==1.0.3, + serversession-backend-persistent ==2.0.1, + serversession-backend-redis ==1.0.5, + serversession-frontend-wai ==1.0.1, + serversession-frontend-yesod ==1.0.1, + servius ==1.2.3.0, + ses-html ==0.4.0.0, + set-cover ==0.1.1, + setenv ==0.1.1.3, + setlocale ==1.0.0.10, + set-monad ==0.3.0.0, + sets ==0.0.6.2, + sexp-grammar ==2.3.4.1, + sexpr-parser ==0.2.2.0, + SHA ==1.6.4.4, + shake ==0.19.7, + shake-language-c ==0.12.0, + shake-plus ==0.3.4.0, + shake-plus-extended ==0.4.1.0, + shakespeare ==2.0.30, + shakespeare-text ==1.1.0, + shared-memory ==0.2.0.1, + ShellCheck ==0.8.0, + shell-conduit ==5.0.0, + shell-escape ==0.2.0, + shellmet ==0.0.4.1, + shelltestrunner ==1.9, + shell-utility ==0.1, + shellwords ==0.1.3.1, + shelly ==1.10.0.1, + shikensu ==0.4.1, + should-not-typecheck ==2.1.0, + show-combinators ==0.2.0.0, + siggy-chardust ==1.0.0, + signal ==0.1.0.4, + silently ==1.2.5.3, + simple-affine-space ==0.1.1, + simple-cabal ==0.1.3.1, + simple-cmd ==0.2.7, + simple-cmd-args ==0.1.8, + simple-media-timestamp ==0.2.1.0, + simple-media-timestamp-attoparsec ==0.1.0.0, + simple-media-timestamp-formatting ==0.1.1.0, + simple-prompt ==0.1.0, + simple-reflect ==0.3.3, + simple-sendfile ==0.2.31, + simple-vec3 ==0.6.0.1, + since ==0.0.0, + singleton-bool ==0.1.6, + singleton-nats ==0.4.6, + singletons ==3.0.1, + singletons-base ==3.1, + singletons-presburger ==0.6.1.0, + singletons-th ==3.1, + Sit ==0.2022.3.18, + sitemap-gen ==0.1.0.0, + size-based ==0.1.3.1, + sized ==1.0.0.2, + skein ==1.0.9.4, + skews ==0.1.0.3, + skip-var ==0.1.1.0, + skylighting ==0.13.2.1, + skylighting-core ==0.13.2.1, + skylighting-format-ansi ==0.1, + skylighting-format-blaze-html ==0.1.1, + skylighting-format-context ==0.1.0.2, + skylighting-format-latex ==0.1, + slack-progressbar ==0.1.0.1, + slave-thread ==1.1.0.2, + slynx ==0.7.2.1, + smallcheck ==1.2.1.1, + smtp-mail ==0.3.0.0, + snowflake ==0.1.1.1, + socket ==0.8.3.0, + socks ==0.6.1, + solana-staking-csvs ==0.1.2.0, + some ==1.0.4.1, + some-dict-of ==0.1.0.2, + sop-core ==0.5.0.2, + sort ==1.0.0.0, + sorted-list ==0.2.1.0, + sourcemap ==0.1.7, + sox ==0.2.3.2, + spacecookie ==1.0.0.2, + sparse-linear-algebra ==0.3.1, + spatial-math ==0.2.7.0, + spdx ==1.0.0.3, + special-values ==0.1.0.0, + speculate ==0.4.14, + speedy-slice ==0.3.2, + Spintax ==0.3.6, + splice ==0.6.1.1, + split ==0.2.3.5, + splitmix ==0.1.0.4, + splitmix-distributions ==1.0.0, + Spock ==0.14.0.0, + Spock-api ==0.14.0.0, + Spock-api-server ==0.14.0.0, + Spock-core ==0.14.0.1, + Spock-lucid ==0.4.0.1, + Spock-worker ==0.3.1.0, + spoon ==0.3.1, + spreadsheet ==0.1.3.9, + sqlcli ==0.2.2.0, + sqlcli-odbc ==0.2.0.1, + sqlite-simple ==0.4.18.2, + sql-words ==0.1.6.4, + squeather ==0.8.0.0, + srcloc ==0.6.0.1, + srt ==0.1.2.0, + srt-attoparsec ==0.1.0.0, + srt-formatting ==0.1.0.0, + stache ==2.3.3, + stack ==2.9.1, + stack-all ==0.4.1, + stack-clean-old ==0.4.6, + stack-templatizer ==0.1.1.0, + state-codes ==0.1.3, + stateref ==0.3, + statestack ==0.3.1.1, + StateVar ==1.2.2, + stateWriter ==0.3.0, + static-text ==0.2.0.7, + statistics ==0.16.2.0, + status-notifier-item ==0.3.1.0, + stb-image-redux ==0.2.1.2, + step-function ==0.2.0.1, + stitch ==0.6.0.0, + stm installed, + stm-chans ==3.0.0.9, + stm-conduit ==4.0.1, + stm-containers ==1.2.0.2, + stm-delay ==0.1.1.1, + stm-extras ==0.1.0.3, + stm-hamt ==1.2.0.11, + stm-lifted ==2.5.0.0, + STMonadTrans ==0.4.7, + stm-split ==0.0.2.1, + stopwatch ==0.1.0.6, + storable-complex ==0.2.3.0, + storable-endian ==0.2.6.1, + storable-record ==0.0.7, + storable-tuple ==0.0.3.3, + storablevector ==0.2.13.1, + store ==0.7.16, + store-core ==0.4.4.4, + store-streaming ==0.2.0.3, + stratosphere ==0.60.0, + Stream ==0.4.7.2, + streaming ==0.2.3.1, + streaming-attoparsec ==1.0.0.1, + streaming-bytestring ==0.2.4, + streaming-cassava ==0.2.0.0, + streaming-commons ==0.2.2.6, + streaming-wai ==0.1.1, + streamly ==0.8.1.1, + streams ==3.3.2, + streamt ==0.5.0.1, + strict ==0.4.0.1, + strict-base-types ==0.7, + strict-concurrency ==0.2.4.3, + strict-lens ==0.4.0.2, + strict-list ==0.1.7.1, + strict-tuple ==0.1.5.2, + strict-wrapper ==0.0.0.0, + stringable ==0.1.3, + stringbuilder ==0.5.1, + string-class ==0.1.7.0, + string-combinators ==0.6.0.5, + string-conv ==0.2.0, + string-conversions ==0.4.0.1, + string-interpolate ==0.3.2.1, + stringprep ==1.0.0, + string-qq ==0.0.4, + string-random ==0.1.4.3, + stringsearch ==0.3.6.6, + string-transform ==1.1.1, + stripe-concepts ==1.0.3.2, + stripe-scotty ==1.1.0.3, + stripe-signature ==1.0.0.15, + stripe-wreq ==1.0.1.15, + strive ==6.0.0.7, + strongweak ==0.3.2, + structs ==0.1.8, + structured ==0.1.1, + structured-cli ==2.7.0.1, + stylish-haskell ==0.14.3.0, + subcategories ==0.2.0.1, + sundown ==0.6, + superbuffer ==0.3.1.2, + svg-builder ==0.1.1, + SVGFonts ==1.8.0.1, + svg-tree ==0.6.2.4, + swagger2 ==2.8.7, + swish ==0.10.4.0, + syb ==0.7.2.3, + syb-with-class ==0.6.1.14, + sydtest ==0.13.0.4, + sydtest-aeson ==0.1.0.0, + sydtest-amqp ==0.1.0.0, + sydtest-autodocodec ==0.0.0.0, + sydtest-discover ==0.0.0.3, + sydtest-hedgehog ==0.3.0.1, + sydtest-hedis ==0.0.0.0, + sydtest-hspec ==0.3.0.2, + sydtest-mongo ==0.0.0.0, + sydtest-persistent ==0.0.0.1, + sydtest-persistent-postgresql ==0.2.0.2, + sydtest-persistent-sqlite ==0.2.0.2, + sydtest-process ==0.0.0.0, + sydtest-rabbitmq ==0.1.0.0, + sydtest-servant ==0.2.0.2, + sydtest-typed-process ==0.0.0.0, + sydtest-wai ==0.2.0.0, + sydtest-yesod ==0.3.0.1, + symbol ==0.2.4, + symengine ==0.1.2.0, + symmetry-operations-symbols ==0.0.2.1, + synthesizer-core ==0.8.3, + sysinfo ==0.1.1, + system-argv0 ==0.1.1, + systemd ==2.3.0, + system-fileio ==0.3.16.4, + system-filepath ==0.4.14, + system-info ==0.5.2, + tabular ==0.2.2.8, + tagged ==0.8.6.1, + tagged-binary ==0.2.0.1, + tagged-identity ==0.1.3, + tagged-transformer ==0.8.2, + tagshare ==0.0, + tagsoup ==0.14.8, + tagstream-conduit ==0.5.6, + tao ==1.0.0, + tao-example ==1.0.0, + tar ==0.5.1.1, + tar-conduit ==0.3.2, + tardis ==0.4.4.0, + tasty ==1.4.3, + tasty-ant-xml ==1.1.8, + tasty-autocollect ==0.3.2.0, + tasty-bench ==0.3.4, + tasty-dejafu ==2.1.0.0, + tasty-discover ==4.2.2, + tasty-expected-failure ==0.12.3, + tasty-fail-fast ==0.0.3, + tasty-focus ==1.0.1, + tasty-golden ==2.3.5, + tasty-hedgehog ==1.3.1.0, + tasty-hslua ==1.0.2, + tasty-hspec ==1.2.0.2, + tasty-html ==0.4.2.1, + tasty-hunit ==0.10.0.3, + tasty-hunit-compat ==0.2.0.1, + tasty-inspection-testing ==0.1.0.1, + tasty-kat ==0.0.3, + tasty-leancheck ==0.0.2, + tasty-lua ==1.0.2, + tasty-program ==1.0.5, + tasty-quickcheck ==0.10.2, + tasty-rerun ==1.1.18, + tasty-silver ==3.3.1.1, + tasty-smallcheck ==0.8.2, + tasty-tap ==0.1.0, + tasty-test-reporter ==0.1.1.4, + tasty-th ==0.1.7, + tasty-wai ==0.1.2.0, + tce-conf ==1.3, + tcp-streams ==1.0.1.1, + tdigest ==0.2.1.1, + teardown ==0.5.0.1, + telegram-bot-simple ==0.6.2, + template ==0.2.0.10, + template-haskell installed, + template-haskell-compat-v0208 ==0.1.9.2, + temporary ==1.3, + temporary-rc ==1.2.0.3, + temporary-resourcet ==0.1.0.1, + tensorflow-test ==0.1.0.0, + tensors ==0.1.5, + termbox ==1.1.0.1, + termbox-banana ==1.0.0, + termbox-bindings-c ==0.1.0, + termbox-bindings-hs ==0.1.0, + termbox-tea ==0.1.0, + terminal-progress-bar ==0.4.2, + terminal-size ==0.3.4, + terminfo installed, + termonad ==4.4.0.0, + test-framework ==0.8.2.0, + test-framework-hunit ==0.3.0.2, + test-framework-leancheck ==0.0.4, + test-framework-quickcheck2 ==0.3.0.5, + test-framework-smallcheck ==0.2, + test-fun ==0.1.0.0, + testing-feat ==1.1.1.1, + testing-type-modifiers ==0.1.0.1, + texmath ==0.12.5.5, + text installed, + text-ansi ==0.2.1.1, + text-binary ==0.2.1.1, + text-builder ==0.6.7, + text-builder-dev ==0.3.3.2, + text-conversions ==0.3.1.1, + text-icu ==0.8.0.2, + text-latin1 ==0.3.1, + text-ldap ==0.1.1.14, + textlocal ==0.1.0.5, + text-manipulate ==0.3.1.0, + text-metrics ==0.3.2, + text-postgresql ==0.0.3.1, + text-printer ==0.5.0.2, + text-regex-replace ==0.1.1.5, + text-rope ==0.2, + text-short ==0.1.5, + text-show ==3.10.3, + text-show-instances ==3.9.5, + text-zipper ==0.12, + tfp ==1.0.2, + tf-random ==0.5, + th-abstraction ==0.4.5.0, + th-bang-compat ==0.0.1.0, + th-compat ==0.1.4, + th-constraint-compat ==0.0.1.0, + th-data-compat ==0.1.2.0, + th-desugar ==1.13.1, + th-env ==0.1.1, + these ==1.1.1.1, + these-lens ==1.0.1.2, + these-optics ==1.0.1.2, + these-skinny ==0.7.5, + th-expand-syns ==0.4.11.0, + th-extras ==0.0.0.6, + th-lego ==0.3.0.2, + th-lift ==0.8.3, + th-lift-instances ==0.1.20, + th-nowq ==0.1.0.5, + th-orphans ==0.13.14, + th-printf ==0.7, + thread-hierarchy ==0.3.0.2, + thread-local-storage ==0.2, + threads ==0.5.1.7, + threads-extras ==0.1.0.3, + thread-supervisor ==0.2.0.0, + th-reify-compat ==0.0.1.5, + th-reify-many ==0.1.10, + through-text ==0.1.0.0, + th-strict-compat ==0.1.0.1, + th-test-utils ==1.2.1, + th-utilities ==0.2.5.0, + tidal ==1.9.2, + tidal-link ==1.0.1, + tile ==0.3.0.0, + time installed, + time-compat ==1.9.6.1, + time-domain ==0.1.0.2, + timeit ==2.0, + time-lens ==0.4.0.2, + timelens ==0.2.0.2, + time-locale-compat ==0.1.1.5, + time-locale-vietnamese ==1.0.0.0, + time-manager ==0.0.0, + time-parsers ==0.1.2.1, + timerep ==2.1.0.0, + timers-tick ==0.5.0.4, + timer-wheel ==0.4.0.1, + timespan ==0.4.0.0, + time-units ==1.0.0, + time-units-types ==0.2.0.1, + timezone-olson ==0.2.1, + timezone-olson-th ==0.1.0.11, + timezone-series ==0.1.13, + titlecase ==1.0.1, + tldr ==0.9.2, + tls ==1.5.8, + tls-debug ==0.4.8, + tls-session-manager ==0.0.4, + tlynx ==0.7.2.1, + tmapchan ==0.0.3, + tmapmvar ==0.0.4, + tmp-postgres ==1.34.1.0, + tmp-proc ==0.5.1.3, + tmp-proc-postgres ==0.5.2.2, + tmp-proc-rabbitmq ==0.5.1.2, + tmp-proc-redis ==0.5.1.2, + toml-reader ==0.2.1.0, + tophat ==1.0.5.1, + topograph ==1.0.0.2, + torrent ==10000.1.3, + torsor ==0.1, + tostring ==0.2.1.1, + tracing ==0.0.7.3, + tracing-control ==0.0.7.3, + transaction ==0.1.1.4, + transformers installed, + transformers-base ==0.4.6, + transformers-compat ==0.7.2, + transformers-either ==0.1.4, + transformers-fix ==1.0, + transient ==0.7.0.0, + traverse-with-class ==1.0.1.1, + tree-diff ==0.2.2, + tree-fun ==0.8.1.0, + tree-view ==0.5.1, + trifecta ==2.1.2, + trimdent ==0.1.0.0, + triplesec ==0.2.2.1, + trivial-constraint ==0.7.0.0, + tsv2csv ==0.1.0.2, + ttc ==1.2.1.0, + ttrie ==0.1.2.2, + tuple ==0.3.0.2, + tuples ==0.1.0.0, + tuples-homogenous-h98 ==0.1.1.0, + tuple-sop ==0.3.1.0, + tuple-th ==0.2.5, + turtle ==1.5.25, + twitter-conduit ==0.6.1, + twitter-types ==0.11.0, + twitter-types-lens ==0.11.0, + typecheck-plugin-nat-simple ==0.1.0.7, + typed-process ==0.2.11.0, + typed-uuid ==0.2.0.0, + type-equality ==1, + type-errors ==0.2.0.2, + type-fun ==0.1.3, + type-hint ==0.1, + type-level-integers ==0.0.1, + type-level-kv-list ==2.0.2.0, + type-level-natural-number ==2.0, + type-level-numbers ==0.1.1.2, + type-map ==0.1.7.0, + type-natural ==1.1.0.1, + typenums ==0.1.4, + type-of-html ==1.6.2.0, + type-of-html-static ==0.1.0.2, + type-operators ==0.2.0.0, + type-rig ==0.1, + type-spec ==0.4.0.0, + typography-geometry ==1.0.1.0, + tz ==0.1.3.6, + tzdata ==0.2.20230322.0, + tztime ==0.1.0.0, + ua-parser ==0.7.7.0, + uglymemo ==0.1.0.1, + ulid ==0.3.2.0, + unagi-chan ==0.4.1.4, + unbounded-delays ==0.1.1.1, + unbound-generics ==0.4.3, + unboxed-ref ==0.4.0.0, + unboxing-vector ==0.2.0.0, + uncaught-exception ==0.1.0, + unconstrained ==0.1.0.2, + unexceptionalio ==0.5.1, + unexceptionalio-trans ==0.5.1, + unfork ==1.0.0.1, + unicode ==0.0.1.1, + unicode-collation ==0.1.3.4, + unicode-data ==0.3.1, + unicode-show ==0.1.1.1, + unicode-transforms ==0.4.0.1, + unidecode ==0.1.0.4, + unification-fd ==0.11.2, + union-angle ==0.1.0.1, + union-find ==0.2, + unipatterns ==0.0.0.0, + uniplate ==1.6.13, + uniq-deep ==1.2.1, + unique ==0.0.1, + unique-logic ==0.4.0.1, + unique-logic-tf ==0.5.1, + unit-constraint ==0.0.0, + units-parser ==0.1.1.4, + universe ==1.2.2, + universe-base ==1.1.3.1, + universe-dependent-sum ==1.3, + universe-instances-extended ==1.1.3, + universe-reverse-instances ==1.1.1, + universe-some ==1.2.1, + universum ==1.8.1.1, + unix installed, + unix-bytestring ==0.3.7.8, + unix-compat ==0.5.4, + unix-time ==0.4.9, + unjson ==0.15.4, + unliftio ==0.2.25.0, + unliftio-core ==0.2.1.0, + unliftio-path ==0.0.2.0, + unliftio-pool ==0.2.2.0, + unliftio-streams ==0.1.1.1, + unlit ==0.4.0.0, + unordered-containers ==0.2.19.1, + unsafe ==0.0, + urbit-hob ==0.3.3, + uri-bytestring ==0.3.3.1, + uri-bytestring-aeson ==0.1.0.8, + uri-encode ==1.5.0.7, + url ==2.1.3, + userid ==0.1.3.7, + users ==0.5.0.0, + users-postgresql-simple ==0.5.0.2, + users-test ==0.5.0.1, + utf8-string ==1.0.2, + utility-ht ==0.0.17, + uuid ==1.3.15, + uuid-types ==1.0.5, + valida ==1.1.0, + valida-base ==0.2.0, + validate-input ==0.5.0.0, + validation ==1.1.2, + validationt ==0.3.0, + validity ==0.12.0.1, + validity-aeson ==0.2.0.5, + validity-bytestring ==0.4.1.1, + validity-case-insensitive ==0.0.0.0, + validity-containers ==0.5.0.4, + validity-path ==0.4.0.1, + validity-persistent ==0.0.0.0, + validity-primitive ==0.0.0.1, + validity-scientific ==0.2.0.3, + validity-text ==0.3.1.3, + validity-time ==0.5.0.0, + validity-unordered-containers ==0.2.0.3, + validity-uuid ==0.1.0.3, + validity-vector ==0.2.0.3, + valor ==1.0.0.0, + variable-media-field ==0.1.0.0, + variable-media-field-dhall ==0.1.0.0, + variable-media-field-optics ==0.1.0.0, + varying ==0.8.1.0, + vault ==0.3.1.5, + vcs-ignore ==0.0.2.0, + vec ==0.4.1, + vector ==0.12.3.1, + vector-algorithms ==0.8.0.4, + vector-binary-instances ==0.2.5.2, + vector-buffer ==0.4.1, + vector-builder ==0.3.8.4, + vector-bytes-instances ==0.1.1, + vector-circular ==0.1.4, + vector-extras ==0.2.8, + vector-hashtables ==0.1.1.3, + vector-instances ==3.4.2, + vector-mmap ==0.0.3, + vector-rotcev ==0.1.0.2, + vector-sized ==1.5.0, + vector-space ==0.16, + vector-split ==1.0.0.3, + vector-stream ==0.1.0.0, + vector-th-unbox ==0.2.2, + verbosity ==0.4.0.0, + versions ==5.0.5, + vformat ==0.14.1.0, + vformat-time ==0.1.0.0, + ViennaRNAParser ==1.3.3, + vinyl ==0.14.3, + vinyl-loeb ==0.0.1.0, + vivid ==0.5.2.0, + vivid-osc ==0.5.0.0, + vivid-supercollider ==0.4.1.2, + void ==0.7.3, + vty ==5.37, + wai ==3.2.3, + wai-app-static ==3.1.7.4, + wai-cli ==0.2.3, + wai-conduit ==3.0.0.4, + wai-cors ==0.2.7, + wai-enforce-https ==1.0.0.0, + wai-eventsource ==3.0.0, + wai-extra ==3.1.13.0, + wai-feature-flags ==0.1.0.4, + wai-handler-launch ==3.0.3.1, + wai-logger ==2.4.0, + wai-middleware-bearer ==1.0.3, + wai-middleware-caching ==0.1.0.2, + wai-middleware-caching-lru ==0.1.0.0, + wai-middleware-caching-redis ==0.2.0.0, + wai-middleware-clacks ==0.1.0.1, + wai-middleware-delegate ==0.1.3.1, + wai-middleware-metrics ==0.2.4, + wai-middleware-prometheus ==1.0.0.1, + wai-middleware-static ==0.9.2, + wai-rate-limit ==0.3.0.0, + wai-rate-limit-redis ==0.2.0.1, + wai-saml2 ==0.3.0.1, + wai-session ==0.3.3, + wai-session-postgresql ==0.2.1.3, + wai-session-redis ==0.1.0.5, + wai-slack-middleware ==0.2.0, + wai-websockets ==3.0.1.2, + wakame ==0.1.0.0, + warp ==3.3.23, + warp-tls ==3.3.4, + warp-tls-uid ==0.2.0.6, + wave ==0.2.0, + wcwidth ==0.0.2, + webby ==1.1.1, + webdriver ==0.10.0.1, + webex-teams-api ==0.2.0.1, + webex-teams-conduit ==0.2.0.1, + webgear-core ==1.0.5, + webgear-openapi ==1.0.5, + webgear-server ==1.0.5, + webpage ==0.0.5.1, + web-plugins ==0.4.1, + web-routes ==0.27.15, + web-routes-boomerang ==0.28.4.4, + web-routes-happstack ==0.23.12.3, + web-routes-hsp ==0.24.6.2, + web-routes-th ==0.22.8.1, + web-routes-wai ==0.24.3.2, + webrtc-vad ==0.1.0.3, + websockets ==0.12.7.3, + weigh ==0.0.16, + wide-word ==0.1.5.0, + Win32 ==2.12.0.1, + Win32-notify ==0.3.0.3, + windns ==0.1.0.1, + witch ==1.1.6.1, + withdependencies ==0.3.0, + witherable ==0.4.2, + within ==0.2.0.1, + with-location ==0.1.0, + with-utf8 ==1.0.2.4, + witness ==0.6.1, + wizards ==1.0.3, + wl-pprint ==1.2.1, + wl-pprint-annotated ==0.1.0.1, + wl-pprint-text ==1.2.0.2, + word8 ==0.1.3, + word-compat ==0.0.6, + wordpress-auth ==1.0.0.1, + word-trie ==0.3.0, + word-wrap ==0.5, + world-peace ==1.0.2.0, + wrap ==0.0.0, + wreq ==0.5.4.0, + wreq-stringless ==0.5.9.1, + writer-cps-exceptions ==0.1.0.1, + writer-cps-mtl ==0.1.1.6, + writer-cps-transformers ==0.5.6.1, + wss-client ==0.3.0.0, + wuss ==2.0.1.3, + X11 ==1.10.3, + X11-xft ==0.3.4, + x11-xim ==0.0.9.0, + x509 ==1.7.7, + x509-store ==1.6.9, + x509-system ==1.6.7, + x509-validation ==1.6.12, + Xauth ==0.1, + xdg-basedir ==0.2.2, + xdg-desktop-entry ==0.1.1.1, + xdg-userdirs ==0.1.0.2, + xeno ==0.6, + xhtml installed, + xlsx ==1.0.0.1, + xlsx-tabular ==0.2.2.1, + xml ==1.3.14, + xml-basic ==0.1.3.2, + xmlbf ==0.6.2, + xmlbf-xeno ==0.2.1, + xmlbf-xmlhtml ==0.2, + xml-conduit ==1.9.1.2, + xml-conduit-writer ==0.1.1.2, + xmlgen ==0.6.2.2, + xml-hamlet ==0.5.0.2, + xml-helpers ==1.0.0, + xmlhtml ==0.2.5.4, + xml-html-qq ==0.1.0.1, + xml-indexed-cursor ==0.1.1.0, + xml-lens ==0.3.1, + xml-parser ==0.1.1.1, + xml-picklers ==0.3.6, + xml-to-json-fast ==2.0.0, + xml-types ==0.3.8, + xmonad ==0.17.2, + xmonad-contrib ==0.17.1, + xmonad-extras ==0.17.0, + xor ==0.0.1.1, + xss-sanitize ==0.3.7.2, + xxhash-ffi ==0.2.0.0, + yaml ==0.11.11.1, + yaml-unscrambler ==0.1.0.13, + Yampa ==0.13.7, + yarn-lock ==0.6.5, + yeshql-core ==4.2.0.0, + yesod ==1.6.2.1, + yesod-alerts ==0.1.3.0, + yesod-auth ==1.6.11.1, + yesod-auth-basic ==0.1.0.3, + yesod-auth-hashdb ==1.7.1.7, + yesod-auth-oauth2 ==0.7.1.0, + yesod-bin ==1.6.2.2, + yesod-core ==1.6.24.2, + yesod-eventsource ==1.6.0.1, + yesod-fb ==0.6.1, + yesod-form ==1.7.4, + yesod-form-bootstrap4 ==3.0.1, + yesod-gitrepo ==0.3.0, + yesod-gitrev ==0.2.2, + yesod-markdown ==0.12.6.13, + yesod-newsfeed ==1.7.0.0, + yesod-page-cursor ==2.0.1.0, + yesod-paginator ==1.1.2.2, + yesod-persistent ==1.6.0.8, + yesod-recaptcha2 ==1.0.2, + yesod-routes-flow ==3.0.0.2, + yesod-sitemap ==1.6.0, + yesod-static ==1.6.1.0, + yesod-test ==1.6.15, + yesod-websockets ==0.3.0.3, + yes-precure5-command ==5.5.3, + yi-rope ==0.11, + yjsvg ==0.2.0.1, + yjtools ==0.9.18, + yoga ==0.0.0.5, + zenacy-html ==2.0.7, + zenacy-unicode ==1.0.2, + zeromq4-haskell ==0.8.0, + zeromq4-patterns ==0.3.1.0, + zigzag ==0.0.1.0, + zim-parser ==0.2.1.0, + zio ==0.1.0.2, + zip ==1.7.2, + zip-archive ==0.4.3, + zipper-extra ==0.1.3.2, + zippers ==0.3.2, + zip-stream ==0.2.2.0, + zlib ==0.6.3.0, + zlib-bindings ==0.1.1.5, + zot ==0.0.3, + zstd ==0.1.3.0, + ztail ==1.2.0.3 + diff --git a/ci/configs/ghc-9.4.8.project b/ci/configs/ghc-9.4.8.project new file mode 100644 index 0000000..bb69787 --- /dev/null +++ b/ci/configs/ghc-9.4.8.project @@ -0,0 +1,3022 @@ +import: ../../cabal.project +with-compiler: ghc-9.4.8 +index-state: hackage.haskell.org 2024-03-05T05:41:26Z +-- NOTE: Due to revisions, this file may not work. See: +-- https://github.com/fpco/stackage-server/issues/232 + +-- Stackage snapshot from: http://www.stackage.org/snapshot/lts-21.25 +-- Please place this file next to your .cabal file as cabal.config +-- To only use tested packages, uncomment the following line: +-- remote-repo: stackage-lts-21.25:http://www.stackage.org/lts-21.25 +with-compiler: ghc-9.4.8 +constraints: abstract-deque ==0.3, + abstract-deque-tests ==0.3, + abstract-par ==0.3.3, + AC-Angle ==1.0, + acc ==0.2.0.3, + ace ==0.6, + acid-state ==0.16.1.3, + action-permutations ==0.0.0.1, + active ==0.2.1, + ad ==4.5.4, + ad-delcont ==0.3.0.0, + adjunctions ==4.4.2, + adler32 ==0.1.2.0, + advent-of-code-api ==0.2.9.1, + aern2-mp ==0.2.15.1, + aern2-real ==0.2.15, + aeson ==2.1.2.1, + aeson-attoparsec ==0.0.0, + aeson-casing ==0.2.0.0, + aeson-combinators ==0.1.1.0, + aeson-diff ==1.1.0.13, + aeson-extra ==0.5.1.2, + aeson-generic-compat ==0.0.2.0, + aeson-iproute ==0.3.0, + aeson-optics ==1.2.1, + aeson-picker ==0.1.0.6, + aeson-pretty ==0.8.9, + aeson-qq ==0.8.4, + aeson-schemas ==1.4.1.0, + aeson-typescript ==0.6.1.0, + aeson-value-parser ==0.19.7.2, + aeson-yak ==0.1.1.3, + aeson-yaml ==1.1.0.1, + Agda ==2.6.4.1, + agda2lagda ==0.2023.6.9, + al ==0.1.4.2, + alarmclock ==0.7.0.6, + alex ==3.3.0.0, + alex-meta ==0.3.0.13, + algebra ==4.3.1, + algebraic-graphs ==0.7, + align-audio ==0.0.0.1, + Allure ==0.11.0.0, + almost-fix ==0.0.2, + alsa-core ==0.5.0.1, + alsa-mixer ==0.3.0.1, + alsa-pcm ==0.6.1.1, + alsa-seq ==0.6.0.9, + alternative-vector ==0.0.0, + alternators ==1.0.0.0, + ALUT ==2.4.0.3, + amqp ==0.22.1, + amqp-utils ==0.6.3.2, + annotated-exception ==0.2.0.5, + annotated-wl-pprint ==0.7.0, + ansi-terminal ==0.11.5, + ansi-terminal-game ==1.9.2.0, + ansi-terminal-types ==0.11.5, + ansi-wl-pprint ==0.6.9, + ANum ==0.2.0.2, + aos-signature ==0.1.1, + apecs ==0.9.5, + api-field-json-th ==0.1.0.2, + api-maker ==0.1.0.6, + ap-normalize ==0.1.0.1, + appar ==0.1.8, + appendful ==0.1.0.0, + appendmap ==0.1.5, + apply-refact ==0.13.0.0, + apportionment ==0.0.0.4, + approximate ==0.3.5, + approximate-equality ==1.1.0.2, + app-settings ==0.2.0.12, + arbor-lru-cache ==0.1.1.1, + arithmoi ==0.12.1.0, + array installed, + array-memoize ==0.6.0, + arrow-extras ==0.1.0.1, + arrows ==0.4.4.2, + ascii ==1.7.0.1, + ascii-case ==1.0.1.3, + ascii-caseless ==0.0.0.1, + ascii-char ==1.0.1.0, + ascii-group ==1.0.0.16, + ascii-numbers ==1.2.0.1, + ascii-predicates ==1.0.1.3, + ascii-progress ==0.3.3.0, + ascii-superset ==1.3.0.1, + ascii-th ==1.2.0.1, + asn1-encoding ==0.9.6, + asn1-parse ==0.9.5, + asn1-types ==0.3.4, + assert-failure ==0.1.3.0, + assoc ==1.1, + astro ==0.4.3.0, + async ==2.2.5, + async-extra ==0.2.0.0, + async-refresh ==0.3.0.0, + async-refresh-tokens ==0.4.0.0, + atom-basic ==0.2.5, + atom-conduit ==0.9.0.1, + atomic-primops ==0.8.4, + atomic-write ==0.2.0.7, + attoparsec ==0.14.4, + attoparsec-aeson ==2.1.0.0, + attoparsec-base64 ==0.0.0, + attoparsec-binary ==0.2, + attoparsec-data ==1.0.5.4, + attoparsec-expr ==0.1.1.2, + attoparsec-framer ==0.1.0.1, + attoparsec-iso8601 ==1.1.0.0, + attoparsec-path ==0.0.0.1, + attoparsec-run ==0.0.2.0, + attoparsec-time ==1.0.3.1, + audacity ==0.0.2.1, + authenticate ==1.3.5.2, + authenticate-oauth ==1.7, + autodocodec ==0.2.2.0, + autodocodec-openapi3 ==0.2.1.1, + autodocodec-schema ==0.1.0.3, + autodocodec-yaml ==0.2.0.3, + autoexporter ==2.0.0.9, + auto-update ==0.1.6, + avro ==0.6.1.2, + aws ==0.24.1, + aws-cloudfront-signed-cookies ==0.2.0.12, + aws-lambda-haskell-runtime ==4.1.2, + aws-lambda-haskell-runtime-wai ==2.0.2, + aws-sns-verify ==0.0.0.2, + aws-xray-client ==0.1.0.2, + aws-xray-client-persistent ==0.1.0.5, + aws-xray-client-wai ==0.1.0.2, + backtracking ==0.1.0, + bank-holidays-england ==0.2.0.9, + barbies ==2.0.5.0, + base installed, + base16 ==0.3.2.1, + base16-bytestring ==1.0.2.0, + base32 ==0.3.1.0, + base32string ==0.9.1, + base58-bytestring ==0.1.0, + base58string ==0.10.0, + base64 ==0.4.2.4, + base64-bytestring ==1.2.1.0, + base64-bytestring-type ==1.0.1, + base64-string ==0.2, + base-compat ==0.12.3, + base-compat-batteries ==0.12.3, + basement ==0.0.16, + base-orphans ==0.9.1, + base-prelude ==1.6.1.1, + base-unicode-symbols ==0.2.4.2, + basic-prelude ==0.7.0, + battleship-combinatorics ==0.0.1, + bazel-runfiles ==0.12, + bbdb ==0.8, + bcp47 ==0.2.0.6, + bcp47-orphans ==0.1.0.6, + bcrypt ==0.0.11, + bech32 ==1.1.3, + bech32-th ==1.1.1, + bench ==1.0.12, + benchpress ==0.2.2.23, + bencode ==0.6.1.1, + bencoding ==0.4.5.4, + benri-hspec ==0.1.0.1, + between ==0.11.0.0, + bhoogle ==0.1.4.2, + bibtex ==0.1.0.7, + bifunctor-classes-compat ==0.1, + bifunctors ==5.5.15, + bimap ==0.5.0, + bimaps ==0.1.0.2, + bimap-server ==0.1.0.1, + bin ==0.1.3, + binance-exports ==0.1.2.0, + binary installed, + binary-conduit ==1.3.1, + binaryen ==0.0.6.0, + binary-generic-combinators ==0.4.4.0, + binary-ieee754 ==0.1.0.0, + binary-instances ==1.0.4, + binary-list ==1.1.1.2, + binary-orphans ==1.0.4.1, + binary-parser ==0.5.7.5, + binary-search ==2.0.0, + binary-shared ==0.8.3, + binary-tagged ==0.3.1, + bindings-DSL ==1.0.25, + bindings-GLFW ==3.3.2.0, + bindings-libzip ==1.0.1, + bindings-uname ==0.1, + BiobaseEnsembl ==0.2.0.1, + bitarray ==0.0.1.1, + bits ==0.6, + bitset-word8 ==0.1.1.2, + bits-extra ==0.0.2.3, + bitvec ==1.1.5.0, + bitwise-enum ==1.0.1.2, + blake2 ==0.3.0, + Blammo ==1.1.2.1, + blank-canvas ==0.7.4, + blanks ==0.5.0, + blas-carray ==0.1.0.2, + blas-comfort-array ==0.0.0.3, + blas-ffi ==0.1, + blas-hs ==0.1.1.0, + blaze-bootstrap ==0.1.0.1, + blaze-builder ==0.4.2.3, + blaze-colonnade ==1.2.2.1, + blaze-html ==0.9.1.2, + blaze-markup ==0.8.3.0, + blaze-svg ==0.3.7, + blaze-textual ==0.2.3.1, + bloodhound ==0.21.0.0, + bm ==0.2.0.0, + bmp ==1.2.6.3, + bnb-staking-csvs ==0.2.1.0, + BNFC ==2.9.5, + BNFC-meta ==0.6.1, + board-games ==0.4, + bodhi ==0.1.0, + boltzmann-samplers ==0.1.1.0, + Boolean ==0.2.4, + boolsimplifier ==0.1.8, + boomerang ==1.4.9, + boots ==0.2.0.1, + bordacount ==0.1.0.0, + boring ==0.2.1, + bound ==2.0.7, + BoundedChan ==1.0.3.0, + bounded-queue ==1.0.0, + boundingboxes ==0.2.3, + box ==0.9.2.1, + boxes ==0.1.5, + breakpoint ==0.1.2.2, + brick ==1.9, + broadcast-chan ==0.2.1.2, + brotli ==0.0.0.1, + brotli-streams ==0.0.0.0, + bsb-http-chunked ==0.0.0.4, + bson ==0.4.0.1, + bson-lens ==0.1.1, + buffer-builder ==0.2.4.8, + buffer-pipe ==0.0, + bugsnag ==1.0.0.1, + bugsnag-haskell ==0.0.4.4, + bugsnag-hs ==0.2.0.12, + bugsnag-wai ==1.0.0.1, + bugsnag-yesod ==1.0.1.0, + bugzilla-redhat ==1.0.1.1, + burrito ==2.0.1.7, + bv ==0.5, + byteable ==0.1.1, + bytebuild ==0.3.14.0, + byte-count-reader ==0.10.1.10, + bytedump ==1.0, + bytehash ==0.1.0.0, + byte-order ==0.1.3.0, + byteorder ==1.0.4, + bytes ==0.17.3, + byteset ==0.1.1.1, + byteslice ==0.2.12.0, + bytesmith ==0.3.10.0, + bytestring installed, + bytestring-builder ==0.10.8.2.0, + bytestring-lexing ==0.5.0.11, + bytestring-mmap ==0.2.2, + bytestring-strict-builder ==0.4.5.7, + bytestring-to-vector ==0.3.0.1, + bytestring-tree-builder ==0.2.7.11, + bytestring-trie ==0.2.7.2, + bz2 ==1.0.1.0, + bzlib-conduit ==0.3.0.2, + c14n ==0.1.0.3, + c2hs ==0.28.8, + Cabal installed, + cabal2nix ==2.19.1, + cabal2spec ==2.7.0, + cabal-appimage ==0.4.0.2, + cabal-clean ==0.2.20230609, + cabal-doctest ==1.0.9, + cabal-file ==0.1.1, + cabal-install ==3.8.1.0, + cabal-install-solver ==3.8.1.0, + cabal-rpm ==2.1.5, + Cabal-syntax installed, + cache ==0.1.3.0, + cached-json-file ==0.1.1, + cacophony ==0.10.1, + cairo ==0.13.10.0, + calendar-recycling ==0.0.0.1, + call-alloy ==0.4.0.3, + calligraphy ==0.1.6, + call-plantuml ==0.0.1.3, + call-stack ==0.4.0, + can-i-haz ==0.3.1.1, + capability ==0.5.0.1, + ca-province-codes ==1.0.0.0, + cardano-coin-selection ==1.0.1, + carray ==0.1.6.8, + casa-client ==0.0.2, + casa-types ==0.0.2, + cased ==0.1.0.0, + case-insensitive ==1.2.1.0, + cases ==0.1.4.2, + casing ==0.1.4.1, + cassava ==0.5.3.0, + cassava-conduit ==0.6.5, + cassava-megaparsec ==2.0.4, + cast ==0.1.0.2, + cborg ==0.2.10.0, + cborg-json ==0.2.6.0, + cdar-mBound ==0.1.0.4, + c-enum ==0.1.1.3, + cereal ==0.5.8.3, + cereal-conduit ==0.8.0, + cereal-text ==0.1.0.2, + cereal-unordered-containers ==0.1.0.1, + cereal-vector ==0.2.0.1, + cfenv ==0.1.0.0, + cgi ==3001.5.0.1, + chan ==0.0.4.1, + character-cases ==0.1.0.6, + charset ==0.3.10, + charsetdetect-ae ==1.1.0.4, + Chart ==1.9.5, + Chart-diagrams ==1.9.5.1, + ChasingBottoms ==1.3.1.12, + check-email ==1.0.2, + checkers ==0.6.0, + checksum ==0.0.0.1, + chimera ==0.3.4.0, + choice ==0.2.3, + chronologique ==0.3.1.3, + chronos ==1.1.5.1, + chronos-bench ==0.2.0.2, + chunked-data ==0.3.1, + cipher-aes ==0.2.11, + cipher-camellia ==0.0.2, + cipher-rc4 ==0.1.4, + circle-packing ==0.1.0.6, + circular ==0.4.0.3, + citeproc ==0.8.1, + classy-prelude ==1.5.0.3, + classy-prelude-conduit ==1.5.0, + classy-prelude-yesod ==1.5.0, + cleff ==0.3.3.0, + clientsession ==0.9.2.0, + Clipboard ==2.3.2.0, + clock ==0.8.4, + closed ==0.2.0.2, + clumpiness ==0.17.0.2, + ClustalParser ==1.3.0, + cmark-gfm ==0.2.6, + cmdargs ==0.10.22, + codec-beam ==0.2.0, + code-conjure ==0.5.6, + code-page ==0.2.1, + coinor-clp ==0.0.0.1, + cointracking-imports ==0.1.0.2, + collect-errors ==0.1.5.0, + co-log-concurrent ==0.5.1.0, + co-log-core ==0.3.2.1, + colonnade ==1.2.0.2, + Color ==0.3.3, + colorful-monoids ==0.2.1.3, + colorize-haskell ==1.0.1, + colour ==2.3.6, + colourista ==0.1.0.2, + columnar ==1.0.0.0, + combinatorial ==0.1.1, + comfort-array ==0.5.3, + comfort-array-shape ==0.0, + comfort-blas ==0.0.1, + comfort-fftw ==0.0.0.1, + comfort-glpk ==0.1, + comfort-graph ==0.0.4, + commonmark ==0.2.4.1, + commonmark-extensions ==0.2.5.1, + commonmark-pandoc ==0.2.2, + commutative ==0.0.2, + commutative-semigroups ==0.1.0.1, + comonad ==5.0.8, + comonad-extras ==4.0.1, + compactmap ==0.1.4.3, + compdata ==0.13.1, + compensated ==0.8.3, + compiler-warnings ==0.1.0, + componentm ==0.0.0.2, + componentm-devel ==0.0.0.2, + composable-associations ==0.1.0.0, + composition ==1.0.2.2, + composition-extra ==2.0.0, + composition-prelude ==3.0.0.2, + concise ==0.1.0.1, + concurrency ==1.11.0.3, + concurrent-extra ==0.7.0.12, + concurrent-output ==1.10.20, + concurrent-split ==0.0.1.1, + cond ==0.4.1.1, + conduino ==0.2.4.0, + conduit ==1.3.5, + conduit-aeson ==0.1.0.1, + conduit-algorithms ==0.0.13.0, + conduit-combinators ==1.3.0, + conduit-concurrent-map ==0.1.3, + conduit-extra ==1.3.6, + conduit-parse ==0.2.1.1, + conduit-zstd ==0.0.2.0, + conferer ==1.1.0.0, + conferer-aeson ==1.1.0.2, + conferer-warp ==1.1.0.1, + ConfigFile ==1.1.4, + config-ini ==0.2.7.0, + configuration-tools ==0.6.1, + configurator ==0.3.0.0, + configurator-export ==0.1.0.1, + connection ==0.3.1, + console-style ==0.0.2.1, + constraints ==0.13.4, + constraints-extras ==0.4.0.0, + constraint-tuples ==0.1.2, + containers installed, + context ==0.2.0.3, + context-http-client ==0.2.0.2, + context-resource ==0.2.0.2, + context-wai-middleware ==0.2.0.2, + contiguous ==0.6.3.0, + contravariant ==1.5.5, + contravariant-extras ==0.3.5.4, + control-bool ==0.2.1, + control-dsl ==0.2.1.3, + control-monad-free ==0.6.2, + control-monad-omega ==0.3.2, + convertible ==1.1.1.1, + cookie ==0.4.6, + copr-api ==0.1.0, + core-data ==0.3.9.1, + core-program ==0.6.9.4, + core-telemetry ==0.2.9.4, + core-text ==0.3.8.1, + countable ==1.2, + country ==0.2.3.1, + covariance ==0.2.0.1, + cpphs ==1.20.9.1, + cprng-aes ==0.6.1, + cpu ==0.1.2, + cpuinfo ==0.1.0.2, + cql ==4.0.4, + cql-io ==1.1.1, + crackNum ==3.4, + crc32c ==0.1.0, + credential-store ==0.1.2, + criterion ==1.6.1.0, + criterion-measurement ==0.2.1.0, + cron ==0.7.0, + crypto-api ==0.13.3, + crypto-api-tests ==0.3, + crypto-cipher-tests ==0.0.11, + crypto-cipher-types ==0.0.9, + cryptocompare ==0.1.2, + crypto-enigma ==0.1.1.6, + cryptohash ==0.11.9, + cryptohash-cryptoapi ==0.1.4, + cryptohash-md5 ==0.11.101.0, + cryptohash-sha1 ==0.11.101.0, + cryptohash-sha256 ==0.11.102.1, + cryptohash-sha512 ==0.11.102.0, + crypton ==0.32, + crypton-conduit ==0.2.3, + cryptonite ==0.30, + cryptonite-conduit ==0.2.2, + cryptonite-openssl ==0.7, + crypto-pubkey-types ==0.4.3, + crypto-random ==0.0.9, + crypto-random-api ==0.2.0, + cryptostore ==0.3.0.1, + crypt-sha512 ==0, + csp ==1.4.0, + css-syntax ==0.1.0.1, + css-text ==0.1.3.0, + c-struct ==0.1.3.0, + csv ==0.1.2, + csv-conduit ==0.7.3.0, + ctrie ==0.2, + cubicbezier ==0.6.0.7, + cubicspline ==0.1.2, + cue-sheet ==2.0.2, + curl ==1.3.8, + curl-runnings ==0.17.0, + currency ==0.2.0.0, + currycarbon ==0.2.1.2, + cursor ==0.3.2.0, + cursor-brick ==0.1.0.1, + cursor-fuzzy-time ==0.0.0.0, + cursor-gen ==0.4.0.0, + cutter ==0.0, + cyclotomic ==1.1.2, + d10 ==1.0.1.3, + data-accessor ==0.2.3.1, + data-accessor-mtl ==0.2.0.5, + data-accessor-transformers ==0.2.1.8, + data-array-byte ==0.1.0.1, + data-binary-ieee754 ==0.4.4, + data-bword ==0.1.0.2, + data-checked ==0.3, + data-clist ==0.2, + data-compat ==0.1.0.4, + data-default ==0.7.1.1, + data-default-class ==0.1.2.0, + data-default-instances-base ==0.1.0.1, + data-default-instances-bytestring ==0.0.1, + data-default-instances-case-insensitive ==0.0.1, + data-default-instances-containers ==0.0.1, + data-default-instances-dlist ==0.0.1, + data-default-instances-old-locale ==0.0.1, + data-default-instances-unordered-containers ==0.0.1, + data-default-instances-vector ==0.0.1, + data-diverse ==4.7.1.0, + datadog ==0.3.0.0, + data-dword ==0.3.2.1, + data-endian ==0.1.1, + data-fix ==0.3.2, + data-forest ==0.1.0.12, + data-has ==0.4.0.0, + data-hash ==0.2.0.1, + data-interval ==2.1.1, + data-inttrie ==0.1.4, + data-lens-light ==0.1.2.4, + data-memocombinators ==0.5.1, + data-msgpack ==0.0.13, + data-msgpack-types ==0.0.3, + data-or ==1.0.0.7, + data-ordlist ==0.4.7.0, + data-ref ==0.1, + data-reify ==0.6.3, + data-serializer ==0.3.5, + data-sketches ==0.3.1.0, + data-sketches-core ==0.1.0.0, + data-textual ==0.3.0.3, + dataurl ==0.1.0.0, + DAV ==1.3.4, + dbcleaner ==0.1.3, + DBFunctor ==0.1.2.1, + dbus ==1.2.29, + dbus-hslogger ==0.1.0.1, + debian ==4.0.5, + debian-build ==0.10.2.1, + debug-trace-var ==0.2.0, + dec ==0.0.5, + Decimal ==0.5.2, + declarative ==0.5.4, + deepseq installed, + deepseq-generics ==0.2.0.0, + deferred-folds ==0.9.18.6, + dejafu ==2.4.0.5, + dense-linear-algebra ==0.1.0.0, + dependent-map ==0.4.0.0, + dependent-sum ==0.7.2.0, + depq ==0.4.2, + deque ==0.4.4.1, + deriveJsonNoPrefix ==0.1.0.1, + derive-storable ==0.3.1.0, + derive-topdown ==0.0.3.0, + deriving-aeson ==0.2.9, + deriving-compat ==0.6.5, + deriving-trans ==0.5.2.0, + detour-via-sci ==1.0.0, + df1 ==0.4.2, + dhall ==1.41.2, + dhall-bash ==1.0.40, + dhall-json ==1.7.11, + dhall-yaml ==1.2.12, + di ==1.3, + diagrams ==1.4.1, + diagrams-cairo ==1.4.2.1, + diagrams-canvas ==1.4.1.2, + diagrams-contrib ==1.4.5.1, + diagrams-core ==1.5.1.1, + diagrams-html5 ==1.4.2, + diagrams-lib ==1.4.6, + diagrams-postscript ==1.5.1.1, + diagrams-rasterific ==1.4.2.3, + diagrams-solve ==0.1.3, + diagrams-svg ==1.4.3.1, + dice ==0.1.1, + di-core ==1.0.4, + dictionary-sharing ==0.1.0.0, + di-df1 ==1.2.1, + Diff ==0.4.1, + diff-loc ==0.1.0.0, + digest ==0.0.2.0, + digits ==0.3.1, + di-handle ==1.0.1, + dimensional ==1.5, + di-monad ==1.3.5, + directory installed, + directory-tree ==0.12.1, + direct-sqlite ==2.3.28, + dirichlet ==0.1.0.7, + discount ==0.1.1, + discover-instances ==0.1.0.0, + discrimination ==0.5, + disk-free-space ==0.1.0.1, + distributed-static ==0.3.9, + distribution-nixpkgs ==1.7.0.1, + distribution-opensuse ==1.1.4, + distributive ==0.6.2.1, + diversity ==0.8.1.0, + djinn-lib ==0.0.1.4, + dl-fedora ==0.9.6, + dlist ==1.0, + dlist-instances ==0.1.1.1, + dlist-nonempty ==0.1.3, + dns ==4.1.1, + dockerfile ==0.2.0, + doclayout ==0.4.0.1, + doctemplates ==0.11, + doctest ==0.20.1, + doctest-discover ==0.2.0.0, + doctest-driver-gen ==0.3.0.8, + doctest-exitcode-stdio ==0.0, + doctest-extract ==0.1.1.1, + doctest-lib ==0.1, + doctest-parallel ==0.3.1, + doldol ==0.4.1.2, + do-list ==1.0.1, + domain ==0.1.1.5, + domain-aeson ==0.1.1.2, + domain-cereal ==0.1.0.1, + domain-core ==0.1.0.4, + domain-optics ==0.1.0.4, + do-notation ==0.1.0.2, + dot ==0.3, + dotenv ==0.11.0.2, + dotgen ==0.4.3, + dotnet-timespan ==0.0.1.0, + double-conversion ==2.0.4.2, + download ==0.3.2.7, + download-curl ==0.1.4, + DPutils ==0.1.1.0, + drifter ==0.3.0, + drifter-postgresql ==0.2.1, + drifter-sqlite ==0.1.0.0, + dsp ==0.2.5.2, + dual ==0.1.1.1, + dual-tree ==0.2.3.1, + dublincore-xml-conduit ==0.1.0.3, + dunai ==0.11.2, + duration ==0.2.0.0, + dvorak ==0.1.0.0, + dynamic-state ==0.3.1, + dyre ==0.9.2, + eap ==0.9.0.2, + Earley ==0.13.0.1, + easy-file ==0.2.5, + easy-logger ==0.1.0.7, + Ebnf2ps ==1.0.15, + echo ==0.1.4, + ecstasy ==0.2.1.0, + ed25519 ==0.0.5.0, + ede ==0.3.3.0, + edit-distance ==0.2.2.1, + edit-distance-vector ==1.0.0.4, + editor-open ==0.6.0.0, + effectful ==2.2.2.0, + effectful-core ==2.2.2.2, + effectful-plugin ==1.1.0.2, + effectful-th ==1.0.0.1, + either ==5.0.2, + either-both ==0.1.1.1, + either-unwrap ==1.1, + ekg-core ==0.1.1.7, + elerea ==2.9.0, + elf ==0.31, + eliminators ==0.9.2, + elm2nix ==0.3.1, + elm-bridge ==0.8.2, + elm-core-sources ==1.0.0, + elm-export ==0.6.0.1, + elynx ==0.7.2.2, + elynx-markov ==0.7.2.2, + elynx-nexus ==0.7.2.2, + elynx-seq ==0.7.2.2, + elynx-tools ==0.7.2.1, + elynx-tree ==0.7.2.2, + emacs-module ==0.1.1.1, + email-validate ==2.3.2.19, + emojis ==0.1.3, + enclosed-exceptions ==1.0.3, + ENIG ==0.0.1.0, + entropy ==0.4.1.10, + enummapset ==0.7.2.0, + enumset ==0.1, + enum-subset-generate ==0.1.0.1, + enum-text ==0.5.3.0, + envelope ==0.2.2.0, + envparse ==0.5.0, + envy ==2.1.2.0, + eq ==4.3, + equal-files ==0.0.5.4, + equational-reasoning ==0.7.0.1, + equivalence ==0.4.1, + erf ==2.0.0.0, + error ==1.0.0.0, + errorcall-eq-instance ==0.3.0, + error-or ==0.3.0, + error-or-utils ==0.2.0, + errors ==2.3.0, + errors-ext ==0.4.2, + ersatz ==0.4.13, + esqueleto ==3.5.11.0, + event-list ==0.1.2.1, + eventstore ==1.4.2, + every ==0.0.1, + evm-opcodes ==0.1.2, + exact-combinatorics ==0.2.0.11, + exact-pi ==0.5.0.2, + exception-hierarchy ==0.1.0.10, + exception-mtl ==0.4.0.2, + exceptions installed, + exception-transformers ==0.4.0.12, + executable-hash ==0.2.0.4, + executable-path ==0.0.3.1, + exinst ==0.9, + exit-codes ==1.0.0, + exomizer ==1.0.0, + experimenter ==0.1.0.14, + expiring-cache-map ==0.0.6.1, + explainable-predicates ==0.1.2.4, + explicit-exception ==0.2, + exp-pairs ==0.2.1.0, + express ==1.0.12, + extended-reals ==0.2.4.0, + extensible ==0.9, + extensible-effects ==5.0.0.1, + extensible-exceptions ==0.1.1.4, + extra ==1.7.14, + extractable-singleton ==0.0.1, + extrapolate ==0.4.6, + fail ==4.9.0.0, + failable ==1.2.4.0, + FailT ==0.1.2.0, + fakedata ==1.0.3, + fakedata-parser ==0.1.0.0, + fakedata-quickcheck ==0.2.0, + fakefs ==0.3.0.2, + fakepull ==0.3.0.2, + faktory ==1.1.2.4, + fasta ==0.10.4.2, + fast-logger ==3.2.2, + fast-math ==1.0.2, + fastmemo ==0.1.1, + fast-myers-diff ==0.0.0, + fb ==2.1.1.1, + fcf-family ==0.2.0.0, + fdo-notify ==0.3.1, + feature-flags ==0.1.0.1, + fedora-dists ==2.1.1, + fedora-haskell-tools ==1.0, + feed ==1.3.2.1, + FenwickTree ==0.1.2.1, + fft ==0.1.8.7, + fftw-ffi ==0.1, + fgl ==5.8.0.0, + fields-json ==0.4.0.0, + file-embed ==0.0.15.0, + file-embed-lzma ==0.0.1, + filelock ==0.1.1.7, + filemanip ==0.3.6.3, + file-modules ==0.1.2.4, + filepath installed, + filepath-bytestring ==1.4.2.1.13, + file-path-th ==0.1.0.0, + filepattern ==0.1.3, + fileplow ==0.1.0.0, + filter-logger ==0.6.0.0, + filtrable ==0.1.6.0, + fin ==0.3, + FindBin ==0.0.5, + fingertree ==0.1.5.0, + finite-typelits ==0.1.6.0, + first-class-families ==0.8.0.1, + first-class-patterns ==0.3.2.5, + fitspec ==0.4.10, + fixed ==0.3, + fixed-length ==0.2.3.1, + fixed-vector ==1.2.3.0, + fixed-vector-hetero ==0.6.1.1, + fix-whitespace ==0.0.11, + flac ==0.2.1, + flac-picture ==0.1.2, + flags-applicative ==0.1.0.3, + flat ==0.6, + flatparse ==0.4.1.0, + flay ==0.4, + FloatingHex ==0.5, + floatshow ==0.2.4, + flow ==2.0.0.4, + flush-queue ==1.0.0, + fmlist ==0.9.4, + fmt ==0.6.3.0, + fn ==0.3.0.2, + focus ==1.0.3.2, + focuslist ==0.1.1.0, + foldable1-classes-compat ==0.1, + fold-debounce ==0.2.0.11, + foldl ==1.4.15, + folds ==0.7.8, + follow-file ==0.0.3, + FontyFruity ==0.5.3.5, + force-layout ==0.4.0.6, + foreign-store ==0.2, + ForestStructures ==0.0.1.1, + forkable-monad ==0.2.0.3, + formatn ==0.3.0.1, + format-numbers ==0.1.0.1, + formatting ==7.2.0, + foundation ==0.0.30, + fourmolu ==0.11.0.0, + free ==5.1.10, + free-categories ==0.2.0.2, + freenect ==1.2.1, + freetype2 ==0.2.0, + free-vl ==0.1.4, + friday ==0.2.3.2, + friday-juicypixels ==0.1.2.4, + friendly-time ==0.4.1, + frisby ==0.2.5, + from-sum ==0.2.3.0, + frontmatter ==0.1.0.2, + fsnotify ==0.4.1.0, + ftp-client ==0.5.1.4, + funcmp ==1.9, + function-builder ==0.3.0.1, + functor-classes-compat ==2.0.0.2, + functor-combinators ==0.4.1.2, + fused-effects ==1.1.2.2, + fusion-plugin ==0.2.7, + fusion-plugin-types ==0.1.0, + fuzzcheck ==0.1.1, + fuzzy ==0.1.0.1, + fuzzy-dates ==0.1.1.2, + fuzzy-time ==0.2.0.3, + gauge ==0.2.5, + gd ==3000.7.3, + gdp ==0.0.3.0, + gemini-exports ==0.1.0.0, + general-games ==1.1.1, + generically ==0.1.1, + generic-arbitrary ==1.0.1, + generic-constraints ==1.1.1.1, + generic-data ==1.1.0.0, + generic-data-surgery ==0.3.0.0, + generic-deriving ==1.14.5, + generic-functor ==1.1.0.0, + generic-lens ==2.2.2.0, + generic-lens-core ==2.2.1.0, + generic-monoid ==0.1.0.1, + generic-optics ==2.2.1.0, + GenericPretty ==1.2.2, + generic-random ==1.5.0.1, + generics-eot ==0.4.0.1, + generics-sop ==0.5.1.3, + generics-sop-lens ==0.2.0.1, + geniplate-mirror ==0.7.9, + genvalidity ==1.1.0.0, + genvalidity-aeson ==1.0.0.1, + genvalidity-appendful ==0.1.0.0, + genvalidity-bytestring ==1.0.0.1, + genvalidity-case-insensitive ==0.0.0.1, + genvalidity-containers ==1.0.0.1, + genvalidity-criterion ==1.1.0.0, + genvalidity-hspec ==1.0.0.3, + genvalidity-hspec-aeson ==1.0.0.0, + genvalidity-hspec-binary ==1.0.0.0, + genvalidity-hspec-cereal ==1.0.0.0, + genvalidity-hspec-hashable ==1.0.0.1, + genvalidity-hspec-optics ==1.0.0.0, + genvalidity-hspec-persistent ==1.0.0.0, + genvalidity-mergeful ==0.3.0.1, + genvalidity-mergeless ==0.3.0.0, + genvalidity-persistent ==1.0.0.2, + genvalidity-property ==1.0.0.0, + genvalidity-scientific ==1.0.0.0, + genvalidity-sydtest ==1.0.0.0, + genvalidity-sydtest-aeson ==1.0.0.0, + genvalidity-sydtest-hashable ==1.0.0.1, + genvalidity-sydtest-lens ==1.0.0.0, + genvalidity-sydtest-persistent ==1.0.0.0, + genvalidity-text ==1.0.0.1, + genvalidity-time ==1.0.0.1, + genvalidity-typed-uuid ==0.1.0.1, + genvalidity-unordered-containers ==1.0.0.1, + genvalidity-uuid ==1.0.0.1, + genvalidity-vector ==1.0.0.0, + geodetics ==0.1.2, + getopt-generics ==0.13.1.0, + ghc installed, + ghc-bignum installed, + ghc-byteorder ==4.11.0.0.10, + ghc-check ==0.5.0.8, + ghc-compact installed, + ghc-core ==0.5.6, + ghc-events ==0.19.0.1, + ghc-exactprint ==1.6.1.3, + ghcid ==0.8.9, + ghci-hexcalc ==0.1.1.0, + ghcjs-codemirror ==0.0.0.2, + ghcjs-perch ==0.3.3.3, + ghc-lib ==9.4.8.20231111, + ghc-lib-parser ==9.4.8.20231111, + ghc-lib-parser-ex ==9.4.0.0, + ghc-paths ==0.1.0.12, + ghc-prof ==1.4.1.12, + ghc-syntax-highlighter ==0.0.9.0, + ghc-tcplugins-extra ==0.4.5, + ghc-trace-events ==0.1.2.7, + ghc-typelits-extra ==0.4.6, + ghc-typelits-knownnat ==0.7.10, + ghc-typelits-natnormalise ==0.7.9, + ghc-typelits-presburger ==0.7.2.0, + ghost-buster ==0.1.1.0, + gi-atk ==2.0.27, + gi-cairo ==1.0.29, + gi-cairo-connector ==0.1.1, + gi-cairo-render ==0.1.2, + gi-dbusmenu ==0.4.13, + gi-dbusmenugtk3 ==0.4.14, + gi-freetype2 ==2.0.4, + gi-gdk ==3.0.28, + gi-gdkpixbuf ==2.0.31, + gi-gdkx11 ==3.0.15, + gi-gio ==2.0.32, + gi-glib ==2.0.29, + gi-gmodule ==2.0.5, + gi-gobject ==2.0.30, + gi-graphene ==1.0.7, + gi-gtk ==3.0.41, + gi-gtk-hs ==0.3.16, + gi-harfbuzz ==0.0.9, + gi-javascriptcore ==4.0.27, + gio ==0.13.10.0, + gi-pango ==1.0.29, + gi-soup ==2.4.28, + githash ==0.1.7.0, + github ==0.28.0.1, + github-release ==2.0.0.9, + github-rest ==1.1.4, + github-types ==0.2.1, + github-webhooks ==0.17.0, + gitlab-haskell ==1.0.0.3, + gitlib ==3.1.3, + gitrev ==1.3.1, + gi-vte ==2.91.31, + gi-webkit2 ==4.0.30, + gi-xlib ==2.0.13, + gl ==0.9, + glabrous ==2.0.6.2, + glasso ==0.1.0, + GLFW-b ==3.3.0.0, + glib ==0.13.10.0, + Glob ==0.10.2, + glob-posix ==0.2.0.1, + gloss ==1.13.2.2, + gloss-algorithms ==1.13.0.3, + gloss-rendering ==1.13.1.2, + glpk-headers ==0.5.1, + GLURaw ==2.0.0.5, + GLUT ==2.7.0.16, + gmail-simple ==0.1.0.5, + gnuplot ==0.5.7, + goldplate ==0.2.1.1, + google-isbn ==1.0.3, + gopher-proxy ==0.1.1.3, + gpolyline ==0.1.0.1, + graph-core ==0.3.0.0, + graphite ==0.10.0.1, + graphql ==1.2.0.1, + graphql-client ==1.2.2, + graphs ==0.7.2, + graphula ==2.0.2.2, + graphviz ==2999.20.2.0, + graph-wrapper ==0.2.6.0, + gravatar ==0.8.1, + gridtables ==0.1.0.0, + groom ==0.1.2.1, + group-by-date ==0.1.0.5, + groups ==0.5.3, + gtk ==0.15.8, + gtk2hs-buildtools ==0.13.10.0, + gtk3 ==0.15.8, + gtk-sni-tray ==0.1.8.1, + gtk-strut ==0.1.3.2, + guarded-allocation ==0.0.1, + H ==1.0.0, + hackage-cli ==0.1.0.1, + hackage-db ==2.1.3, + hackage-security ==0.6.2.3, + haddock-library ==1.11.0, + haha ==0.3.1.1, + hakyll ==4.16.2.0, + hal ==1.0.1, + half ==0.3.1, + hall-symbols ==0.1.0.6, + hamlet ==1.2.0, + hamtsolo ==1.0.4, + HandsomeSoup ==0.4.2, + handwriting ==0.1.0.3, + happstack-hsp ==7.3.7.7, + happstack-jmacro ==7.0.12.5, + happstack-server ==7.8.0.2, + happstack-server-tls ==7.2.1.3, + happy ==1.20.1.1, + happy-meta ==0.2.1.0, + harp ==0.4.3.6, + HasBigDecimal ==0.2.0.0, + hasbolt ==0.1.7.0, + hashable ==1.4.3.0, + hashing ==0.1.1.0, + hashmap ==1.3.3, + hashtables ==1.3.1, + haskeline installed, + haskell-gi ==0.26.7, + haskell-gi-base ==0.26.4, + haskell-gi-overloading ==1.0, + haskell-lexer ==1.1.1, + HaskellNet ==0.6.1.2, + HaskellNet-SSL ==0.3.4.4, + haskell-src ==1.0.4, + haskell-src-exts ==1.23.1, + haskell-src-exts-simple ==1.23.0.0, + haskell-src-exts-util ==0.2.5, + haskell-src-meta ==0.8.13, + haskoin-core ==0.21.2, + haskoin-node ==0.18.1, + haskoin-store-data ==0.65.5, + hasktags ==0.72.0, + hasql ==1.6.3.4, + hasql-dynamic-statements ==0.3.1.2, + hasql-implicits ==0.1.1, + hasql-interpolate ==0.1.0.4, + hasql-listen-notify ==0.1.0, + hasql-migration ==0.3.0, + hasql-notifications ==0.2.0.6, + hasql-optparse-applicative ==0.7, + hasql-pool ==0.9.0.1, + hasql-queue ==1.2.0.2, + hasql-th ==0.4.0.19, + hasql-transaction ==1.0.1.2, + has-transformers ==0.1.0.4, + hasty-hamiltonian ==1.3.4, + HaTeX ==3.22.4.1, + HaXml ==1.25.13, + haxr ==3000.11.5, + HCodecs ==0.5.2, + hdaemonize ==0.5.7, + HDBC ==2.4.0.4, + HDBC-session ==0.1.2.1, + headed-megaparsec ==0.2.1.3, + heap ==1.0.4, + heaps ==0.4, + heatshrink ==0.1.0.0, + hebrew-time ==0.1.2, + hedgehog ==1.2, + hedgehog-classes ==0.2.5.4, + hedgehog-corpus ==0.2.0, + hedgehog-fakedata ==0.0.1.5, + hedgehog-fn ==1.0, + hedgehog-optics ==1.0.0.3, + hedgehog-quickcheck ==0.1.1, + hedis ==0.15.2, + hedn ==0.3.0.4, + heist ==1.1.1.2, + here ==1.2.14, + heredoc ==0.2.0.0, + heterocephalus ==1.0.5.7, + hetzner ==0.2.1.1, + hex ==0.2.0, + hexml ==0.3.4, + hexml-lens ==0.2.2, + hexpat ==0.20.13, + hex-text ==0.1.0.9, + hformat ==0.3.3.1, + hfsevents ==0.1.6, + hgal ==2.0.0.3, + hidapi ==0.1.8, + hie-bios ==0.12.1, + hi-file-parser ==0.1.6.0, + highlighting-kate ==0.6.4, + hindent ==6.0.0, + hinfo ==0.0.3.0, + hinotify ==0.4.1, + hint ==0.9.0.8, + histogram-fill ==0.9.1.0, + hjsmin ==0.2.1, + hkd-default ==1.1.0.0, + hkgr ==0.4.3.2, + hledger ==1.30.1, + hledger-interest ==1.6.6, + hledger-lib ==1.30, + hledger-stockquotes ==0.1.2.1, + hledger-ui ==1.30, + hledger-web ==1.30, + hlibcpuid ==0.2.0, + hlibgit2 ==0.18.0.16, + hlibsass ==0.1.10.1, + hlint ==3.5, + hmatrix ==0.20.2, + hmatrix-gsl ==0.19.0.1, + hmatrix-gsl-stats ==0.4.1.8, + hmatrix-morpheus ==0.1.1.2, + hmatrix-special ==0.19.0.0, + hmm-lapack ==0.5.0.1, + hmpfr ==0.4.5, + hoauth2 ==2.8.0, + hoogle ==5.0.18.3, + hopenssl ==2.2.5, + hopfli ==0.2.2.1, + horizontal-rule ==0.6.0.0, + hosc ==0.20, + hostname ==1.0, + hostname-validate ==1.0.0, + hourglass ==0.2.12, + hourglass-orphans ==0.1.0.0, + hp2pretty ==0.10, + hpack ==0.35.2, + hpack-dhall ==0.5.7, + hpc installed, + hpc-codecov ==0.3.0.0, + hpc-lcov ==1.1.1, + HPDF ==1.6.2, + hpp ==0.6.5, + hpqtypes ==1.11.1.2, + hpqtypes-extras ==1.16.4.4, + hreader ==1.1.1, + hreader-lens ==0.1.3.0, + hruby ==0.5.1.0, + hsass ==0.8.0, + hs-bibutils ==6.10.0.0, + hsc2hs ==0.68.10, + hscolour ==1.24.4, + hsdns ==1.8, + hse-cpp ==0.2, + hsemail ==2.2.1, + hset ==2.2.0, + hs-GeoIP ==0.3, + hsignal ==0.2.7.5, + hsini ==0.5.2.2, + hsinstall ==2.8, + HSlippyMap ==3.0.1, + hslogger ==1.3.1.0, + hslua ==2.3.0, + hslua-aeson ==2.3.0.1, + hslua-classes ==2.3.0, + hslua-core ==2.3.1, + hslua-list ==1.1.1, + hslua-marshalling ==2.3.0, + hslua-module-doclayout ==1.1.0, + hslua-module-path ==1.1.0, + hslua-module-system ==1.1.0.1, + hslua-module-text ==1.1.0.1, + hslua-module-version ==1.1.0, + hslua-objectorientation ==2.3.0, + hslua-packaging ==2.3.0, + hslua-typing ==0.1.0, + hsndfile ==0.8.0, + hsndfile-vector ==0.5.2, + HsOpenSSL ==0.11.7.6, + HsOpenSSL-x509-system ==0.1.0.4, + hsp ==0.10.0, + hspec ==2.10.10, + hspec-attoparsec ==0.1.0.2, + hspec-checkers ==0.1.0.2, + hspec-contrib ==0.5.2, + hspec-core ==2.10.10, + hspec-discover ==2.10.10, + hspec-expectations ==0.8.2, + hspec-expectations-json ==1.0.2.1, + hspec-expectations-lifted ==0.10.0, + hspec-expectations-pretty-diff ==0.7.2.6, + hspec-golden ==0.2.1.0, + hspec-golden-aeson ==0.9.0.0, + hspec-hedgehog ==0.0.1.2, + hspec-junit-formatter ==1.1.0.2, + hspec-leancheck ==0.0.6, + hspec-megaparsec ==2.2.1, + hspec-meta ==2.10.5, + hspec-parsec ==0, + hspec-smallcheck ==0.5.3, + hspec-tmp-proc ==0.5.1.2, + hspec-wai ==0.11.1, + hspec-wai-json ==0.11.0, + hspec-webdriver ==1.2.2, + hs-php-session ==0.0.9.3, + hstatistics ==0.3.1, + HStringTemplate ==0.8.8, + HSvm ==0.1.1.3.25, + hsx2hs ==0.14.1.11, + hsx-jmacro ==7.3.8.2, + HsYAML ==0.2.1.3, + HsYAML-aeson ==0.2.0.1, + hsyslog ==5.0.2, + htaglib ==1.2.1, + HTF ==0.15.0.1, + html ==1.0.1.2, + html-conduit ==1.3.2.2, + html-email-validate ==0.2.0.0, + html-entities ==1.1.4.6, + html-entity-map ==0.1.0.0, + htoml-megaparsec ==2.1.0.4, + htoml-parse ==0.1.0.1, + HTTP ==4000.4.1, + http2 ==4.1.4, + http-api-data ==0.5, + http-api-data-qq ==0.1.0.0, + http-client ==0.7.15, + http-client-openssl ==0.3.3, + http-client-overrides ==0.1.1.0, + http-client-restricted ==0.0.5, + http-client-tls ==0.3.6.1, + http-common ==0.8.3.4, + http-conduit ==2.3.8.1, + http-date ==0.0.11, + http-directory ==0.1.10, + http-download ==0.2.0.0, + httpd-shed ==0.4.1.1, + http-io-streams ==0.1.6.3, + http-link-header ==1.2.1, + http-media ==0.8.1.1, + http-query ==0.1.3, + http-reverse-proxy ==0.6.0.2, + http-streams ==0.8.9.9, + http-types ==0.12.4, + human-readable-duration ==0.2.1.4, + HUnit ==1.6.2.0, + HUnit-approx ==1.1.1.1, + hunit-dejafu ==2.0.0.6, + hvect ==0.4.0.1, + hvega ==0.12.0.7, + hw-balancedparens ==0.4.1.3, + hw-bits ==0.7.2.2, + hw-conduit ==0.2.1.1, + hw-conduit-merges ==0.2.1.0, + hw-diagnostics ==0.0.1.0, + hweblib ==0.6.3, + hw-eliasfano ==0.1.2.1, + hw-excess ==0.2.3.0, + hw-fingertree ==0.1.2.1, + hw-fingertree-strict ==0.1.2.1, + hw-hedgehog ==0.1.1.1, + hw-hspec-hedgehog ==0.1.1.1, + hw-int ==0.0.2.0, + hw-ip ==2.4.2.1, + hw-json-simd ==0.1.1.2, + hw-json-simple-cursor ==0.1.1.1, + hw-json-standard-cursor ==0.2.3.2, + hwk ==0.6, + hw-kafka-client ==4.0.3, + hw-mquery ==0.2.1.1, + hworker ==0.1.0.1, + hw-packed-vector ==0.2.1.1, + hw-parser ==0.1.1.0, + hw-prim ==0.6.3.2, + hw-rankselect ==0.13.4.1, + hw-rankselect-base ==0.3.4.1, + hw-simd ==0.1.2.2, + hw-string-parse ==0.0.0.5, + hw-succinct ==0.1.0.1, + hxt ==9.3.1.22, + hxt-charproperties ==9.5.0.0, + hxt-css ==0.1.0.3, + hxt-curl ==9.1.1.1, + hxt-expat ==9.1.1, + hxt-http ==9.1.5.2, + hxt-regex-xmlschema ==9.2.0.7, + hxt-tagsoup ==9.1.4, + hxt-unicode ==9.0.2.4, + hybrid-vectors ==0.2.4, + hyper ==0.2.1.1, + hyperloglog ==0.4.6, + hyphenation ==0.8.2, + identicon ==0.2.2, + ieee754 ==0.8.0, + if ==0.1.0.0, + IfElse ==0.85, + iff ==0.0.6.1, + ihs ==0.1.0.3, + imagesize-conduit ==1.1, + Imlib ==0.1.2, + immortal ==0.3, + immortal-queue ==0.1.0.1, + inbox ==0.2.0, + incipit-base ==0.5.1.0, + incipit-core ==0.5.1.0, + include-file ==0.1.0.4, + incremental ==0.3.1, + indents ==0.5.0.1, + indexed ==0.1.3, + indexed-containers ==0.1.0.2, + indexed-list-literals ==0.2.1.3, + indexed-profunctors ==0.1.1.1, + indexed-traversable ==0.1.3, + indexed-traversable-instances ==0.1.1.2, + inf-backprop ==0.1.0.2, + infer-license ==0.2.0, + infinite-list ==0.1, + ini ==0.4.2, + inj ==1.0, + inline-c ==0.9.1.10, + inline-c-cpp ==0.5.0.2, + inline-r ==1.0.1, + input-parsers ==0.3.0.2, + insert-ordered-containers ==0.2.5.3, + inspection-testing ==0.5.0.2, + instance-control ==0.1.2.0, + integer-gmp installed, + integer-logarithms ==1.0.3.1, + integer-roots ==1.0.2.0, + integer-types ==0.1.4.0, + integration ==0.2.1, + intern ==0.9.5, + interpolate ==0.2.1, + interpolatedstring-perl6 ==1.0.2, + interpolation ==0.1.1.2, + Interpolation ==0.3.0, + IntervalMap ==0.6.2.1, + intervals ==0.9.2, + intset-imperative ==0.1.0.0, + invariant ==0.6.2, + invert ==1.0.0.4, + invertible-grammar ==0.1.3.5, + io-machine ==0.2.0.0, + io-manager ==0.1.0.4, + io-memoize ==1.1.1.0, + io-region ==0.1.1, + io-storage ==0.3, + io-streams ==1.5.2.2, + io-streams-haproxy ==1.0.1.0, + ip ==1.7.7, + ip6addr ==1.0.3, + iproute ==1.7.12, + IPv6Addr ==2.0.5.1, + ipynb ==0.2, + ipython-kernel ==0.10.3.0, + irc ==0.6.1.1, + irc-ctcp ==0.1.3.1, + isbn ==1.1.0.4, + islink ==0.1.0.0, + iso3166-country-codes ==0.20140203.8, + iso639 ==0.1.0.3, + iso8601-time ==0.1.5, + isocline ==1.0.9, + isomorphism-class ==0.1.0.12, + iterable ==3.0, + ix-shapable ==0.1.0, + jack ==0.7.2.2, + jailbreak-cabal ==1.4, + jalaali ==1.0.0.0, + java-adt ==0.2018.11.4, + jira-wiki-markup ==1.5.1, + jl ==0.1.0, + jmacro ==0.6.18, + jose ==0.10.0.1, + jose-jwt ==0.9.6, + journalctl-stream ==0.6.0.5, + js-chart ==2.9.4.1, + js-dgtable ==0.5.2, + js-flot ==0.8.3, + js-jquery ==3.3.1, + json ==0.10, + json-feed ==2.0.0.10, + jsonifier ==0.2.1.2, + jsonpath ==0.3.0.0, + json-rpc ==1.0.4, + json-stream ==0.4.5.3, + JuicyPixels ==3.3.8, + JuicyPixels-extra ==0.6.0, + JuicyPixels-scale-dct ==0.1.2, + junit-xml ==0.1.0.3, + justified-containers ==0.3.0.0, + jwt ==0.11.0, + kan-extensions ==5.2.5, + kansas-comet ==0.4.2, + katip ==0.8.8.0, + katip-logstash ==0.1.0.2, + katip-wai ==0.1.2.2, + kazura-queue ==0.1.0.4, + kdt ==0.2.5, + keep-alive ==0.2.1.0, + keter ==2.1.2, + keycode ==0.2.2, + keyed-vals ==0.2.2.0, + keyed-vals-hspec-tests ==0.2.2.0, + keyed-vals-mem ==0.2.2.0, + keyed-vals-redis ==0.2.2.0, + keys ==3.12.3, + ki ==1.0.1.1, + kind-apply ==0.4.0.0, + kind-generics ==0.5.0.0, + kind-generics-th ==0.2.3.3, + ki-unlifted ==1.0.0.2, + kleene ==0.1, + kmeans ==0.1.3, + knob ==0.2.2, + koji ==0.0.2, + krank ==0.3.0, + labels ==0.3.3, + lackey ==2.0.0.7, + LambdaHack ==0.11.0.1, + lame ==0.2.2, + language-avro ==0.1.4.0, + language-bash ==0.9.2, + language-c ==0.9.2, + language-c-quote ==0.13.0.1, + language-docker ==12.1.0, + language-dot ==0.1.2, + language-glsl ==0.3.0, + language-java ==0.2.9, + language-javascript ==0.7.1.0, + language-nix ==2.2.0, + language-protobuf ==1.0.1, + language-python ==0.5.8, + language-thrift ==0.12.0.1, + lapack ==0.5.1, + lapack-carray ==0.0.3, + lapack-comfort-array ==0.0.1, + lapack-ffi ==0.0.3, + lapack-ffi-tools ==0.1.3.1, + lapack-hmatrix ==0.0.0.2, + largeword ==1.2.5, + latex ==0.1.0.4, + lattices ==2.1, + lawful ==0.1.0.0, + lazy-csv ==0.5.1, + lazyio ==0.1.0.4, + lazysmallcheck ==0.6, + lca ==0.4, + leancheck ==1.0.0, + leancheck-instances ==0.0.5, + leapseconds-announced ==2017.1.0.1, + learn-physics ==0.6.5, + leb128-cereal ==1.2, + lens ==5.2.3, + lens-action ==0.2.6, + lens-aeson ==1.2.3, + lens-csv ==0.1.1.0, + lens-family ==2.1.2, + lens-family-core ==2.1.2, + lens-misc ==0.0.2.0, + lens-properties ==4.11.1, + lens-regex ==0.1.3, + lens-regex-pcre ==1.1.0.0, + lentil ==1.5.6.0, + LetsBeRational ==1.0.0.0, + leveldb-haskell ==0.6.5, + lexer-applicative ==2.1.0.2, + libBF ==0.6.7, + libffi ==0.2.1, + libgit ==0.3.1, + liboath-hs ==0.0.1.2, + libyaml ==0.1.2, + lifted-async ==0.10.2.5, + lifted-base ==0.2.3.12, + lift-generics ==0.2.1, + lift-type ==0.1.1.1, + line ==4.0.1, + linear ==1.22, + linear-base ==0.3.1, + linear-circuit ==0.1.0.4, + linear-generics ==0.2.1, + linear-programming ==0.0.0.1, + linebreak ==1.1.0.4, + linux-capabilities ==0.1.1.0, + linux-file-extents ==0.2.0.0, + linux-namespaces ==0.1.3.0, + List ==0.6.2, + ListLike ==4.7.8.2, + list-predicate ==0.1.0.1, + listsafe ==0.1.0.1, + list-t ==1.0.5.7, + list-transformer ==1.0.9, + ListTree ==0.2.3, + ListZipper ==1.2.0.2, + literatex ==0.3.0.0, + lmdb ==0.2.5, + load-env ==0.2.1.0, + loc ==0.1.4.1, + locators ==0.3.0.3, + loch-th ==0.2.2, + lockfree-queue ==0.2.4, + log-base ==0.12.0.1, + log-domain ==0.13.2, + logfloat ==0.14.0, + logger-thread ==0.1.0.2, + logging ==3.0.5, + logging-effect ==1.4.0, + logging-facade ==0.3.1, + logging-facade-syslog ==1, + logict ==0.8.0.0, + logstash ==0.1.0.4, + loop ==0.3.0, + lpeg ==1.0.4, + lrucache ==1.2.0.1, + lsp ==2.0.0.0, + lsp-test ==0.15.0.0, + lsp-types ==2.0.2.0, + lua ==2.3.1, + lua-arbitrary ==1.0.1.1, + lucid ==2.11.20230408, + lucid2 ==0.0.20230706, + lucid-cdn ==0.2.2.0, + lucid-extras ==0.2.2, + lukko ==0.1.1.3, + lz4 ==0.2.3.1, + lz4-frame-conduit ==0.1.0.1, + lzma ==0.0.1.0, + lzma-clib ==5.2.2, + lzma-conduit ==1.2.3, + machines ==0.7.3, + magic ==1.1, + magico ==0.0.2.3, + mail-pool ==2.2.3, + mainland-pretty ==0.7.1, + main-tester ==0.2.0.1, + managed ==1.0.10, + mandrill ==0.5.7.0, + map-syntax ==0.3, + markdown ==0.1.17.5, + markdown-unlit ==0.5.1, + markov-chain ==0.0.3.4, + markov-chain-usage-model ==0.0.0, + mason ==0.2.6, + massiv ==1.0.4.0, + massiv-io ==1.0.0.1, + massiv-serialise ==1.0.0.2, + massiv-test ==1.0.0.0, + matchable ==0.1.2.1, + mathexpr ==0.3.1.0, + math-extras ==0.1.1.0, + math-functions ==0.3.4.3, + mathlist ==0.2.0.0, + matplotlib ==0.7.7, + matrices ==0.5.0, + matrix ==0.3.6.3, + matrix-as-xyz ==0.1.2.2, + matrix-market-attoparsec ==0.1.1.3, + matrix-static ==0.3, + maximal-cliques ==0.1.1, + mbox-utility ==0.0.3.1, + mcmc ==0.8.2.0, + mcmc-types ==1.0.3, + median-stream ==0.7.0.0, + med-module ==0.1.3, + megaparsec ==9.3.1, + megaparsec-tests ==9.3.1, + mega-sdist ==0.4.3.0, + membership ==0.0.1, + memcache ==0.3.0.1, + memfd ==1.0.1.3, + memory ==0.18.0, + MemoTrie ==0.6.11, + mergeful ==0.3.0.0, + mergeless ==0.4.0.0, + merkle-tree ==0.1.1, + mersenne-random ==1.0.0.1, + mersenne-random-pure64 ==0.2.2.0, + messagepack ==0.5.5, + metrics ==0.4.1.1, + mfsolve ==0.3.2.2, + microaeson ==0.1.0.1, + microlens ==0.4.13.1, + microlens-aeson ==2.5.1, + microlens-contra ==0.1.0.3, + microlens-ghc ==0.4.14.2, + microlens-mtl ==0.2.0.3, + microlens-platform ==0.4.3.4, + microlens-th ==0.4.3.14, + microspec ==0.2.1.3, + microstache ==1.0.2.3, + midair ==0.2.0.1, + midi ==0.2.2.4, + midi-alsa ==0.2.1, + midi-music-box ==0.0.1.2, + mighty-metropolis ==2.0.0, + mime-mail ==0.5.1, + mime-mail-ses ==0.4.3, + mime-types ==0.1.2.0, + minimal-configuration ==0.1.4, + minimorph ==0.3.0.1, + minio-hs ==1.7.0, + minisat-solver ==0.1, + miniutter ==0.5.1.2, + min-max-pqueue ==0.1.0.2, + mintty ==0.1.4, + misfortune ==0.1.2.1, + missing-foreign ==0.1.1, + MissingH ==1.6.0.1, + mixed-types-num ==0.5.12, + mmap ==0.5.9, + mmark ==0.0.7.6, + mmark-cli ==0.0.5.1, + mmark-ext ==0.2.1.5, + mmorph ==1.2.0, + mnist-idx ==0.1.3.2, + mnist-idx-conduit ==0.4.0.0, + mockery ==0.3.5, + mock-time ==0.1.0, + mod ==0.2.0.1, + model ==0.5, + modern-uri ==0.3.6.1, + modular ==0.1.0.8, + monad-chronicle ==1.0.1, + monad-control ==1.0.3.1, + monad-control-identity ==0.2.0.0, + monad-coroutine ==0.9.2, + monad-extras ==0.6.0, + monadic-arrays ==0.2.2, + monad-journal ==0.8.1, + monadlist ==0.0.2, + monadloc ==0.7.1, + monad-logger ==0.3.40, + monad-logger-aeson ==0.4.1.2, + monad-logger-json ==0.1.0.0, + monad-logger-logstash ==0.2.0.2, + monad-loops ==0.4.3, + monad-memo ==0.5.4, + monadoid ==0.0.3, + monadology ==0.1, + monad-par ==0.3.6, + monad-parallel ==0.8, + monad-par-extras ==0.3.3, + monad-peel ==0.2.1.2, + monad-primitive ==0.1, + monad-products ==4.0.1, + MonadPrompt ==1.0.0.5, + MonadRandom ==0.6, + monad-resumption ==0.1.4.0, + monad-st ==0.2.4.1, + monads-tf ==0.1.0.3, + monad-time ==0.4.0.0, + mongoDB ==2.7.1.2, + monoidal-containers ==0.6.4.0, + monoid-extras ==0.6.2, + monoid-subclasses ==1.2.4.1, + monoid-transformer ==0.0.4, + mono-traversable ==1.0.15.3, + mono-traversable-instances ==0.1.1.0, + mono-traversable-keys ==0.3.0, + more-containers ==0.2.2.2, + morpheus-graphql ==0.27.3, + morpheus-graphql-app ==0.27.3, + morpheus-graphql-client ==0.27.3, + morpheus-graphql-code-gen ==0.27.3, + morpheus-graphql-code-gen-utils ==0.27.3, + morpheus-graphql-core ==0.27.3, + morpheus-graphql-server ==0.27.3, + morpheus-graphql-subscriptions ==0.27.3, + morpheus-graphql-tests ==0.27.3, + moss ==0.2.0.1, + mountpoints ==1.0.2, + mpi-hs ==0.7.2.0, + mpi-hs-binary ==0.1.1.0, + mpi-hs-cereal ==0.1.0.0, + mstate ==0.2.8, + mtl installed, + mtl-compat ==0.2.2, + mtl-prelude ==2.0.3.2, + multiarg ==0.30.0.10, + multi-containers ==0.2, + multimap ==1.2.1, + multipart ==0.2.1, + MultipletCombiner ==0.0.7, + multiset ==0.3.4.3, + murmur3 ==1.0.5, + murmur-hash ==0.1.0.10, + MusicBrainz ==0.4.1, + mustache ==2.4.2, + mutable-containers ==0.3.4.1, + mwc-probability ==2.3.1, + mwc-random ==0.15.0.2, + mwc-random-monad ==0.7.3.1, + mx-state-codes ==1.0.0.0, + mysql ==0.2.1, + mysql-simple ==0.4.9, + n2o ==0.11.1, + n2o-nitro ==0.11.2, + nagios-check ==0.3.2, + named ==0.3.0.1, + names-th ==0.3.0.1, + nano-erl ==0.1.0.1, + nanospec ==0.2.2, + nanovg ==0.8.1.0, + nats ==1.1.2, + natural-arithmetic ==0.1.4.0, + natural-induction ==0.2.0.0, + natural-sort ==0.1.2, + natural-transformation ==0.4, + ndjson-conduit ==0.1.0.5, + neat-interpolation ==0.5.1.4, + netcode-io ==0.0.3, + netlib-carray ==0.1, + netlib-comfort-array ==0.0.0.2, + netlib-ffi ==0.1.1, + net-mqtt ==0.8.3.0, + net-mqtt-lens ==0.1.1.0, + netpbm ==1.0.4, + netrc ==0.2.0.0, + nettle ==0.3.0, + netwire ==5.0.3, + netwire-input ==0.0.7, + netwire-input-glfw ==0.0.11, + network ==3.1.4.0, + network-bsd ==2.8.1.0, + network-byte-order ==0.1.7, + network-conduit-tls ==1.3.2, + network-info ==0.2.1, + network-ip ==0.3.0.3, + network-messagepack-rpc ==0.1.2.0, + network-messagepack-rpc-websocket ==0.1.1.1, + network-multicast ==0.3.2, + Network-NineP ==0.4.7.3, + network-run ==0.2.6, + network-simple ==0.4.5, + network-simple-tls ==0.4.1, + network-transport ==0.5.6, + network-uri ==2.6.4.2, + network-wait ==0.2.0.0, + newtype ==0.2.2.0, + newtype-generics ==0.6.2, + nfc ==0.1.1, + nicify-lib ==1.0.1, + NineP ==0.0.2.1, + nix-derivation ==1.1.3, + nix-paths ==1.0.1, + NoHoed ==0.1.1, + nonce ==1.0.7, + nondeterminism ==1.5, + non-empty ==0.3.5, + nonempty-containers ==0.3.4.5, + nonemptymap ==0.0.6.0, + non-empty-sequence ==0.2.0.4, + nonempty-vector ==0.2.3, + nonempty-zipper ==1.0.0.4, + non-negative ==0.1.2, + normaldistribution ==1.1.0.3, + not-gloss ==0.7.7.0, + nothunks ==0.1.5, + no-value ==1.0.0.0, + nowdoc ==0.1.1.0, + nqe ==0.6.5, + nsis ==0.3.3, + numbers ==3000.2.0.2, + numeric-extras ==0.1, + numeric-limits ==0.1.0.0, + numeric-prelude ==0.4.4, + numeric-quest ==0.2.0.2, + numhask ==0.10.1.1, + numhask-array ==0.10.2, + NumInstances ==1.4, + numtype-dk ==0.5.0.3, + nuxeo ==0.3.2, + nvim-hs ==2.3.2.3, + nvim-hs-contrib ==2.0.0.2, + nvim-hs-ghcid ==2.0.1.0, + oauthenticated ==0.3.0.0, + ObjectName ==1.1.0.2, + oblivious-transfer ==0.1.0, + o-clock ==1.3.0, + ofx ==0.4.4.0, + oidc-client ==0.7.0.1, + old-locale ==1.0.0.7, + old-time ==1.1.0.4, + once ==0.4, + one-liner ==2.1, + one-liner-instances ==0.1.3.0, + OneTuple ==0.4.1.1, + Only ==0.1, + oo-prototypes ==0.1.0.0, + oops ==0.2.0.1, + opaleye ==0.9.7.0, + OpenAL ==1.7.0.5, + openapi3 ==3.2.4, + open-browser ==0.2.1.0, + openexr-write ==0.1.0.2, + OpenGL ==3.0.3.0, + OpenGLRaw ==3.3.4.1, + openpgp-asciiarmor ==0.1.2, + opensource ==0.1.1.0, + openssl-streams ==1.2.3.0, + opentelemetry ==0.8.0, + opentelemetry-extra ==0.8.0, + opentelemetry-lightstep ==0.8.0, + opentelemetry-wai ==0.8.0, + open-witness ==0.6, + operational ==0.2.4.2, + operational-class ==0.3.0.0, + opml-conduit ==0.9.0.0, + optics ==0.4.2.1, + optics-core ==0.4.1.1, + optics-extra ==0.4.2.1, + optics-operators ==0.1.0.1, + optics-th ==0.4.1, + optics-vl ==0.2.1, + optima ==0.4.0.5, + optional-args ==1.0.2, + options ==1.2.1.1, + optparse-applicative ==0.17.1.0, + optparse-enum ==1.0.0.0, + optparse-generic ==1.4.9, + optparse-simple ==0.1.1.4, + optparse-text ==0.1.1.0, + OrderedBits ==0.0.2.0, + ordered-containers ==0.2.3, + ormolu ==0.5.3.0, + overhang ==1.0.0, + packcheck ==0.6.0, + pager ==0.1.1.0, + pagination ==0.2.2, + pagure ==0.1.1, + pagure-cli ==0.2.1, + palette ==0.3.0.3, + pandoc ==3.0.1, + pandoc-dhall-decoder ==0.1.0.1, + pandoc-lua-marshal ==0.2.2, + pandoc-plot ==1.7.0, + pandoc-symreg ==0.2.0.0, + pandoc-throw ==0.1.0.0, + pandoc-types ==1.23.1, + pango ==0.13.10.0, + pantry ==0.8.3, + parallel ==3.2.2.0, + parallel-io ==0.3.5, + parameterized ==0.5.0.0, + parseargs ==0.2.0.9, + parsec installed, + parsec-class ==1.0.0.0, + parsec-numbers ==0.1.0, + parsec-numeric ==0.1.0.0, + ParsecTools ==0.0.2.0, + parser-combinators ==1.3.0, + parser-combinators-tests ==1.3.0, + parsers ==0.12.11, + partial-handler ==1.0.3, + partial-isomorphisms ==0.2.3.0, + partial-order ==0.2.0.0, + partial-semigroup ==0.6.0.2, + password ==3.0.2.1, + password-instances ==3.0.0.0, + password-types ==1.0.0.0, + path ==0.9.5, + path-binary-instance ==0.1.0.1, + path-dhall-instance ==0.2.1.0, + path-extensions ==0.1.1.0, + path-extra ==0.2.0, + path-io ==1.8.1, + path-like ==0.2.0.2, + path-pieces ==0.2.1, + path-text-utf8 ==0.0.1.12, + pathtype ==0.8.1.2, + path-utils ==0.1.1.0, + pathwalk ==0.3.1.2, + patrol ==1.0.0.6, + pattern-arrows ==0.0.2, + pava ==0.1.1.4, + pcf-font ==0.2.2.1, + pcg-random ==0.1.4.0, + pcre2 ==2.2.1, + pcre-heavy ==1.0.0.3, + pcre-light ==0.4.1.2, + pcre-utils ==0.1.9, + pdc ==0.1.1, + pdf-toolbox-content ==0.1.1, + pdf-toolbox-core ==0.1.1, + pdf-toolbox-document ==0.1.2, + peano ==0.1.0.2, + pedersen-commitment ==0.2.0, + pem ==0.2.4, + percent-format ==0.0.4, + perfect-hash-generator ==1.0.0, + persistent ==2.14.6.0, + persistent-discover ==0.1.0.7, + persistent-documentation ==0.1.0.4, + persistent-iproute ==0.2.5, + persistent-lens ==1.0.0, + persistent-mongoDB ==2.13.0.1, + persistent-mtl ==0.5.0.1, + persistent-mysql ==2.13.1.5, + persistent-pagination ==0.1.1.2, + persistent-postgresql ==2.13.6.1, + persistent-qq ==2.12.0.6, + persistent-redis ==2.13.0.1, + persistent-refs ==0.4, + persistent-sqlite ==2.13.3.0, + persistent-template ==2.12.0.0, + persistent-test ==2.13.1.3, + persistent-typed-db ==0.1.0.7, + pg-harness-client ==0.6.0, + pgp-wordlist ==0.1.0.3, + pg-transact ==0.3.2.0, + phantom-state ==0.2.1.4, + phatsort ==0.6.0.0, + picosat ==0.1.6, + pid1 ==0.1.3.1, + pinch ==0.4.3.0, + pipes ==4.3.16, + pipes-attoparsec ==0.6.0, + pipes-bytestring ==2.1.7, + pipes-concurrency ==2.0.14, + pipes-csv ==1.4.3, + pipes-extras ==1.0.15, + pipes-fastx ==0.3.0.0, + pipes-fluid ==0.6.0.1, + pipes-group ==1.0.12, + pipes-http ==1.0.6, + pipes-mongodb ==0.1.0.0, + pipes-ordered-zip ==1.2.1, + pipes-parse ==3.0.9, + pipes-random ==1.0.0.5, + pipes-safe ==2.3.5, + pipes-text ==1.0.1, + pipes-wai ==3.2.0, + pkgtreediff ==0.6.0, + place-cursor-at ==1.0.1, + placeholders ==0.1, + plaid ==0.1.0.4, + plot ==0.2.3.11, + plotlyhs ==0.2.3, + Plural ==0.0.2, + pointed ==5.0.4, + pointedlist ==0.6.1, + pointless-fun ==1.1.0.8, + poll ==0.0.0.2, + poly-arity ==0.1.0, + polynomials-bernstein ==1.1.2, + polyparse ==1.13, + polysemy ==1.9.1.3, + polysemy-fs ==0.1.0.0, + polysemy-plugin ==0.4.5.1, + polysemy-webserver ==0.2.1.2, + pontarius-xmpp ==0.5.6.6, + pooled-io ==0.0.2.3, + portable-lines ==0.1, + port-utils ==0.2.1.0, + posix-paths ==0.3.0.0, + posix-pty ==0.2.2, + possibly ==1.0.0.0, + postgres-options ==0.2.1.0, + postgresql-binary ==0.13.1.2, + postgresql-libpq ==0.9.5.0, + postgresql-libpq-notify ==0.2.0.0, + postgresql-migration ==0.2.1.7, + postgresql-schema ==0.1.14, + postgresql-simple ==0.6.5.1, + postgresql-simple-url ==0.2.1.0, + postgresql-syntax ==0.4.1.1, + postgresql-typed ==0.6.2.2, + post-mess-age ==0.2.1.0, + pptable ==0.3.0.0, + pqueue ==1.4.3.0, + prairie ==0.0.2.0, + prefix-units ==0.3.0.1, + prelude-compat ==0.0.0.2, + prelude-safeenum ==0.1.1.3, + pretty installed, + pretty-class ==1.0.1.1, + prettyclass ==1.0.0.0, + pretty-hex ==1.1, + prettyprinter ==1.7.1, + prettyprinter-ansi-terminal ==1.1.3, + prettyprinter-combinators ==0.1.2, + prettyprinter-compat-annotated-wl-pprint ==1.1, + prettyprinter-compat-ansi-wl-pprint ==1.0.2, + prettyprinter-compat-wl-pprint ==1.0.1, + prettyprinter-convert-ansi-wl-pprint ==1.1.2, + pretty-relative-time ==0.3.0.0, + pretty-show ==1.10, + pretty-simple ==4.1.2.0, + pretty-sop ==0.2.0.3, + pretty-terminal ==0.1.0.0, + pretty-types ==0.4.0.0, + primes ==0.2.1.0, + primitive ==0.8.0.0, + primitive-addr ==0.1.0.2, + primitive-extras ==0.10.1.10, + primitive-offset ==0.2.0.0, + primitive-unaligned ==0.1.1.2, + primitive-unlifted ==0.1.3.1, + prim-uniq ==0.2, + print-console-colors ==0.1.0.0, + probability ==0.2.8, + process installed, + process-extras ==0.7.4, + product-profunctors ==0.11.1.1, + profiterole ==0.1, + profunctors ==5.6.2, + projectroot ==0.2.0.1, + project-template ==0.2.1.0, + prometheus-client ==1.1.1, + prometheus-metrics-ghc ==1.0.1.2, + promises ==0.3, + prompt ==0.1.1.2, + prospect ==0.1.0.0, + protobuf ==0.2.1.3, + protobuf-simple ==0.1.1.1, + protocol-radius ==0.0.1.1, + protocol-radius-test ==0.1.0.1, + proto-lens ==0.7.1.3, + proto-lens-optparse ==0.1.1.10, + proto-lens-runtime ==0.7.0.4, + protolude ==0.3.3, + proxied ==0.3.1, + psql-helpers ==0.1.0.0, + PSQueue ==1.2.0, + psqueues ==0.2.8.0, + pthread ==0.2.1, + ptr ==0.16.8.5, + ptr-poker ==0.1.2.14, + pulse-simple ==0.1.14, + pureMD5 ==2.1.4, + purescript-bridge ==0.15.0.0, + pusher-http-haskell ==2.1.0.17, + pvar ==1.0.0.0, + pwstore-fast ==2.4.4, + PyF ==0.11.2.1, + qchas ==1.1.0.1, + qm-interpolated-string ==0.3.1.0, + qrcode-core ==0.9.9, + qrcode-juicypixels ==0.8.5, + quaalude ==0.0.0.1, + quadratic-irrational ==0.1.1, + QuasiText ==0.1.2.6, + QuickCheck ==2.14.3, + quickcheck-arbitrary-adt ==0.3.1.0, + quickcheck-assertions ==0.3.0, + quickcheck-classes ==0.6.5.0, + quickcheck-classes-base ==0.6.2.0, + quickcheck-groups ==0.0.0.0, + quickcheck-higherorder ==0.1.0.1, + quickcheck-instances ==0.3.30, + quickcheck-io ==0.2.0, + quickcheck-monoid-subclasses ==0.1.0.0, + quickcheck-simple ==0.1.1.1, + quickcheck-special ==0.1.0.6, + quickcheck-state-machine ==0.7.3, + quickcheck-text ==0.1.2.1, + quickcheck-transformer ==0.3.1.2, + quickcheck-unicode ==1.0.1.0, + quicklz ==1.5.0.11, + quiet ==0.2, + quote-quot ==0.2.1.0, + radius ==0.7.1.0, + rainbow ==0.34.2.2, + rainbox ==0.26.0.0, + ral ==0.2.1, + rampart ==2.0.0.7, + ramus ==0.1.2, + rando ==0.0.0.4, + random ==1.2.1.1, + random-bytestring ==0.1.4, + random-fu ==0.3.0.1, + random-shuffle ==0.0.4, + random-tree ==0.6.0.5, + range ==0.3.0.2, + ranged-list ==0.1.2.1, + Ranged-sets ==0.4.0, + ranges ==0.2.4, + range-set-list ==0.1.3.1, + rank1dynamic ==0.4.1, + Rasterific ==0.7.5.4, + rasterific-svg ==0.3.3.2, + ratel ==2.0.0.10, + rate-limit ==1.4.3, + ratel-wai ==2.0.0.5, + ratio-int ==0.1.2, + rattle ==0.2, + rattletrap ==12.0.3, + Rattus ==0.5.1.1, + rawfilepath ==1.0.1, + rawstring-qm ==0.2.3.0, + raw-strings-qq ==1.1, + rcu ==0.2.7, + rdtsc ==1.3.0.1, + re2 ==0.3, + reactive-balsa ==0.4.0.1, + reactive-banana ==1.3.2.0, + reactive-banana-bunch ==1.0.0.1, + reactive-jack ==0.4.1.2, + reactive-midyim ==0.4.1.1, + readable ==0.3.1, + read-editor ==0.1.0.2, + read-env-var ==1.0.0.0, + rebase ==1.19, + rec-def ==0.2.2, + record-dot-preprocessor ==0.2.16, + record-hasfield ==1.0, + recursion-schemes ==5.2.2.5, + recv ==0.1.0, + redact ==0.5.0.0, + reddit-scrape ==0.0.1, + redis-glob ==0.1.0.6, + reducers ==3.12.4, + refact ==0.3.0.2, + ref-fd ==0.5.0.1, + refined ==0.8.1, + refinery ==0.4.0.0, + reflection ==2.1.7, + reform ==0.2.7.5, + reform-blaze ==0.2.4.4, + reform-happstack ==0.2.5.6, + RefSerialize ==0.4.0, + ref-tf ==0.5.0.1, + regex ==1.1.0.2, + regex-applicative ==0.3.4, + regex-applicative-text ==0.1.0.1, + regex-base ==0.94.0.2, + regex-compat ==0.95.2.1, + regex-pcre ==0.95.0.0, + regex-pcre-builtin ==0.95.2.3.8.44, + regex-posix ==0.96.0.1, + regex-posix-clib ==2.7, + regex-tdfa ==1.3.2.2, + regex-with-pcre ==1.1.0.2, + reinterpret-cast ==0.1.0, + rel8 ==1.4.1.0, + relapse ==1.0.0.1, + reliable-io ==0.0.2, + relude ==1.2.1.0, + renderable ==0.2.0.1, + replace-attoparsec ==1.5.0.0, + replace-megaparsec ==1.5.0.1, + repline ==0.4.2.0, + req ==3.13.0, + req-conduit ==1.0.1, + rerebase ==1.19, + reroute ==0.7.0.0, + resistor-cube ==0.0.1.4, + resolv ==0.2.0.2, + resource-pool ==0.4.0.0, + resourcet ==1.2.6, + rest-rewrite ==0.4.2, + result ==0.2.6.0, + retry ==0.9.3.1, + rev-state ==0.1.2, + rex ==0.6.2, + rfc1751 ==0.1.3, + rfc5051 ==0.2, + rg ==1.4.0.0, + rhbzquery ==0.4.4, + riak-protobuf ==0.25.0.0, + rio ==0.1.22.0, + rio-orphans ==0.1.2.0, + rio-prettyprint ==0.1.7.0, + rng-utils ==0.3.1, + rocksdb-haskell ==1.0.1, + rocksdb-haskell-jprupp ==2.1.6, + rocksdb-query ==0.4.2, + roles ==0.2.1.0, + rollbar ==1.1.3, + rope-utf16-splay ==0.4.0.0, + rosezipper ==0.2, + rot13 ==0.2.0.1, + row-types ==1.0.1.2, + rpmbuild-order ==0.4.10, + rpm-nvr ==0.1.2, + rp-tree ==0.7.1, + rrb-vector ==0.2.1.0, + RSA ==2.4.1, + rss ==3000.2.0.7, + rss-conduit ==0.6.0.1, + run-haskell-module ==0.0.2, + runmemo ==1.0.0.1, + run-st ==0.1.3.0, + rvar ==0.3.0.2, + s3-signer ==0.5.0.0, + safe ==0.3.19, + safe-coloured-text ==0.2.0.1, + safe-coloured-text-gen ==0.0.0.2, + safe-coloured-text-layout ==0.0.0.0, + safe-coloured-text-layout-gen ==0.0.0.0, + safe-coloured-text-terminfo ==0.1.0.0, + safecopy ==0.10.4.2, + safe-decimal ==0.2.1.0, + safe-exceptions ==0.1.7.4, + safe-exceptions-checked ==0.1.0, + safe-foldable ==0.1.0.0, + safe-gen ==1.0.1, + safeio ==0.0.6.0, + safe-json ==1.1.4.0, + safe-money ==0.9.1, + SafeSemaphore ==0.10.1, + saltine ==0.2.1.0, + salve ==2.0.0.4, + sample-frame ==0.0.4, + sample-frame-np ==0.0.5, + sampling ==0.3.5, + sandi ==0.5, + sandwich ==0.1.5.2, + sandwich-hedgehog ==0.1.3.0, + sandwich-quickcheck ==0.1.0.7, + sandwich-slack ==0.1.2.0, + sandwich-webdriver ==0.2.3.1, + say ==0.1.0.1, + sbp ==4.15.0, + sbv ==10.2, + scalpel ==0.6.2.2, + scalpel-core ==0.6.2.2, + scanf ==0.1.0.0, + scanner ==0.3.1, + scheduler ==2.0.0.1, + SciBaseTypes ==0.1.1.0, + scientific ==0.3.7.0, + scientist ==0.0.0.0, + scotty ==0.12.1, + scrypt ==0.5.0, + sdl2 ==2.5.5.0, + sdl2-gfx ==0.3.0.0, + sdl2-image ==2.1.0.0, + sdl2-mixer ==1.2.0.0, + sdl2-ttf ==2.1.3, + search-algorithms ==0.3.2, + secp256k1-haskell ==0.6.1, + securemem ==0.1.10, + selections ==0.3.0.0, + selective ==0.7, + semialign ==1.3, + semigroupoid-extras ==5, + semigroupoids ==5.3.7, + semigroups ==0.20, + semirings ==0.6, + semiring-simple ==1.0.0.1, + semver ==0.4.0.1, + sendfile ==0.7.11.5, + sendgrid-v3 ==1.0.0.1, + seqalign ==0.2.0.4, + seqid ==0.6.3, + seqid-streams ==0.7.2, + sequence-formats ==1.7.1, + sequenceTools ==1.5.3.1, + serialise ==0.2.6.1, + servant ==0.19.1, + servant-auth ==0.4.1.0, + servant-auth-client ==0.4.1.1, + servant-auth-docs ==0.2.10.0, + servant-auth-wordpress ==1.0.0.2, + servant-blaze ==0.9.1, + servant-cassava ==0.10.2, + servant-checked-exceptions ==2.2.0.1, + servant-checked-exceptions-core ==2.2.0.1, + servant-client ==0.19, + servant-client-core ==0.19, + servant-conduit ==0.15.1, + servant-docs ==0.12, + servant-elm ==0.7.3, + servant-exceptions ==0.2.1, + servant-exceptions-server ==0.2.1, + servant-foreign ==0.15.4, + servant-http-streams ==0.18.4, + servant-lucid ==0.9.0.6, + servant-machines ==0.15.1, + servant-multipart ==0.12.1, + servant-multipart-api ==0.12.1, + servant-multipart-client ==0.12.2, + servant-openapi3 ==2.0.1.6, + servant-pipes ==0.15.3, + servant-rate-limit ==0.2.0.0, + servant-rawm ==1.0.0.0, + servant-server ==0.19.2, + servant-static-th ==1.0.0.0, + servant-subscriber ==0.7.0.0, + servant-swagger ==1.1.11, + servant-swagger-ui ==0.3.5.5.0.0, + servant-swagger-ui-core ==0.3.5, + servant-websockets ==2.0.0, + servant-xml ==1.0.2, + serversession ==1.0.3, + serversession-backend-redis ==1.0.5, + serversession-frontend-wai ==1.0.1, + serversession-frontend-yesod ==1.0.1, + servius ==1.2.3.0, + ses-html ==0.4.0.0, + set-cover ==0.1.1, + setenv ==0.1.1.3, + setlocale ==1.0.0.10, + set-monad ==0.3.0.0, + sets ==0.0.6.2, + sexp-grammar ==2.3.4.2, + SHA ==1.6.4.4, + shake ==0.19.7, + shake-plus ==0.3.4.0, + shakespeare ==2.1.0.1, + shakespeare-text ==1.1.0, + shared-memory ==0.2.0.1, + ShellCheck ==0.9.0, + shell-conduit ==5.0.0, + shell-escape ==0.2.0, + shelltestrunner ==1.9.0.1, + shell-utility ==0.1, + shellwords ==0.1.3.1, + shelly ==1.12.1, + should-not-typecheck ==2.1.0, + show-combinators ==0.2.0.0, + shower ==0.2.0.3, + siggy-chardust ==1.0.0, + signal ==0.1.0.4, + silently ==1.2.5.3, + simple ==2.0.0, + simple-affine-space ==0.2.1, + simple-cabal ==0.1.3.1, + simple-cmd ==0.2.7, + simple-cmd-args ==0.1.8, + simple-expr ==0.1.1.0, + simple-media-timestamp ==0.2.1.0, + simple-media-timestamp-attoparsec ==0.1.0.0, + simple-prompt ==0.2.2, + simple-reflect ==0.3.3, + simple-sendfile ==0.2.32, + simple-session ==2.0.0, + simple-templates ==2.0.0, + simple-vec3 ==0.6.0.1, + since ==0.0.0, + singleton-bool ==0.1.6, + singleton-nats ==0.4.7, + singletons ==3.0.2, + singletons-base ==3.1.1, + singletons-presburger ==0.7.2.0, + singletons-th ==3.1.1, + Sit ==0.2022.3.18, + sitemap-gen ==0.1.0.0, + size-based ==0.1.3.2, + sized ==1.1.0.0, + skein ==1.0.9.4, + skews ==0.1.0.3, + skip-var ==0.1.1.0, + skylighting ==0.13.4.1, + skylighting-core ==0.13.4.1, + skylighting-format-ansi ==0.1, + skylighting-format-blaze-html ==0.1.1.1, + skylighting-format-context ==0.1.0.2, + skylighting-format-latex ==0.1, + slack-progressbar ==0.1.0.1, + slave-thread ==1.1.0.3, + slick ==1.2.1.0, + slist ==0.2.1.0, + slynx ==0.7.2.2, + smallcheck ==1.2.1.1, + smtp-mail ==0.3.0.0, + snap-blaze ==0.2.1.5, + snap-core ==1.0.5.1, + snowflake ==0.1.1.1, + socket ==0.8.3.0, + socks ==0.6.1, + solana-staking-csvs ==0.1.2.0, + some ==1.0.4.1, + some-dict-of ==0.1.0.2, + sop-core ==0.5.0.2, + sort ==1.0.0.0, + sorted-list ==0.2.1.2, + sound-collage ==0.2.1, + sourcemap ==0.1.7, + sox ==0.2.3.2, + soxlib ==0.0.3.2, + spacecookie ==1.0.0.2, + spatial-math ==0.2.7.0, + special-values ==0.1.0.0, + speculate ==0.4.14, + speedy-slice ==0.3.2, + splice ==0.6.1.1, + split ==0.2.3.5, + splitmix ==0.1.0.5, + splitmix-distributions ==1.0.0, + split-record ==0.1.1.4, + Spock ==0.14.0.0, + Spock-api ==0.14.0.0, + Spock-api-server ==0.14.0.0, + Spock-core ==0.14.0.1, + Spock-lucid ==0.4.0.1, + Spock-worker ==0.3.1.0, + spoon ==0.3.1, + spreadsheet ==0.1.3.10, + sqlcli ==0.2.2.0, + sqlcli-odbc ==0.2.0.1, + sqlite-simple ==0.4.18.2, + sql-words ==0.1.6.5, + squeather ==0.8.0.0, + srcloc ==0.6.0.1, + srt ==0.1.2.0, + srtree ==1.0.0.5, + stache ==2.3.4, + stack ==2.9.3.1, + stack-all ==0.4.2, + stack-clean-old ==0.4.8, + stack-templatizer ==0.1.1.0, + state-codes ==0.1.3, + stateref ==0.3, + statestack ==0.3.1.1, + StateVar ==1.2.2, + stateWriter ==0.4.0, + static-canvas ==0.2.0.3, + static-text ==0.2.0.7, + statistics ==0.16.2.1, + statistics-linreg ==0.3, + status-notifier-item ==0.3.1.0, + step-function ==0.2.0.1, + stitch ==0.6.0.0, + stm installed, + stm-chans ==3.0.0.9, + stm-conduit ==4.0.1, + stm-containers ==1.2.0.3, + stm-delay ==0.1.1.1, + stm-extras ==0.1.0.3, + stm-hamt ==1.2.0.14, + stm-lifted ==2.5.0.0, + STMonadTrans ==0.4.7, + stm-split ==0.0.2.1, + stopwatch ==0.1.0.6, + storable-complex ==0.2.3.0, + storable-endian ==0.2.6.1, + storable-record ==0.0.7, + storable-tuple ==0.1, + storablevector ==0.2.13.2, + store ==0.7.18, + store-core ==0.4.4.6, + store-streaming ==0.2.0.5, + stratosphere ==0.60.0, + Stream ==0.4.7.2, + streaming ==0.2.4.0, + streaming-attoparsec ==1.0.0.1, + streaming-bytestring ==0.3.2, + streaming-commons ==0.2.2.6, + streaming-wai ==0.1.1, + streamly ==0.9.0, + streamly-core ==0.1.0, + streamly-examples ==0.1.3, + streamly-process ==0.3.0, + streams ==3.3.2, + streamt ==0.5.0.1, + strict ==0.5, + strict-base-types ==0.8, + strict-concurrency ==0.2.4.3, + strict-lens ==0.4.0.3, + strict-list ==0.1.7.4, + strict-tuple ==0.1.5.3, + strict-wrapper ==0.0.0.0, + stringable ==0.1.3, + stringbuilder ==0.5.1, + string-combinators ==0.6.0.5, + string-conv ==0.2.0, + string-conversions ==0.4.0.1, + string-interpolate ==0.3.2.1, + stringprep ==1.0.0, + string-qq ==0.0.5, + string-random ==0.1.4.3, + stringsearch ==0.3.6.6, + string-transform ==1.1.1, + string-variants ==0.2.2.0, + stripe-concepts ==1.0.3.3, + stripe-scotty ==1.1.0.4, + stripe-signature ==1.0.0.16, + stripe-wreq ==1.0.1.16, + strive ==6.0.0.10, + structs ==0.1.9, + structured ==0.1.1, + structured-cli ==2.7.0.1, + subcategories ==0.2.0.1, + sundown ==0.6, + superbuffer ==0.3.1.2, + svg-builder ==0.1.1, + SVGFonts ==1.8.0.1, + svg-tree ==0.6.2.4, + swagger2 ==2.8.7, + swish ==0.10.7.0, + syb ==0.7.2.4, + sydtest ==0.15.1.1, + sydtest-aeson ==0.1.0.0, + sydtest-amqp ==0.1.0.0, + sydtest-autodocodec ==0.0.0.0, + sydtest-discover ==0.0.0.4, + sydtest-hedgehog ==0.4.0.0, + sydtest-hedis ==0.0.0.0, + sydtest-mongo ==0.0.0.0, + sydtest-persistent ==0.0.0.2, + sydtest-persistent-postgresql ==0.2.0.3, + sydtest-persistent-sqlite ==0.2.0.3, + sydtest-process ==0.0.0.0, + sydtest-rabbitmq ==0.1.0.0, + sydtest-servant ==0.2.0.2, + sydtest-typed-process ==0.0.0.0, + sydtest-wai ==0.2.0.1, + sydtest-webdriver ==0.0.0.1, + sydtest-webdriver-screenshot ==0.0.0.2, + sydtest-webdriver-yesod ==0.0.0.1, + sydtest-yesod ==0.3.0.2, + symbol ==0.2.4, + symengine ==0.1.2.0, + symmetry-operations-symbols ==0.0.2.1, + synthesizer-alsa ==0.5.0.6, + synthesizer-core ==0.8.3, + synthesizer-dimensional ==0.8.1.1, + synthesizer-midi ==0.6.1.2, + sysinfo ==0.1.1, + system-argv0 ==0.1.1, + systemd ==2.3.0, + systemd-socket-activation ==1.1.0.1, + system-fileio ==0.3.16.4, + system-filepath ==0.4.14, + system-info ==0.5.2, + tabular ==0.2.2.8, + tagchup ==0.4.1.2, + tagged ==0.8.7, + tagged-binary ==0.2.0.1, + tagged-identity ==0.1.4, + tagged-transformer ==0.8.2, + tagshare ==0.0, + tagsoup ==0.14.8, + tagstream-conduit ==0.5.6, + tao ==1.0.0, + tao-example ==1.0.0, + tar ==0.5.1.1, + tar-conduit ==0.3.2.1, + tardis ==0.4.4.0, + tasty ==1.4.3, + tasty-ant-xml ==1.1.9, + tasty-autocollect ==0.4.1, + tasty-bench ==0.3.5, + tasty-dejafu ==2.1.0.1, + tasty-discover ==5.0.0, + tasty-expected-failure ==0.12.3, + tasty-fail-fast ==0.0.3, + tasty-focus ==1.0.1, + tasty-golden ==2.3.5, + tasty-hedgehog ==1.4.0.1, + tasty-hslua ==1.1.0, + tasty-hspec ==1.2.0.3, + tasty-html ==0.4.2.1, + tasty-hunit ==0.10.1, + tasty-hunit-compat ==0.2.0.1, + tasty-inspection-testing ==0.2, + tasty-kat ==0.0.3, + tasty-leancheck ==0.0.2, + tasty-lua ==1.1.0, + tasty-program ==1.1.0, + tasty-quickcheck ==0.10.2, + tasty-rerun ==1.1.19, + tasty-silver ==3.3.1.3, + tasty-smallcheck ==0.8.2, + tasty-tap ==0.1.0, + tasty-th ==0.1.7, + tasty-wai ==0.1.2.0, + tce-conf ==1.3, + tcp-streams ==1.0.1.1, + tdigest ==0.3, + teardown ==0.5.0.1, + telegram-bot-api ==6.7.1, + telegram-bot-simple ==0.12, + template-haskell installed, + template-haskell-compat-v0208 ==0.1.9.3, + temporary ==1.3, + temporary-rc ==1.2.0.3, + temporary-resourcet ==0.1.0.1, + tensorflow-test ==0.1.0.0, + tensors ==0.1.5, + termbox ==1.1.0.2, + termbox-banana ==1.0.0, + termbox-bindings-c ==0.1.0.1, + termbox-bindings-hs ==0.1.1, + termbox-tea ==0.1.0.1, + terminal-progress-bar ==0.4.2, + terminal-size ==0.3.4, + terminfo installed, + termonad ==4.5.0.0, + test-framework ==0.8.2.0, + test-framework-hunit ==0.3.0.2, + test-framework-leancheck ==0.0.4, + test-framework-quickcheck2 ==0.3.0.5, + test-framework-smallcheck ==0.2, + test-fun ==0.1.0.0, + testing-feat ==1.1.1.1, + testing-type-modifiers ==0.1.0.1, + texmath ==0.12.8.4, + text installed, + text-ansi ==0.2.1.1, + text-binary ==0.2.1.1, + text-builder ==0.6.7, + text-builder-dev ==0.3.3.2, + text-builder-linear ==0.1.2, + text-conversions ==0.3.1.1, + text-format ==0.3.2.1, + text-icu ==0.8.0.4, + text-latin1 ==0.3.1, + text-ldap ==0.1.1.14, + textlocal ==0.1.0.5, + text-manipulate ==0.3.1.0, + text-metrics ==0.3.2, + text-postgresql ==0.0.3.1, + text-printer ==0.5.0.2, + text-regex-replace ==0.1.1.5, + text-rope ==0.2, + text-short ==0.1.5, + text-show ==3.10.4, + text-show-instances ==3.9.7, + text-zipper ==0.13, + tfp ==1.0.2, + tf-random ==0.5, + th-abstraction ==0.4.5.0, + th-bang-compat ==0.0.1.0, + th-compat ==0.1.4, + th-constraint-compat ==0.0.1.0, + th-data-compat ==0.1.3.0, + th-desugar ==1.14, + th-env ==0.1.1, + these ==1.2, + these-lens ==1.0.1.3, + these-optics ==1.0.1.2, + these-skinny ==0.7.5, + th-expand-syns ==0.4.11.0, + th-lego ==0.3.0.3, + th-lift ==0.8.4, + th-lift-instances ==0.1.20, + th-nowq ==0.1.0.5, + th-orphans ==0.13.14, + th-printf ==0.7, + thread-hierarchy ==0.3.0.2, + thread-local-storage ==0.2, + threads ==0.5.1.8, + threads-extras ==0.1.0.3, + thread-supervisor ==0.2.0.0, + th-reify-compat ==0.0.1.5, + th-reify-many ==0.1.10, + th-strict-compat ==0.1.0.1, + th-test-utils ==1.2.1, + th-utilities ==0.2.5.0, + thyme ==0.4, + tidal ==1.9.4, + tidal-link ==1.0.2, + tile ==0.3.0.0, + time installed, + time-compat ==1.9.6.1, + time-domain ==0.1.0.2, + timeit ==2.0, + time-lens ==0.4.0.2, + timelens ==0.2.0.2, + time-locale-compat ==0.1.1.5, + time-locale-vietnamese ==1.0.0.0, + time-manager ==0.0.1, + time-parsers ==0.2, + timerep ==2.1.0.0, + timers-tick ==0.5.0.4, + timer-wheel ==0.4.0.1, + timespan ==0.4.0.0, + time-units ==1.0.0, + time-units-types ==0.2.0.1, + timezone-olson ==0.2.1, + timezone-olson-th ==0.1.0.11, + timezone-series ==0.1.13, + titlecase ==1.0.1, + tls ==1.6.0, + tls-session-manager ==0.0.4, + tlynx ==0.7.2.2, + tmapchan ==0.0.3, + tmapmvar ==0.0.4, + tmp-postgres ==1.34.1.0, + tmp-proc ==0.5.1.4, + tmp-proc-postgres ==0.5.2.3, + tmp-proc-rabbitmq ==0.5.1.4, + tmp-proc-redis ==0.5.1.4, + token-bucket ==0.1.0.1, + toml-reader ==0.2.1.0, + toml-reader-parse ==0.1.1.1, + tophat ==1.0.7.0, + topograph ==1.0.0.2, + torrent ==10000.1.3, + torsor ==0.1, + tostring ==0.2.1.1, + tracing ==0.0.7.3, + tracing-control ==0.0.7.3, + transaction ==0.1.1.4, + transformers installed, + transformers-base ==0.4.6, + transformers-compat ==0.7.2, + transformers-either ==0.1.4, + transformers-fix ==1.0, + transient ==0.7.0.0, + traverse-with-class ==1.0.1.1, + tree-diff ==0.3.0.1, + tree-fun ==0.8.1.0, + tree-view ==0.5.1, + trie-simple ==0.4.2, + trifecta ==2.1.3, + trimdent ==0.1.0.0, + triplesec ==0.2.2.1, + trivial-constraint ==0.7.0.0, + tsv2csv ==0.1.0.2, + ttc ==1.2.1.0, + ttrie ==0.1.2.2, + tuple ==0.3.0.2, + tuples ==0.1.0.0, + tuples-homogenous-h98 ==0.1.1.0, + tuple-sop ==0.3.1.0, + tuple-th ==0.2.5, + turtle ==1.6.1, + twitter-conduit ==0.6.1, + twitter-types ==0.11.0, + twitter-types-lens ==0.11.0, + typecheck-plugin-nat-simple ==0.1.0.9, + typed-process ==0.2.11.1, + typed-uuid ==0.2.0.0, + type-equality ==1, + type-errors ==0.2.0.2, + type-fun ==0.1.3, + type-hint ==0.1, + type-level-integers ==0.0.1, + type-level-kv-list ==2.0.2.0, + type-level-natural-number ==2.0, + type-level-numbers ==0.1.1.2, + type-map ==0.1.7.0, + type-natural ==1.3.0.0, + typenums ==0.1.4, + type-of-html ==1.6.2.0, + type-of-html-static ==0.1.0.2, + type-rig ==0.1, + type-spec ==0.4.0.0, + typography-geometry ==1.0.1.0, + typst-symbols ==0.1.4, + tz ==0.1.3.6, + tzdata ==0.2.20230322.0, + tztime ==0.1.1.0, + ua-parser ==0.7.7.0, + uglymemo ==0.1.0.1, + ulid ==0.3.2.0, + unagi-chan ==0.4.1.4, + unbounded-delays ==0.1.1.1, + unbound-generics ==0.4.3, + unboxed-ref ==0.4.0.0, + unboxing-vector ==0.2.0.0, + uncaught-exception ==0.1.0, + unconstrained ==0.1.0.2, + unexceptionalio ==0.5.1, + unexceptionalio-trans ==0.5.1, + unfork ==1.0.0.1, + unicode ==0.0.1.1, + unicode-collation ==0.1.3.5, + unicode-data ==0.4.0.1, + unicode-show ==0.1.1.1, + unicode-transforms ==0.4.0.1, + unidecode ==0.1.0.4, + unification-fd ==0.11.2, + union ==0.1.2, + union-angle ==0.1.0.1, + unipatterns ==0.0.0.0, + uniplate ==1.6.13, + uniq-deep ==1.2.1, + unique ==0.0.1, + unique-logic ==0.4.0.1, + unique-logic-tf ==0.5.1, + unit-constraint ==0.0.0, + units-parser ==0.1.1.5, + universe ==1.2.2, + universe-base ==1.1.3.1, + universe-dependent-sum ==1.3, + universe-instances-extended ==1.1.3, + universe-reverse-instances ==1.1.1, + universe-some ==1.2.1, + universum ==1.8.2, + unix installed, + unix-bytestring ==0.4.0, + unix-compat ==0.7.1, + unix-time ==0.4.11, + unjson ==0.15.4, + unliftio ==0.2.25.0, + unliftio-core ==0.2.1.0, + unliftio-path ==0.0.2.0, + unliftio-pool ==0.4.2.0, + unlit ==0.4.0.0, + unordered-containers ==0.2.19.1, + unsafe ==0.0, + uri-bytestring ==0.3.3.1, + uri-bytestring-aeson ==0.1.0.8, + uri-encode ==1.5.0.7, + url ==2.1.3, + users ==0.5.0.0, + users-postgresql-simple ==0.5.0.2, + users-test ==0.5.0.1, + utf8-light ==0.4.4.0, + utf8-string ==1.0.2, + utility-ht ==0.0.17, + uuid ==1.3.15, + uuid-types ==1.0.5.1, + valida ==1.1.0, + valida-base ==0.2.0, + validate-input ==0.5.0.0, + validationt ==0.3.0, + validity ==0.12.0.2, + validity-aeson ==0.2.0.5, + validity-bytestring ==0.4.1.1, + validity-case-insensitive ==0.0.0.0, + validity-containers ==0.5.0.4, + validity-persistent ==0.0.0.0, + validity-primitive ==0.0.0.1, + validity-scientific ==0.2.0.3, + validity-text ==0.3.1.3, + validity-time ==0.5.0.0, + validity-unordered-containers ==0.2.0.3, + validity-uuid ==0.1.0.3, + validity-vector ==0.2.0.3, + valor ==1.0.0.0, + varying ==0.8.1.0, + vault ==0.3.1.5, + vcs-ignore ==0.0.2.0, + vec ==0.5, + vector ==0.13.1.0, + vector-algorithms ==0.9.0.1, + vector-binary-instances ==0.2.5.2, + vector-buffer ==0.4.1, + vector-builder ==0.3.8.5, + vector-bytes-instances ==0.1.1, + vector-extras ==0.2.8.1, + vector-hashtables ==0.1.1.4, + vector-instances ==3.4.2, + vector-mmap ==0.0.3, + vector-rotcev ==0.1.0.2, + vector-sized ==1.5.0, + vector-space ==0.16, + vector-split ==1.0.0.3, + vector-stream ==0.1.0.0, + vector-th-unbox ==0.2.2, + verbosity ==0.4.0.0, + versions ==6.0.3, + vformat ==0.14.1.0, + vformat-time ==0.1.0.0, + ViennaRNAParser ==1.3.3, + vinyl ==0.14.3, + vinyl-loeb ==0.0.1.0, + vivid ==0.5.2.0, + vivid-osc ==0.5.0.0, + vivid-supercollider ==0.4.1.2, + void ==0.7.3, + vty ==5.38, + wai ==3.2.4, + wai-app-static ==3.1.8, + wai-cli ==0.2.3, + wai-conduit ==3.0.0.4, + wai-control ==0.2.0.0, + wai-cors ==0.2.7, + wai-enforce-https ==1.0.0.0, + wai-eventsource ==3.0.0, + wai-extra ==3.1.13.0, + wai-feature-flags ==0.1.0.7, + wai-handler-launch ==3.0.3.1, + wai-logger ==2.4.0, + wai-middleware-bearer ==1.0.3, + wai-middleware-caching ==0.1.0.2, + wai-middleware-caching-lru ==0.1.0.0, + wai-middleware-caching-redis ==0.2.0.0, + wai-middleware-clacks ==0.1.0.1, + wai-middleware-delegate ==0.1.3.1, + wai-middleware-metrics ==0.2.4, + wai-middleware-prometheus ==1.0.0.1, + wai-middleware-static ==0.9.2, + wai-middleware-throttle ==0.3.0.1, + wai-rate-limit ==0.3.0.0, + wai-rate-limit-redis ==0.2.0.1, + wai-saml2 ==0.4, + wai-session ==0.3.3, + wai-session-postgresql ==0.2.1.3, + wai-session-redis ==0.1.0.5, + wai-slack-middleware ==0.2.0, + wai-websockets ==3.0.1.2, + wakame ==0.1.0.0, + warp ==3.3.25, + warp-tls ==3.3.6, + warp-tls-uid ==0.2.0.6, + wave ==0.2.1, + wcwidth ==0.0.2, + webdriver ==0.11.0.0, + webex-teams-api ==0.2.0.1, + webex-teams-conduit ==0.2.0.1, + webgear-core ==1.0.5, + webgear-openapi ==1.0.5, + webpage ==0.0.5.1, + web-routes ==0.27.15, + web-routes-boomerang ==0.28.4.4, + web-routes-happstack ==0.23.12.3, + web-routes-hsp ==0.24.6.2, + web-routes-th ==0.22.8.1, + web-routes-wai ==0.24.3.2, + webrtc-vad ==0.1.0.3, + websockets ==0.12.7.3, + weigh ==0.0.16, + welford-online-mean-variance ==0.2.0.0, + wide-word ==0.1.6.0, + Win32 installed, + Win32-notify ==0.3.0.3, + windns ==0.1.0.1, + witch ==1.2.0.3, + withdependencies ==0.3.0, + witherable ==0.4.2, + within ==0.2.0.1, + with-location ==0.1.0, + with-utf8 ==1.0.2.4, + witness ==0.6.2, + wizards ==1.0.3, + wl-pprint ==1.2.1, + wl-pprint-annotated ==0.1.0.1, + wl-pprint-text ==1.2.0.2, + word8 ==0.1.3, + word-compat ==0.0.6, + wordpress-auth ==1.0.0.1, + word-trie ==0.3.0, + word-wrap ==0.5, + world-peace ==1.0.2.0, + wrap ==0.0.0, + wreq ==0.5.4.2, + wreq-stringless ==0.5.9.1, + writer-cps-exceptions ==0.1.0.1, + writer-cps-mtl ==0.1.1.6, + writer-cps-transformers ==0.5.6.1, + wss-client ==0.3.0.0, + wuss ==2.0.1.3, + X11 ==1.10.3, + X11-xft ==0.3.4, + x11-xim ==0.0.9.0, + x509 ==1.7.7, + x509-store ==1.6.9, + x509-system ==1.6.7, + x509-validation ==1.6.12, + Xauth ==0.1, + xdg-basedir ==0.2.2, + xdg-desktop-entry ==0.1.1.1, + xdg-userdirs ==0.1.0.2, + xeno ==0.6, + xhtml installed, + xlsx ==1.1.1, + xml ==1.3.14, + xml-basic ==0.1.3.2, + xmlbf ==0.7, + xmlbf-xeno ==0.2.2, + xmlbf-xmlhtml ==0.2.2, + xml-conduit ==1.9.1.3, + xml-conduit-writer ==0.1.1.4, + xmlgen ==0.6.2.2, + xml-hamlet ==0.5.0.2, + xml-helpers ==1.0.0, + xmlhtml ==0.2.5.4, + xml-html-qq ==0.1.0.1, + xml-indexed-cursor ==0.1.1.0, + xml-lens ==0.3.1, + xml-parser ==0.1.1.1, + xml-picklers ==0.3.6, + xml-to-json-fast ==2.0.0, + xml-types ==0.3.8, + xmonad ==0.17.2, + xmonad-contrib ==0.17.1, + xor ==0.0.1.2, + xss-sanitize ==0.3.7.2, + xxhash-ffi ==0.2.0.0, + yaml ==0.11.11.2, + yaml-unscrambler ==0.1.0.18, + Yampa ==0.14.6, + yarn-lock ==0.6.5, + yeshql-core ==4.2.0.0, + yesod ==1.6.2.1, + yesod-auth ==1.6.11.2, + yesod-auth-basic ==0.1.0.3, + yesod-auth-hashdb ==1.7.1.7, + yesod-auth-oauth2 ==0.7.1.3, + yesod-auth-oidc ==0.1.4, + yesod-bin ==1.6.2.2, + yesod-core ==1.6.25.1, + yesod-eventsource ==1.6.0.1, + yesod-fb ==0.6.1, + yesod-form ==1.7.6, + yesod-form-bootstrap4 ==3.0.1.1, + yesod-gitrepo ==0.3.0, + yesod-gitrev ==0.2.2, + yesod-markdown ==0.12.6.13, + yesod-middleware-csp ==1.2.0, + yesod-newsfeed ==1.7.0.0, + yesod-page-cursor ==2.0.1.0, + yesod-paginator ==1.1.2.2, + yesod-persistent ==1.6.0.8, + yesod-recaptcha2 ==1.0.2.1, + yesod-routes-flow ==3.0.0.2, + yesod-sitemap ==1.6.0, + yesod-static ==1.6.1.0, + yesod-test ==1.6.16, + yesod-websockets ==0.3.0.3, + yes-precure5-command ==5.5.3, + yi-rope ==0.11, + yjsvg ==0.2.0.1, + yjtools ==0.9.18, + yoga ==0.0.0.5, + youtube ==0.2.1.1, + zenacy-html ==2.1.0, + zenacy-unicode ==1.0.2, + zeromq4-haskell ==0.8.0, + zeromq4-patterns ==0.3.1.0, + zigzag ==0.0.1.0, + zim-parser ==0.2.1.0, + zio ==0.1.0.2, + zip ==2.0.0, + zip-archive ==0.4.3, + zipper-extra ==0.1.3.2, + zippers ==0.3.2, + zip-stream ==0.2.2.0, + zlib ==0.6.3.0, + zlib-bindings ==0.1.1.5, + zot ==0.0.3, + zstd ==0.1.3.0 + diff --git a/ci/configs/ghc-9.6.6.project b/ci/configs/ghc-9.6.6.project new file mode 100644 index 0000000..640cd25 --- /dev/null +++ b/ci/configs/ghc-9.6.6.project @@ -0,0 +1,3385 @@ +-- NOTE: Due to revisions, this file may not work. See: +-- https://github.com/fpco/stackage-server/issues/232 + +-- Stackage snapshot from: http://www.stackage.org/snapshot/lts-22.36 +-- Please place this file next to your .cabal file as cabal.config +-- To only use tested packages, uncomment the following line: +-- remote-repo: stackage-lts-22.36:http://www.stackage.org/lts-22.36 +with-compiler: ghc-9.6.6 +constraints: abstract-deque ==0.3, + abstract-deque-tests ==0.3, + abstract-par ==0.3.3, + AC-Angle ==1.0, + acc ==0.2.0.3, + ace ==0.6, + acid-state ==0.16.1.3, + action-permutations ==0.0.0.1, + active ==0.2.1, + ad ==4.5.6, + ad-delcont ==0.5.0.0, + adjunctions ==4.4.2, + adler32 ==0.1.2.0, + aern2-mp ==0.2.15.1, + aern2-real ==0.2.15.1, + aeson ==2.1.2.1, + aeson-attoparsec ==0.0.0, + aeson-casing ==0.2.0.0, + aeson-combinators ==0.1.2.1, + aeson-diff ==1.1.0.13, + aeson-extra ==0.5.1.3, + aeson-generic-compat ==0.0.2.0, + aeson-iproute ==0.3.0, + aeson-optics ==1.2.1, + aeson-picker ==0.1.0.6, + aeson-pretty ==0.8.10, + aeson-qq ==0.8.4, + aeson-schemas ==1.4.2.1, + aeson-typescript ==0.6.3.0, + aeson-unqualified-ast ==1.0.0.3, + aeson-value-parser ==0.19.7.2, + aeson-warning-parser ==0.1.1, + aeson-yak ==0.1.1.3, + aeson-yaml ==1.1.0.1, + Agda ==2.6.4.3, + agda2lagda ==0.2023.6.9, + agreeing ==0.2.2.0, + alarmclock ==0.7.0.6, + alex ==3.4.0.1, + alex-meta ==0.3.0.13, + alex-tools ==0.6.1, + algebra ==4.3.1, + algebraic-graphs ==0.7, + align-audio ==0.0.0.1, + Allure ==0.11.0.0, + almost-fix ==0.0.2, + alsa-core ==0.5.0.1, + alsa-mixer ==0.3.0.1, + alsa-pcm ==0.6.1.1, + alsa-seq ==0.6.0.9, + alternative-vector ==0.0.0, + alternators ==1.0.0.0, + ALUT ==2.4.0.3, + amazonka ==2.0, + amazonka-accessanalyzer ==2.0, + amazonka-account ==2.0, + amazonka-amp ==2.0, + amazonka-amplify ==2.0, + amazonka-amplifybackend ==2.0, + amazonka-amplifyuibuilder ==2.0, + amazonka-apigateway ==2.0, + amazonka-apigatewaymanagementapi ==2.0, + amazonka-apigatewayv2 ==2.0, + amazonka-appconfig ==2.0, + amazonka-appconfigdata ==2.0, + amazonka-appflow ==2.0, + amazonka-appintegrations ==2.0, + amazonka-application-autoscaling ==2.0, + amazonka-applicationcostprofiler ==2.0, + amazonka-application-insights ==2.0, + amazonka-appmesh ==2.0, + amazonka-apprunner ==2.0, + amazonka-appstream ==2.0, + amazonka-arc-zonal-shift ==2.0, + amazonka-athena ==2.0, + amazonka-auditmanager ==2.0, + amazonka-autoscaling ==2.0, + amazonka-backup ==2.0, + amazonka-backup-gateway ==2.0, + amazonka-backupstorage ==2.0, + amazonka-billingconductor ==2.0, + amazonka-braket ==2.0, + amazonka-budgets ==2.0, + amazonka-certificatemanager ==2.0, + amazonka-chime ==2.0, + amazonka-chime-sdk-identity ==2.0, + amazonka-chime-sdk-media-pipelines ==2.0, + amazonka-chime-sdk-meetings ==2.0, + amazonka-chime-sdk-messaging ==2.0, + amazonka-chime-sdk-voice ==2.0, + amazonka-cloudcontrol ==2.0, + amazonka-cloudformation ==2.0, + amazonka-cloudfront ==2.0, + amazonka-cloudhsm ==2.0, + amazonka-cloudsearch ==2.0, + amazonka-cloudsearch-domains ==2.0, + amazonka-cloudtrail ==2.0, + amazonka-cloudwatch ==2.0, + amazonka-cloudwatch-events ==2.0, + amazonka-cloudwatch-logs ==2.0, + amazonka-codeartifact ==2.0, + amazonka-codebuild ==2.0, + amazonka-codecommit ==2.0, + amazonka-codedeploy ==2.0, + amazonka-codeguruprofiler ==2.0, + amazonka-codeguru-reviewer ==2.0, + amazonka-codepipeline ==2.0, + amazonka-codestar-connections ==2.0, + amazonka-codestar-notifications ==2.0, + amazonka-cognito-identity ==2.0, + amazonka-cognito-idp ==2.0, + amazonka-cognito-sync ==2.0, + amazonka-comprehendmedical ==2.0, + amazonka-compute-optimizer ==2.0, + amazonka-config ==2.0, + amazonka-connectcampaigns ==2.0, + amazonka-connectcases ==2.0, + amazonka-connect-contact-lens ==2.0, + amazonka-connectparticipant ==2.0, + amazonka-controltower ==2.0, + amazonka-core ==2.0, + amazonka-customer-profiles ==2.0, + amazonka-databrew ==2.0, + amazonka-dataexchange ==2.0, + amazonka-datapipeline ==2.0, + amazonka-datasync ==2.0, + amazonka-detective ==2.0, + amazonka-devicefarm ==2.0, + amazonka-devops-guru ==2.0, + amazonka-directconnect ==2.0, + amazonka-discovery ==2.0, + amazonka-dlm ==2.0, + amazonka-dms ==2.0, + amazonka-docdb ==2.0, + amazonka-docdb-elastic ==2.0, + amazonka-drs ==2.0, + amazonka-ds ==2.0, + amazonka-dynamodb ==2.0, + amazonka-dynamodb-streams ==2.0, + amazonka-ebs ==2.0, + amazonka-ec2 ==2.0, + amazonka-ec2-instance-connect ==2.0, + amazonka-ecr ==2.0, + amazonka-ecr-public ==2.0, + amazonka-ecs ==2.0, + amazonka-efs ==2.0, + amazonka-eks ==2.0, + amazonka-elasticache ==2.0, + amazonka-elasticbeanstalk ==2.0, + amazonka-elastic-inference ==2.0, + amazonka-elasticsearch ==2.0, + amazonka-elastictranscoder ==2.0, + amazonka-elb ==2.0, + amazonka-elbv2 ==2.0, + amazonka-emr ==2.0, + amazonka-emr-containers ==2.0, + amazonka-emr-serverless ==2.0, + amazonka-evidently ==2.0, + amazonka-finspace ==2.0, + amazonka-finspace-data ==2.0, + amazonka-fis ==2.0, + amazonka-forecast ==2.0, + amazonka-forecastquery ==2.0, + amazonka-frauddetector ==2.0, + amazonka-fsx ==2.0, + amazonka-gamelift ==2.0, + amazonka-gamesparks ==2.0, + amazonka-glacier ==2.0, + amazonka-globalaccelerator ==2.0, + amazonka-glue ==2.0, + amazonka-grafana ==2.0, + amazonka-greengrassv2 ==2.0, + amazonka-groundstation ==2.0, + amazonka-health ==2.0, + amazonka-healthlake ==2.0, + amazonka-honeycode ==2.0, + amazonka-iam ==2.0, + amazonka-identitystore ==2.0, + amazonka-imagebuilder ==2.0, + amazonka-importexport ==2.0, + amazonka-inspector ==2.0, + amazonka-inspector2 ==2.0, + amazonka-iot ==2.0, + amazonka-iot1click-devices ==2.0, + amazonka-iot1click-projects ==2.0, + amazonka-iot-dataplane ==2.0, + amazonka-iotdeviceadvisor ==2.0, + amazonka-iotevents ==2.0, + amazonka-iotevents-data ==2.0, + amazonka-iotfleethub ==2.0, + amazonka-iotfleetwise ==2.0, + amazonka-iot-roborunner ==2.0, + amazonka-iotsecuretunneling ==2.0, + amazonka-iotsitewise ==2.0, + amazonka-iotthingsgraph ==2.0, + amazonka-iottwinmaker ==2.0, + amazonka-iotwireless ==2.0, + amazonka-ivs ==2.0, + amazonka-ivschat ==2.0, + amazonka-kafka ==2.0, + amazonka-kafkaconnect ==2.0, + amazonka-kendra ==2.0, + amazonka-keyspaces ==2.0, + amazonka-kinesis ==2.0, + amazonka-kinesis-analytics ==2.0, + amazonka-kinesisanalyticsv2 ==2.0, + amazonka-kinesis-firehose ==2.0, + amazonka-kinesis-video-signaling ==2.0, + amazonka-kinesis-video-webrtc-storage ==2.0, + amazonka-kms ==2.0, + amazonka-lakeformation ==2.0, + amazonka-lambda ==2.0, + amazonka-lexv2-models ==2.0, + amazonka-license-manager ==2.0, + amazonka-license-manager-linux-subscriptions ==2.0, + amazonka-license-manager-user-subscriptions ==2.0, + amazonka-lightsail ==2.0, + amazonka-location ==2.0, + amazonka-lookoutequipment ==2.0, + amazonka-lookoutmetrics ==2.0, + amazonka-lookoutvision ==2.0, + amazonka-m2 ==2.0, + amazonka-macie ==2.0, + amazonka-maciev2 ==2.0, + amazonka-managedblockchain ==2.0, + amazonka-marketplace-analytics ==2.0, + amazonka-marketplace-catalog ==2.0, + amazonka-marketplace-metering ==2.0, + amazonka-mediaconnect ==2.0, + amazonka-mediapackage-vod ==2.0, + amazonka-mediatailor ==2.0, + amazonka-memorydb ==2.0, + amazonka-mgn ==2.0, + amazonka-migrationhub-config ==2.0, + amazonka-migrationhuborchestrator ==2.0, + amazonka-migration-hub-refactor-spaces ==2.0, + amazonka-migrationhubstrategy ==2.0, + amazonka-ml ==2.0, + amazonka-mwaa ==2.0, + amazonka-neptune ==2.0, + amazonka-network-firewall ==2.0, + amazonka-networkmanager ==2.0, + amazonka-nimble ==2.0, + amazonka-oam ==2.0, + amazonka-omics ==2.0, + amazonka-opensearch ==2.0, + amazonka-opensearchserverless ==2.0, + amazonka-opsworks ==2.0, + amazonka-opsworks-cm ==2.0, + amazonka-outposts ==2.0, + amazonka-panorama ==2.0, + amazonka-personalize ==2.0, + amazonka-personalize-events ==2.0, + amazonka-personalize-runtime ==2.0, + amazonka-pi ==2.0, + amazonka-pinpoint ==2.0, + amazonka-pinpoint-email ==2.0, + amazonka-pinpoint-sms-voice ==2.0, + amazonka-pinpoint-sms-voice-v2 ==2.0, + amazonka-pipes ==2.0, + amazonka-polly ==2.0, + amazonka-privatenetworks ==2.0, + amazonka-proton ==2.0, + amazonka-qldb ==2.0, + amazonka-qldb-session ==2.0, + amazonka-quicksight ==2.0, + amazonka-ram ==2.0, + amazonka-rbin ==2.0, + amazonka-rds ==2.0, + amazonka-rds-data ==2.0, + amazonka-redshift ==2.0, + amazonka-redshift-data ==2.0, + amazonka-redshift-serverless ==2.0, + amazonka-rekognition ==2.0, + amazonka-resiliencehub ==2.0, + amazonka-resource-explorer-v2 ==2.0, + amazonka-robomaker ==2.0, + amazonka-rolesanywhere ==2.0, + amazonka-route53 ==2.0, + amazonka-route53-domains ==2.0, + amazonka-route53-recovery-cluster ==2.0, + amazonka-route53-recovery-control-config ==2.0, + amazonka-route53-recovery-readiness ==2.0, + amazonka-route53resolver ==2.0, + amazonka-rum ==2.0, + amazonka-s3 ==2.0, + amazonka-s3outposts ==2.0, + amazonka-sagemaker-a2i-runtime ==2.0, + amazonka-sagemaker-edge ==2.0, + amazonka-sagemaker-featurestore-runtime ==2.0, + amazonka-sagemaker-geospatial ==2.0, + amazonka-sagemaker-metrics ==2.0, + amazonka-savingsplans ==2.0, + amazonka-scheduler ==2.0, + amazonka-schemas ==2.0, + amazonka-sdb ==2.0, + amazonka-secretsmanager ==2.0, + amazonka-securityhub ==2.0, + amazonka-securitylake ==2.0, + amazonka-servicecatalog ==2.0, + amazonka-servicecatalog-appregistry ==2.0, + amazonka-service-quotas ==2.0, + amazonka-ses ==2.0, + amazonka-sesv2 ==2.0, + amazonka-shield ==2.0, + amazonka-signer ==2.0, + amazonka-simspaceweaver ==2.0, + amazonka-sms ==2.0, + amazonka-sms-voice ==2.0, + amazonka-snowball ==2.0, + amazonka-snow-device-management ==2.0, + amazonka-sns ==2.0, + amazonka-sqs ==2.0, + amazonka-ssm ==2.0, + amazonka-ssm-contacts ==2.0, + amazonka-ssm-incidents ==2.0, + amazonka-ssm-sap ==2.0, + amazonka-sso ==2.0, + amazonka-sso-admin ==2.0, + amazonka-sso-oidc ==2.0, + amazonka-stepfunctions ==2.0, + amazonka-storagegateway ==2.0, + amazonka-sts ==2.0, + amazonka-support ==2.0, + amazonka-support-app ==2.0, + amazonka-swf ==2.0, + amazonka-synthetics ==2.0, + amazonka-test ==2.0, + amazonka-textract ==2.0, + amazonka-timestream-query ==2.0, + amazonka-timestream-write ==2.0, + amazonka-transfer ==2.0, + amazonka-voice-id ==2.0, + amazonka-waf ==2.0, + amazonka-wafv2 ==2.0, + amazonka-wellarchitected ==2.0, + amazonka-wisdom ==2.0, + amazonka-worklink ==2.0, + amazonka-workmailmessageflow ==2.0, + amazonka-workspaces ==2.0, + amazonka-workspaces-web ==2.0, + amazonka-xray ==2.0, + amqp ==0.22.2, + amqp-utils ==0.6.4.0, + annotated-exception ==0.2.0.5, + annotated-wl-pprint ==0.7.0, + ansi-terminal ==1.0.2, + ansi-terminal-game ==1.9.3.0, + ansi-terminal-types ==0.11.5, + ansi-wl-pprint ==1.0.2, + ANum ==0.2.0.2, + aos-signature ==0.1.1, + apecs ==0.9.6, + apecs-gloss ==0.2.4, + apecs-physics ==0.4.6, + api-field-json-th ==0.1.0.2, + ap-normalize ==0.1.0.1, + appar ==0.1.8, + appendful ==0.1.0.0, + appendful-persistent ==0.1.0.1, + appendmap ==0.1.5, + apply-merge ==0.1.1.0, + apply-refact ==0.13.0.0, + apportionment ==0.0.0.4, + approximate ==0.3.5, + approximate-equality ==1.1.0.2, + arbor-lru-cache ==0.1.1.1, + arithmoi ==0.13.0.0, + array installed, + array-memoize ==0.6.0, + arrow-extras ==0.1.0.1, + arrows ==0.4.4.2, + ascii ==1.7.0.1, + ascii-case ==1.0.1.3, + ascii-caseless ==0.0.0.1, + ascii-char ==1.0.1.0, + ascii-group ==1.0.0.17, + ascii-numbers ==1.2.0.1, + ascii-predicates ==1.0.1.3, + ascii-progress ==0.3.3.0, + ascii-superset ==1.3.0.1, + ascii-th ==1.2.0.1, + asn1-encoding ==0.9.6, + asn1-parse ==0.9.5, + asn1-types ==0.3.4, + assert-failure ==0.1.3.0, + assoc ==1.1.1, + astro ==0.4.3.0, + async ==2.2.5, + async-extra ==0.2.0.0, + async-pool ==0.9.2, + async-refresh ==0.3.0.0, + async-refresh-tokens ==0.4.0.0, + atom-basic ==0.2.5, + atom-conduit ==0.9.0.1, + atomic-counter ==0.1.2.1, + atomic-primops ==0.8.8, + atomic-write ==0.2.0.7, + attoparsec ==0.14.4, + attoparsec-aeson ==2.1.0.0, + attoparsec-base64 ==0.0.0, + attoparsec-binary ==0.2, + attoparsec-data ==1.0.5.4, + attoparsec-expr ==0.1.1.2, + attoparsec-framer ==0.1.0.4, + attoparsec-iso8601 ==1.1.1.0, + attoparsec-path ==0.0.0.1, + attoparsec-run ==0.0.2.0, + attoparsec-time ==1.0.3.1, + attoparsec-uri ==0.0.9, + audacity ==0.0.2.2, + authenticate ==1.3.5.2, + authenticate-oauth ==1.7, + autodocodec ==0.2.3.0, + autodocodec-openapi3 ==0.2.1.1, + autodocodec-schema ==0.1.0.4, + autodocodec-yaml ==0.2.0.3, + autoexporter ==2.0.0.12, + auto-update ==0.1.6, + avro ==0.6.2.1, + aws ==0.24.1, + aws-cloudfront-signed-cookies ==0.2.0.12, + aws-sns-verify ==0.0.0.3, + aws-xray-client ==0.1.0.2, + aws-xray-client-persistent ==0.1.0.5, + aws-xray-client-wai ==0.1.0.2, + backprop ==0.2.6.5, + backtracking ==0.1.0, + bank-holidays-england ==0.2.0.9, + barbies ==2.0.5.0, + barrier ==0.1.1, + base installed, + base16 ==1.0, + base16-bytestring ==1.0.2.0, + base32 ==0.4, + base32string ==0.9.1, + base58-bytestring ==0.1.0, + base58string ==0.10.0, + base64 ==0.4.2.4, + base64-bytestring ==1.2.1.0, + base64-bytestring-type ==1.0.1, + base64-string ==0.2, + base-compat ==0.13.1, + base-compat-batteries ==0.13.1, + basement ==0.0.16, + base-orphans ==0.9.2, + base-prelude ==1.6.1.1, + base-unicode-symbols ==0.2.4.2, + basic-prelude ==0.7.0, + battleship-combinatorics ==0.0.1, + bazel-runfiles ==0.12, + bbdb ==0.8, + bcp47 ==0.2.0.6, + bcp47-orphans ==0.1.0.6, + bcrypt ==0.0.11, + beam-core ==0.10.1.0, + bech32 ==1.1.7, + bech32-th ==1.1.7, + benchpress ==0.2.2.23, + bencode ==0.6.1.1, + benri-hspec ==0.1.0.3, + between ==0.11.0.0, + bibtex ==0.1.0.7, + bifunctor-classes-compat ==0.1, + bifunctors ==5.6.2, + bimap ==0.5.0, + bimaps ==0.1.0.2, + bin ==0.1.3, + binance-exports ==0.1.2.0, + binary installed, + binary-conduit ==1.3.1, + binaryen ==0.0.6.0, + binary-generic-combinators ==0.4.4.0, + binary-ieee754 ==0.1.0.0, + binary-instances ==1.0.4, + binary-list ==1.1.1.2, + binary-orphans ==1.0.5, + binary-parser ==0.5.7.6, + binary-search ==2.0.0, + binary-shared ==0.8.3, + binary-tagged ==0.3.1, + bindings-DSL ==1.0.25, + bindings-GLFW ==3.3.9.2, + bindings-libzip ==1.0.1, + bindings-uname ==0.1, + BiobaseEnsembl ==0.2.0.1, + BiobaseNewick ==0.0.0.2, + bitarray ==0.0.1.1, + bits ==0.6, + bitset-word8 ==0.1.1.2, + bitvec ==1.1.5.0, + bitwise ==1.0.0.1, + bitwise-enum ==1.0.1.2, + blake2 ==0.3.0.1, + Blammo ==1.1.3.0, + blank-canvas ==0.7.4, + blanks ==0.5.0, + blas-carray ==0.1.0.2, + blas-comfort-array ==0.0.0.3, + blas-ffi ==0.1, + blas-hs ==0.1.1.0, + blaze-bootstrap ==0.1.0.1, + blaze-builder ==0.4.2.3, + blaze-colonnade ==1.2.3.0, + blaze-html ==0.9.2.0, + blaze-markup ==0.8.3.0, + blaze-svg ==0.3.7, + blaze-textual ==0.2.3.1, + bloodhound ==0.21.0.0, + bloomfilter ==2.0.1.2, + bm ==0.2.0.0, + bmp ==1.2.6.4, + bnb-staking-csvs ==0.2.2.0, + BNFC ==2.9.5, + BNFC-meta ==0.6.1, + board-games ==0.4, + bodhi ==0.1.0, + boltzmann-samplers ==0.1.1.0, + Boolean ==0.2.4, + boolsimplifier ==0.1.8, + boomerang ==1.4.9.3, + boomwhacker ==0.0.1, + bordacount ==0.1.0.0, + boring ==0.2.2, + bound ==2.0.7, + BoundedChan ==1.0.3.0, + bounded-qsem ==0.1.0.2, + bounded-queue ==1.0.0, + boundingboxes ==0.2.3, + box ==0.9.3.1, + boxes ==0.1.5, + breakpoint ==0.1.4.0, + brick ==2.1.1, + broadcast-chan ==0.2.1.2, + brotli ==0.0.0.2, + brotli-streams ==0.0.0.0, + bsb-http-chunked ==0.0.0.4, + bson ==0.4.0.1, + bson-lens ==0.1.1, + btrfs ==0.2.1.0, + buffer-builder ==0.2.4.8, + buffer-pipe ==0.0, + bugsnag ==1.1.0.0, + bugsnag-haskell ==0.0.4.4, + bugsnag-hs ==0.2.0.12, + bugsnag-wai ==1.0.0.1, + bugsnag-yesod ==1.0.1.0, + bugzilla-redhat ==1.0.1.1, + burrito ==2.0.1.10, + bv ==0.5, + bv-little ==1.3.2, + bv-sized ==1.0.5, + byteable ==0.1.1, + bytebuild ==0.3.16.2, + byte-count-reader ==0.10.1.11, + bytedump ==1.0, + bytehash ==0.1.1.0, + byte-order ==0.1.3.1, + byteorder ==1.0.4, + bytes ==0.17.3, + byteset ==0.1.1.1, + byteslice ==0.2.13.2, + bytesmith ==0.3.11.1, + bytestring installed, + bytestring-builder ==0.10.8.2.0, + bytestring-conversion ==0.3.2, + bytestring-lexing ==0.5.0.14, + bytestring-strict-builder ==0.4.5.7, + bytestring-to-vector ==0.3.0.1, + bytestring-tree-builder ==0.2.7.12, + bytestring-trie ==0.2.7.5, + bz2 ==1.0.1.2, + bzip2-clib ==1.0.8, + bzlib ==0.5.2.0, + bzlib-conduit ==0.3.0.3, + c14n ==0.1.0.3, + c2hs ==0.28.8, + Cabal installed, + cabal2nix ==2.19.1, + cabal2spec ==2.7.1, + cabal-appimage ==0.4.0.5, + cabal-clean ==0.2.20230609, + cabal-debian ==5.2.3, + cabal-doctest ==1.0.10, + cabal-file ==0.1.1, + cabal-install ==3.10.3.0, + cabal-install-solver ==3.10.3.0, + cabal-plan ==0.7.3.0, + cabal-rpm ==2.1.5, + cabal-sort ==0.1.2, + Cabal-syntax installed, + cache ==0.1.3.0, + cached-json-file ==0.1.1, + cacophony ==0.10.1, + cairo ==0.13.11.0, + cairo-image ==0.1.0.3, + calendar-recycling ==0.0.0.1, + call-alloy ==0.4.1.1, + calligraphy ==0.1.6, + call-plantuml ==0.0.1.3, + call-stack ==0.4.0, + can-i-haz ==0.3.1.1, + ca-province-codes ==1.0.0.0, + cardano-coin-selection ==1.0.1, + carray ==0.1.6.8, + casa-client ==0.0.2, + casa-types ==0.0.2, + cased ==0.1.0.0, + case-insensitive ==1.2.1.0, + cases ==0.1.4.3, + casing ==0.1.4.1, + cassava ==0.5.3.2, + cassava-conduit ==0.6.6, + cassava-megaparsec ==2.0.4, + cast ==0.1.0.2, + cborg ==0.2.10.0, + cborg-json ==0.2.6.0, + cdar-mBound ==0.1.0.4, + c-enum ==0.1.1.3, + cereal ==0.5.8.3, + cereal-conduit ==0.8.0, + cereal-text ==0.1.0.2, + cereal-unordered-containers ==0.1.0.1, + cereal-vector ==0.2.0.1, + cfenv ==0.1.0.0, + cgi ==3001.5.0.1, + chan ==0.0.4.1, + ChannelT ==0.0.0.7, + character-cases ==0.1.0.6, + charset ==0.3.10, + charsetdetect-ae ==1.1.0.4, + Chart ==1.9.5, + Chart-cairo ==1.9.4.1, + Chart-diagrams ==1.9.5.1, + chart-svg ==0.5.2.0, + ChasingBottoms ==1.3.1.15, + check-email ==1.0.2, + checkers ==0.6.0, + checksum ==0.0.0.1, + chimera ==0.3.4.0, + choice ==0.2.4.1, + chronologique ==0.3.1.3, + chronos ==1.1.6.1, + chronos-bench ==0.2.0.2, + chunked-data ==0.3.1, + cipher-aes ==0.2.11, + cipher-camellia ==0.0.2, + cipher-rc4 ==0.1.4, + circle-packing ==0.1.0.6, + circular ==0.4.0.3, + citeproc ==0.8.1.1, + clash-prelude ==1.8.1, + classy-prelude ==1.5.0.3, + classy-prelude-conduit ==1.5.0, + classy-prelude-yesod ==1.5.0, + clay ==0.14.0, + cleff ==0.3.3.0, + clientsession ==0.9.2.0, + Clipboard ==2.3.2.0, + clock ==0.8.4, + closed ==0.2.0.2, + clumpiness ==0.17.0.2, + ClustalParser ==1.3.0, + cmark ==0.6.1, + cmark-gfm ==0.2.6, + cmark-lucid ==0.1.0.0, + cmdargs ==0.10.22, + codec-beam ==0.2.0, + code-conjure ==0.5.14, + code-page ==0.2.1, + coinor-clp ==0.0.0.2, + cointracking-imports ==0.1.0.2, + collect-errors ==0.1.6.0, + co-log ==0.6.1.0, + co-log-concurrent ==0.5.1.0, + co-log-core ==0.3.2.2, + co-log-polysemy ==0.0.1.5, + colonnade ==1.2.0.2, + Color ==0.3.3, + colorful-monoids ==0.2.1.3, + colorize-haskell ==1.0.1, + colour ==2.3.6, + colourista ==0.1.0.2, + columnar ==1.0.0.0, + combinatorial ==0.1.1, + comfort-array ==0.5.5, + comfort-array-shape ==0.0, + comfort-blas ==0.0.3, + comfort-fftw ==0.0.0.1, + comfort-glpk ==0.1, + comfort-graph ==0.0.4, + commonmark ==0.2.6, + commonmark-extensions ==0.2.5.5, + commonmark-pandoc ==0.2.2.1, + commutative ==0.0.2, + commutative-semigroups ==0.1.1.0, + comonad ==5.0.8, + compact ==0.2.0.0, + compactmap ==0.1.4.4, + companion ==0.1.0, + compdata ==0.13.1, + compensated ==0.8.3, + compiler-warnings ==0.1.0, + componentm ==0.0.0.2, + componentm-devel ==0.0.0.2, + composable-associations ==0.1.0.0, + composite-base ==0.8.2.1, + composite-binary ==0.8.2.2, + composite-hashable ==0.8.2.2, + composite-tuple ==0.1.2.0, + composite-xstep ==0.1.0.0, + composition ==1.0.2.2, + composition-extra ==2.1.0, + composition-prelude ==3.0.1.0, + concise ==0.1.0.1, + concurrency ==1.11.0.3, + concurrent-extra ==0.7.0.12, + concurrent-output ==1.10.21, + concurrent-split ==0.0.1.1, + concurrent-supply ==0.1.8, + cond ==0.5.1, + conduit ==1.3.6, + conduit-aeson ==0.1.1.0, + conduit-combinators ==1.3.0, + conduit-concurrent-map ==0.1.3, + conduit-extra ==1.3.6, + conduit-parse ==0.2.1.1, + conduit-zstd ==0.0.2.0, + conferer ==1.1.0.0, + conferer-aeson ==1.1.0.2, + conferer-warp ==1.1.0.1, + config-ini ==0.2.7.0, + configuration-tools ==0.7.0, + configurator ==0.3.0.0, + configurator-export ==0.1.0.1, + configurator-pg ==0.2.10, + config-value ==0.8.3, + constraints ==0.14.2, + constraints-extras ==0.4.0.1, + constraint-tuples ==0.1.2, + construct ==0.3.1.2, + containers installed, + context ==0.2.1.0, + context-http-client ==0.2.0.2, + context-resource ==0.2.0.2, + context-wai-middleware ==0.2.0.2, + contiguous ==0.6.4.2, + contravariant ==1.5.5, + contravariant-extras ==0.3.5.4, + control-bool ==0.2.1, + control-dsl ==0.2.1.3, + control-monad-free ==0.6.2, + control-monad-omega ==0.3.2, + convertible ==1.1.1.1, + cookie ==0.4.6, + copilot ==3.19.1, + copilot-c99 ==3.19.1, + copilot-core ==3.19.1, + copilot-interpreter ==3.19.1, + copilot-language ==3.19.1, + copilot-libraries ==3.19.1, + copilot-prettyprinter ==3.19.1, + copilot-theorem ==3.19.1, + copr-api ==0.2.0, + core-data ==0.3.9.1, + core-program ==0.7.0.0, + core-telemetry ==0.2.9.4, + core-text ==0.3.8.1, + countable ==1.2, + country ==0.2.4.2, + covariance ==0.2.0.1, + cpphs ==1.20.9.1, + cpu ==0.1.2, + cpuinfo ==0.1.0.2, + cql ==4.0.4, + cql-io ==1.1.1, + crackNum ==3.4, + crc32c ==0.1.0, + credential-store ==0.1.2, + criterion ==1.6.3.0, + criterion-measurement ==0.2.2.0, + crypto-api ==0.13.3, + crypto-api-tests ==0.3, + crypto-cipher-tests ==0.0.11, + crypto-cipher-types ==0.0.9, + cryptocompare ==0.1.2, + cryptohash ==0.11.9, + cryptohash-cryptoapi ==0.1.4, + cryptohash-md5 ==0.11.101.0, + cryptohash-sha1 ==0.11.101.0, + cryptohash-sha256 ==0.11.102.1, + cryptohash-sha512 ==0.11.102.0, + crypton ==0.34, + crypton-conduit ==0.2.3, + crypton-connection ==0.3.2, + cryptonite ==0.30, + cryptonite-conduit ==0.2.2, + cryptonite-openssl ==0.7, + crypton-x509 ==1.7.7, + crypton-x509-store ==1.6.9, + crypton-x509-system ==1.6.7, + crypton-x509-validation ==1.6.12, + crypto-pubkey-types ==0.4.3, + crypto-random-api ==0.2.0, + cryptostore ==0.3.1.0, + crypt-sha512 ==0, + csp ==1.4.0, + css-syntax ==0.1.0.2, + css-text ==0.1.3.0, + c-struct ==0.1.3.0, + csv ==0.1.2, + ctrie ==0.2, + cubicbezier ==0.6.0.7, + cubicspline ==0.1.2, + cuda ==0.11.0.1, + cue-sheet ==2.0.2, + curl ==1.3.8, + currency ==0.2.0.0, + currycarbon ==0.3.0.1, + cursor ==0.3.2.0, + cursor-brick ==0.1.0.1, + cursor-fuzzy-time ==0.0.0.0, + cursor-gen ==0.4.0.0, + cutter ==0.0, + cyclotomic ==1.1.2, + data-accessor ==0.2.3.1, + data-accessor-mtl ==0.2.0.5, + data-accessor-transformers ==0.2.1.8, + data-array-byte ==0.1.0.1, + data-binary-ieee754 ==0.4.4, + data-bword ==0.1.0.2, + data-checked ==0.3, + data-clist ==0.2, + data-default ==0.7.1.1, + data-default-class ==0.1.2.0, + data-default-instances-base ==0.1.0.1, + data-default-instances-bytestring ==0.0.1, + data-default-instances-case-insensitive ==0.0.1, + data-default-instances-containers ==0.0.1, + data-default-instances-dlist ==0.0.1, + data-default-instances-old-locale ==0.0.1, + data-default-instances-unordered-containers ==0.0.1, + data-default-instances-vector ==0.0.1, + data-diverse ==4.7.1.0, + datadog ==0.3.0.0, + data-dword ==0.3.2.1, + data-endian ==0.1.1, + data-fix ==0.3.4, + data-forest ==0.1.0.12, + data-functor-logistic ==0.0, + data-has ==0.4.0.0, + data-hash ==0.2.0.1, + data-interval ==2.1.2, + data-inttrie ==0.1.4, + data-lens-light ==0.1.2.4, + data-memocombinators ==0.5.1, + data-msgpack ==0.0.13, + data-msgpack-types ==0.0.3, + data-or ==1.0.0.7, + data-ordlist ==0.4.7.0, + data-ref ==0.1, + data-reify ==0.6.3, + data-serializer ==0.3.5, + data-sketches ==0.3.1.0, + data-sketches-core ==0.1.0.0, + data-textual ==0.3.0.3, + dataurl ==0.1.0.0, + DAV ==1.3.4, + dbcleaner ==0.1.3, + DBFunctor ==0.1.2.1, + dbus ==1.3.3, + dbus-hslogger ==0.1.0.1, + debian ==4.0.5, + debian-build ==0.10.2.1, + debug-trace-var ==0.2.0, + dec ==0.0.6, + Decimal ==0.5.2, + declarative ==0.5.4, + deepseq installed, + deepseq-generics ==0.2.0.0, + deferred-folds ==0.9.18.6, + dejafu ==2.4.0.5, + dense-linear-algebra ==0.1.0.0, + dependent-map ==0.4.0.0, + dependent-sum ==0.7.2.0, + dependent-sum-template ==0.1.1.1, + depq ==0.4.2, + deque ==0.4.4.1, + deriveJsonNoPrefix ==0.1.0.1, + derive-storable ==0.3.1.0, + derive-topdown ==0.0.3.0, + deriving-aeson ==0.2.9, + deriving-compat ==0.6.6, + deriving-trans ==0.9.1.0, + detour-via-sci ==1.0.0, + df1 ==0.4.3, + dhall ==1.42.1, + dhall-bash ==1.0.41, + di ==1.3, + diagrams ==1.4.1, + diagrams-builder ==0.8.0.6, + diagrams-cairo ==1.4.2.1, + diagrams-canvas ==1.4.1.2, + diagrams-contrib ==1.4.5.1, + diagrams-core ==1.5.1.1, + diagrams-gtk ==1.4, + diagrams-html5 ==1.4.2, + diagrams-lib ==1.4.6.2, + diagrams-postscript ==1.5.1.1, + diagrams-rasterific ==1.4.2.3, + diagrams-solve ==0.1.3, + diagrams-svg ==1.4.3.2, + dice ==0.1.1, + di-core ==1.0.4, + dictionary-sharing ==0.1.0.0, + di-df1 ==1.2.1, + Diff ==0.4.1, + diff-loc ==0.1.0.0, + digest ==0.0.2.1, + digits ==0.3.1, + di-handle ==1.0.1, + dimensional ==1.5, + di-monad ==1.3.5, + directory installed, + directory-ospath-streaming ==0.1.0.1, + directory-tree ==0.12.1, + direct-sqlite ==2.3.29, + dirichlet ==0.1.0.7, + discount ==0.1.1, + discover-instances ==0.1.0.0, + discrimination ==0.5, + disk-free-space ==0.1.0.1, + distributed-closure ==0.5.0.0, + distributed-static ==0.3.11, + distribution-nixpkgs ==1.7.1, + distribution-opensuse ==1.1.4, + distributive ==0.6.2.1, + diversity ==0.8.1.0, + djinn-lib ==0.0.1.4, + dl-fedora ==1.0, + dlist ==1.0, + dlist-instances ==0.1.1.1, + dlist-nonempty ==0.1.3, + dns ==4.2.0, + dockerfile ==0.2.0, + doclayout ==0.4.0.1, + doctemplates ==0.11.0.1, + doctest ==0.22.6, + doctest-discover ==0.2.0.0, + doctest-driver-gen ==0.3.0.8, + doctest-exitcode-stdio ==0.0, + doctest-extract ==0.1.2, + doctest-lib ==0.1.1.1, + doctest-parallel ==0.3.1.1, + doldol ==0.4.1.2, + do-list ==1.0.1, + domain ==0.1.1.5, + domain-aeson ==0.1.1.2, + domain-cereal ==0.1.0.1, + domain-core ==0.1.0.4, + domain-optics ==0.1.0.4, + do-notation ==0.1.0.2, + dot ==0.3, + dotenv ==0.11.0.2, + dotgen ==0.4.3, + dotnet-timespan ==0.0.1.0, + double-conversion ==2.0.5.0, + DPutils ==0.1.1.0, + drawille ==0.1.3.0, + drifter ==0.3.0, + drifter-postgresql ==0.2.1, + drifter-sqlite ==0.1.0.0, + dsp ==0.2.5.2, + dual-tree ==0.2.3.1, + dublincore-xml-conduit ==0.1.0.3, + duration ==0.2.0.0, + dvorak ==0.1.0.0, + dynamic-state ==0.3.1, + dyre ==0.9.2, + eap ==0.9.0.2, + Earley ==0.13.0.1, + easy-file ==0.2.5, + easy-logger ==0.1.0.7, + Ebnf2ps ==1.0.15, + echo ==0.1.4, + ecstasy ==0.2.1.0, + ed25519 ==0.0.5.0, + edit-distance ==0.2.2.1, + edit-distance-vector ==1.0.0.4, + editor-open ==0.6.0.0, + effectful ==2.3.1.0, + effectful-core ==2.3.1.0, + effectful-plugin ==1.1.0.3, + effectful-th ==1.0.0.1, + egison-pattern-src ==0.2.1.2, + either ==5.0.2, + either-unwrap ==1.1, + ekg-core ==0.1.1.7, + elerea ==2.9.0, + elf ==0.31, + eliminators ==0.9.3, + elm-bridge ==0.8.4, + elm-core-sources ==1.0.0, + elm-export ==0.6.0.1, + elm-street ==0.2.2.1, + elynx ==0.7.2.2, + elynx-markov ==0.7.2.2, + elynx-nexus ==0.7.2.2, + elynx-seq ==0.7.2.2, + elynx-tools ==0.7.2.2, + elynx-tree ==0.7.2.2, + emacs-module ==0.2.1, + email-validate ==2.3.2.21, + emojis ==0.1.4.1, + enclosed-exceptions ==1.0.3, + ENIG ==0.0.1.0, + entropy ==0.4.1.10, + enummapset ==0.7.3.0, + enumset ==0.1, + enum-subset-generate ==0.1.0.1, + enum-text ==0.5.3.0, + envelope ==0.2.2.0, + envparse ==0.5.0, + envy ==2.1.3.0, + epub-metadata ==5.2, + eq ==4.3, + equal-files ==0.0.5.4, + equational-reasoning ==0.7.0.3, + equivalence ==0.4.1, + erf ==2.0.0.0, + errata ==0.4.0.2, + error ==1.0.0.0, + errorcall-eq-instance ==0.3.0, + error-or ==0.3.0, + error-or-utils ==0.2.0, + errors ==2.3.0, + errors-ext ==0.4.2, + ersatz ==0.5, + esqueleto ==3.5.11.2, + event-list ==0.1.3, + every ==0.0.1, + evm-opcodes ==0.1.2, + exact-combinatorics ==0.2.0.11, + exact-pi ==0.5.0.2, + exception-hierarchy ==0.1.0.11, + exception-mtl ==0.4.0.2, + exceptions installed, + exception-transformers ==0.4.0.12, + exception-via ==0.2.0.0, + executable-hash ==0.2.0.4, + executable-path ==0.0.3.1, + exinst ==0.9, + exit-codes ==1.0.0, + exomizer ==1.0.0, + exon ==1.6.1.1, + expiring-cache-map ==0.0.6.1, + explainable-predicates ==0.1.2.4, + explicit-exception ==0.2, + exp-pairs ==0.2.1.0, + express ==1.0.16, + extended-reals ==0.2.4.0, + extensible ==0.9.1, + extensible-effects ==5.0.0.1, + extensible-exceptions ==0.1.1.4, + extra ==1.7.16, + extractable-singleton ==0.0.1, + extra-data-yj ==0.1.0.0, + extrapolate ==0.4.6, + fail ==4.9.0.0, + FailT ==0.1.2.0, + fakedata ==1.0.3, + fakedata-parser ==0.1.0.0, + fakedata-quickcheck ==0.2.0, + fakefs ==0.3.0.2, + fakepull ==0.3.0.2, + faktory ==1.1.3.0, + falsify ==0.2.0, + fasta ==0.10.4.2, + fast-digits ==0.3.2.0, + fast-logger ==3.2.3, + fast-math ==1.0.2, + fast-myers-diff ==0.0.1, + fb ==2.1.1.1, + fcf-family ==0.2.0.1, + fclabels ==2.0.5.1, + fdo-notify ==0.3.1, + feature-flags ==0.1.0.1, + fedora-dists ==2.1.1, + fedora-haskell-tools ==1.1, + FenwickTree ==0.1.2.1, + fft ==0.1.8.7, + fftw-ffi ==0.1, + fgl ==5.8.2.0, + fgl-arbitrary ==0.2.0.6, + fields-json ==0.4.0.0, + file-embed ==0.0.16.0, + file-embed-lzma ==0.0.1, + file-io ==0.1.4, + filelock ==0.1.1.7, + filemanip ==0.3.6.3, + file-modules ==0.1.2.4, + filepath installed, + filepath-bytestring ==1.4.100.3.2, + file-path-th ==0.1.0.0, + filepattern ==0.1.3, + fileplow ==0.1.0.0, + filter-logger ==0.6.0.0, + filtrable ==0.1.6.0, + fin ==0.3, + FindBin ==0.0.5, + fingertree ==0.1.5.0, + finite-typelits ==0.1.6.0, + first-class-families ==0.8.1.0, + fits-parse ==0.3.6, + fitspec ==0.4.10, + fixed ==0.3, + fixed-length ==0.2.3.1, + fixed-vector ==1.2.3.0, + fixed-vector-hetero ==0.6.1.1, + fix-whitespace ==0.1, + flac ==0.2.1, + flac-picture ==0.1.3, + flags-applicative ==0.1.0.3, + flat ==0.6, + flatparse ==0.5.1.0, + flay ==0.4, + flexible-defaults ==0.0.3, + FloatingHex ==0.5, + floatshow ==0.2.4, + flow ==2.0.0.5, + flush-queue ==1.0.0, + fmlist ==0.9.4, + fmt ==0.6.3.0, + fn ==0.3.0.2, + focus ==1.0.3.2, + focuslist ==0.1.1.0, + foldable1-classes-compat ==0.1, + fold-debounce ==0.2.0.12, + foldl ==1.4.17, + folds ==0.7.8, + FontyFruity ==0.5.3.5, + force-layout ==0.4.0.6, + foreign-store ==0.2.1, + ForestStructures ==0.0.1.1, + forkable-monad ==0.2.0.3, + forma ==1.2.0, + formatn ==0.3.0.1, + format-numbers ==0.1.0.1, + formatting ==7.2.0, + foundation ==0.0.30, + fourmolu ==0.14.0.0, + Frames ==0.7.4.2, + free ==5.2, + free-categories ==0.2.0.2, + freenect ==1.2.1, + freer-par-monad ==0.1.0.0, + freetype2 ==0.2.0, + free-vl ==0.1.4, + friday ==0.2.3.2, + friday-juicypixels ==0.1.2.4, + friendly-time ==0.4.1, + frisby ==0.2.5, + from-sum ==0.2.3.0, + frontmatter ==0.1.0.2, + fsnotify ==0.4.1.0, + funcmp ==1.9, + function-builder ==0.3.0.1, + functor-classes-compat ==2.0.0.2, + fused-effects ==1.1.2.3, + fusion-plugin ==0.2.7, + fusion-plugin-types ==0.1.0, + fuzzcheck ==0.1.1, + fuzzy ==0.1.1.0, + fuzzy-dates ==0.1.1.2, + fuzzyset ==0.3.2, + fuzzy-time ==0.2.0.3, + gauge ==0.2.5, + gd ==3000.7.3, + gdp ==0.0.3.0, + gemini-exports ==0.1.0.0, + general-games ==1.1.1, + generically ==0.1.1, + generic-arbitrary ==1.0.1, + generic-constraints ==1.1.1.1, + generic-data ==1.1.0.0, + generic-data-surgery ==0.3.0.0, + generic-deriving ==1.14.5, + generic-functor ==1.1.0.0, + generic-lens ==2.2.2.0, + generic-lens-core ==2.2.1.0, + generic-monoid ==0.1.0.1, + generic-optics ==2.2.1.0, + GenericPretty ==1.2.2, + generic-random ==1.5.0.1, + generics-eot ==0.4.0.1, + generics-sop ==0.5.1.3, + generics-sop-lens ==0.2.0.1, + genvalidity ==1.1.1.0, + genvalidity-aeson ==1.0.0.1, + genvalidity-appendful ==0.1.0.0, + genvalidity-bytestring ==1.0.0.1, + genvalidity-case-insensitive ==0.0.0.1, + genvalidity-containers ==1.0.0.2, + genvalidity-criterion ==1.1.0.0, + genvalidity-hspec ==1.0.0.3, + genvalidity-hspec-aeson ==1.0.0.0, + genvalidity-hspec-binary ==1.0.0.0, + genvalidity-hspec-cereal ==1.0.0.0, + genvalidity-hspec-hashable ==1.0.0.1, + genvalidity-hspec-optics ==1.0.0.0, + genvalidity-hspec-persistent ==1.0.0.0, + genvalidity-mergeful ==0.3.0.1, + genvalidity-mergeless ==0.3.0.0, + genvalidity-network-uri ==0.0.0.0, + genvalidity-path ==1.0.0.1, + genvalidity-persistent ==1.0.0.2, + genvalidity-property ==1.0.0.0, + genvalidity-scientific ==1.0.0.0, + genvalidity-sydtest ==1.0.0.0, + genvalidity-sydtest-aeson ==1.0.0.0, + genvalidity-sydtest-hashable ==1.0.0.1, + genvalidity-sydtest-lens ==1.0.0.0, + genvalidity-sydtest-persistent ==1.0.0.0, + genvalidity-text ==1.0.0.1, + genvalidity-time ==1.0.0.1, + genvalidity-typed-uuid ==0.1.0.1, + genvalidity-unordered-containers ==1.0.0.1, + genvalidity-uuid ==1.0.0.1, + genvalidity-vector ==1.0.0.0, + geodetics ==0.1.2, + geojson ==4.1.1, + getopt-generics ==0.13.1.0, + ghc installed, + ghc-bignum installed, + ghc-bignum-orphans ==0.1.1, + ghc-boot installed, + ghc-boot-th installed, + ghc-byteorder ==4.11.0.0.10, + ghc-check ==0.5.0.8, + ghc-compact ==0.1.0.0, + ghc-core ==0.5.6, + ghc-events ==0.19.0.1, + ghc-exactprint ==1.7.1.0, + ghc-heap installed, + ghc-hs-meta ==0.1.4.0, + ghcid ==0.8.9, + ghci-hexcalc ==0.1.1.0, + ghcjs-codemirror ==0.0.0.2, + ghcjs-perch ==0.3.3.3, + ghc-lib ==9.6.6.20240701, + ghc-lib-parser ==9.6.6.20240701, + ghc-lib-parser-ex ==9.6.0.2, + ghc-parser ==0.2.6.0, + ghc-paths ==0.1.0.12, + ghc-prim installed, + ghc-syntax-highlighter ==0.0.10.0, + ghc-tcplugins-extra ==0.4.6, + ghc-trace-events ==0.1.2.9, + ghc-typelits-extra ==0.4.7, + ghc-typelits-knownnat ==0.7.12, + ghc-typelits-natnormalise ==0.7.10, + ghc-typelits-presburger ==0.7.4.0, + ghost-buster ==0.1.1.0, + ghostscript-parallel ==0.0.1, + gi-atk ==2.0.28, + gi-cairo ==1.0.30, + gi-cairo-render ==0.1.2, + gi-dbusmenu ==0.4.14, + gi-dbusmenugtk3 ==0.4.15, + gi-freetype2 ==2.0.5, + gi-gdk ==3.0.29, + gi-gdkpixbuf ==2.0.32, + gi-gdkx11 ==3.0.16, + gi-gio ==2.0.35, + gi-glib ==2.0.30, + gi-gmodule ==2.0.6, + gi-gobject ==2.0.31, + gi-graphene ==1.0.8, + gi-gtk ==3.0.43, + gi-gtk-hs ==0.3.16, + gi-gtksource ==3.0.29, + gi-harfbuzz ==0.0.10, + gi-javascriptcore ==4.0.28, + ginger ==0.10.5.2, + gio ==0.13.11.0, + gi-pango ==1.0.30, + gi-soup ==2.4.29, + githash ==0.1.7.0, + github ==0.29, + github-release ==2.0.0.11, + github-rest ==1.1.4, + github-types ==0.2.1, + github-webhooks ==0.17.0, + git-lfs ==1.2.2, + gitlib ==3.1.3, + git-mediate ==1.0.9, + gitrev ==1.3.1, + gi-vte ==2.91.33, + gi-webkit2 ==4.0.31, + gi-xlib ==2.0.14, + gl ==0.9, + glabrous ==2.0.6.3, + glasso ==0.1.0, + GLFW-b ==3.3.9.1, + glib ==0.13.11.0, + glib-stopgap ==0.1.0.0, + Glob ==0.10.2, + glob-posix ==0.2.0.1, + gloss ==1.13.2.2, + gloss-algorithms ==1.13.0.3, + gloss-rendering ==1.13.1.2, + glpk-headers ==0.5.1, + GLURaw ==2.0.0.5, + GLUT ==2.7.0.16, + gmail-simple ==0.1.0.6, + gnuplot ==0.5.7, + goldplate ==0.2.1.1, + google-isbn ==1.0.3, + gopher-proxy ==0.1.1.3, + gpolyline ==0.1.0.1, + graph-core ==0.3.0.0, + graphite ==0.10.0.1, + graphql ==1.2.0.3, + graphql-client ==1.2.4, + graphs ==0.7.2, + graphula ==2.1.0.0, + graphviz ==2999.20.2.0, + graph-wrapper ==0.2.6.0, + gravatar ==0.8.1, + gridtables ==0.1.0.0, + groom ==0.1.2.1, + group-by-date ==0.1.0.5, + groups ==0.5.3, + gtk ==0.15.9, + gtk2hs-buildtools ==0.13.11.0, + gtk3 ==0.15.9, + gtk-strut ==0.1.3.2, + guarded-allocation ==0.0.1, + H ==1.0.0, + hackage-cli ==0.1.0.2, + hackage-db ==2.1.3, + hackage-security ==0.6.2.4, + haddock-library ==1.11.0, + haha ==0.3.1.1, + hakyll ==4.16.2.2, + hakyllbars ==1.0.1.0, + hal ==1.0.1, + half ==0.3.1, + hall-symbols ==0.1.0.6, + hamlet ==1.2.0, + hamtsolo ==1.0.4, + HandsomeSoup ==0.4.2, + handwriting ==0.1.0.3, + happstack-jmacro ==7.0.12.6, + happstack-server ==7.8.0.2, + happstack-server-tls ==7.2.1.6, + happy ==1.20.1.1, + happy-meta ==0.2.1.0, + HasBigDecimal ==0.2.0.0, + hashable ==1.4.4.0, + hashids ==1.1.1.0, + hashing ==0.1.1.0, + hashmap ==1.3.3, + hashtables ==1.3.1, + haskeline installed, + haskell-gi ==0.26.11, + haskell-gi-base ==0.26.8, + haskell-gi-overloading ==1.0, + haskell-lexer ==1.1.1, + HaskellNet ==0.6.1.2, + haskell-src ==1.0.4.1, + haskell-src-exts ==1.23.1, + haskell-src-exts-simple ==1.23.0.0, + haskell-src-exts-util ==0.2.5, + haskell-src-meta ==0.8.14, + haskintex ==0.8.0.2, + haskoin-core ==1.0.4, + haskoin-node ==1.0.1, + haskoin-store-data ==1.2.5, + hasktags ==0.73.0, + hasql ==1.6.4.4, + hasql-dynamic-statements ==0.3.1.5, + hasql-implicits ==0.1.1.3, + hasql-interpolate ==0.2.2.0, + hasql-listen-notify ==0.1.0.1, + hasql-migration ==0.3.1, + hasql-notifications ==0.2.2.0, + hasql-optparse-applicative ==0.7.1.3, + hasql-pool ==0.10.1, + hasql-th ==0.4.0.22, + hasql-transaction ==1.0.1.4, + has-transformers ==0.1.0.4, + hasty-hamiltonian ==1.3.4, + HaTeX ==3.22.4.2, + HaXml ==1.25.13, + haxr ==3000.11.5.1, + HCodecs ==0.5.2, + hdaemonize ==0.5.7, + HDBC ==2.4.0.4, + HDBC-session ==0.1.2.1, + headed-megaparsec ==0.2.1.3, + heap ==1.0.4, + heaps ==0.4, + heatshrink ==0.1.0.0, + hebrew-time ==0.1.2, + hedgehog ==1.4, + hedgehog-classes ==0.2.5.4, + hedgehog-corpus ==0.2.0, + hedgehog-fn ==1.0, + hedgehog-quickcheck ==0.1.1, + hedis ==0.15.2, + hedn ==0.3.0.4, + hegg ==0.5.0.0, + heist ==1.1.1.2, + here ==1.2.14, + heredoc ==0.2.0.0, + heterocephalus ==1.0.5.7, + hetzner ==0.6.0.0, + hex ==0.2.0, + hexml ==0.3.5, + hexml-lens ==0.2.2, + hexpat ==0.20.13, + hex-text ==0.1.0.9, + hformat ==0.3.3.1, + hfsevents ==0.1.7, + hgal ==2.0.0.3, + hidapi ==0.1.8, + hie-bios ==0.13.1, + hi-file-parser ==0.1.6.0, + hindent ==6.1.1, + hinfo ==0.0.3.0, + hinotify ==0.4.1, + hint ==0.9.0.8, + histogram-fill ==0.9.1.0, + hjsmin ==0.2.1, + hkd-default ==1.1.0.0, + hkgr ==0.4.6, + hledger ==1.32.3, + hledger-iadd ==1.3.20, + hledger-interest ==1.6.6, + hledger-lib ==1.32.3, + hledger-stockquotes ==0.1.3.1, + hledger-web ==1.32.3, + hlibcpuid ==0.2.0, + hlibgit2 ==0.18.0.16, + hlibsass ==0.1.10.1, + hlint ==3.6.1, + hmatrix ==0.20.2, + hmatrix-backprop ==0.1.3.0, + hmatrix-gsl ==0.19.0.1, + hmatrix-gsl-stats ==0.4.1.8, + hmatrix-morpheus ==0.1.1.2, + hmatrix-special ==0.19.0.0, + hmatrix-vector-sized ==0.1.3.0, + hmm-lapack ==0.5.0.1, + HMock ==0.5.1.2, + hmpfr ==0.4.5, + hnix-store-core ==0.7.0.0, + hoauth2 ==2.10.0, + hopenssl ==2.2.5, + hopfli ==0.2.2.1, + horizontal-rule ==0.6.0.0, + hosc ==0.20, + hostname ==1.0, + hostname-validate ==1.0.0, + hourglass ==0.2.12, + hourglass-orphans ==0.1.0.0, + hp2pretty ==0.10, + hpack ==0.36.1, + hpc installed, + hpc-codecov ==0.5.0.0, + hpc-lcov ==1.1.2, + HPDF ==1.6.2, + hpp ==0.6.5, + hpqtypes ==1.11.1.2, + hpqtypes-extras ==1.16.4.4, + hreader ==1.1.1, + hreader-lens ==0.1.3.0, + hruby ==0.5.1.0, + hsass ==0.8.0, + hs-bibutils ==6.10.0.0, + hsc2hs ==0.68.10, + hscolour ==1.25, + hsdns ==1.8, + hse-cpp ==0.2, + hsemail ==2.2.2, + hset ==2.2.0, + HSet ==0.0.2, + hsexif ==0.6.1.10, + hs-GeoIP ==0.3, + hsignal ==0.2.7.5, + hsini ==0.5.2.2, + hsinstall ==2.8, + HSlippyMap ==3.0.1, + hslogger ==1.3.1.1, + hslua ==2.3.1, + hslua-aeson ==2.3.1.1, + hslua-classes ==2.3.1, + hslua-cli ==1.4.3, + hslua-core ==2.3.2, + hslua-list ==1.1.3, + hslua-marshalling ==2.3.1, + hslua-module-doclayout ==1.1.1.2, + hslua-module-path ==1.1.1, + hslua-module-system ==1.1.2, + hslua-module-text ==1.1.1, + hslua-module-version ==1.1.1, + hslua-module-zip ==1.1.3, + hslua-objectorientation ==2.3.1, + hslua-packaging ==2.3.1, + hslua-repl ==0.1.2, + hslua-typing ==0.1.1, + hsndfile ==0.8.0, + hsndfile-vector ==0.5.2, + HsOpenSSL ==0.11.7.8, + HsOpenSSL-x509-system ==0.1.0.4, + hspec ==2.11.9, + hspec-api ==2.11.9, + hspec-attoparsec ==0.1.0.2, + hspec-checkers ==0.1.0.2, + hspec-contrib ==0.5.2, + hspec-core ==2.11.9, + hspec-discover ==2.11.9, + hspec-expectations ==0.8.4, + hspec-expectations-json ==1.0.2.1, + hspec-expectations-lifted ==0.10.0, + hspec-expectations-pretty-diff ==0.7.2.6, + hspec-golden ==0.2.2.0, + hspec-golden-aeson ==0.9.0.0, + hspec-hedgehog ==0.1.1.0, + hspec-junit-formatter ==1.1.2.1, + hspec-leancheck ==0.0.6, + hspec-megaparsec ==2.2.1, + hspec-meta ==2.11.9, + hspec-parsec ==0, + hspec-smallcheck ==0.5.3, + hspec-tmp-proc ==0.5.2.0, + hspec-wai ==0.11.1, + hspec-wai-json ==0.11.0, + hspec-webdriver ==1.2.2, + hs-php-session ==0.0.9.3, + hstatistics ==0.3.1, + HStringTemplate ==0.8.8, + HSvm ==0.1.2.3.32, + HsYAML ==0.2.1.4, + HsYAML-aeson ==0.2.0.1, + hsyslog ==5.0.2, + htaglib ==1.2.1, + HTF ==0.15.0.2, + html ==1.0.1.2, + html-conduit ==1.3.2.2, + html-email-validate ==0.2.0.0, + html-entities ==1.1.4.7, + html-entity-map ==0.1.0.0, + html-parse ==0.2.1.0, + HTTP ==4000.4.1, + http2 ==5.0.1, + http-api-data ==0.5.1, + http-api-data-qq ==0.1.0.0, + http-client ==0.7.17, + http-client-openssl ==0.3.3, + http-client-overrides ==0.1.1.0, + http-client-restricted ==0.1.0, + http-client-tls ==0.3.6.3, + http-common ==0.8.3.4, + http-conduit ==2.3.9, + http-date ==0.0.11, + http-directory ==0.1.10, + http-download ==0.2.1.0, + httpd-shed ==0.4.1.2, + http-io-streams ==0.1.7.0, + http-link-header ==1.2.1, + http-media ==0.8.1.1, + http-query ==0.1.3, + http-reverse-proxy ==0.6.1.0, + http-streams ==0.8.9.9, + http-types ==0.12.4, + human-readable-duration ==0.2.1.4, + HUnit ==1.6.2.0, + HUnit-approx ==1.1.1.1, + hunit-dejafu ==2.0.0.6, + hvect ==0.4.0.1, + hvega ==0.12.0.7, + hw-bits ==0.7.2.2, + hw-conduit ==0.2.1.1, + hw-conduit-merges ==0.2.1.0, + hw-diagnostics ==0.0.1.0, + hweblib ==0.6.3, + hw-fingertree ==0.1.2.1, + hw-fingertree-strict ==0.1.2.1, + hw-hspec-hedgehog ==0.1.1.1, + hw-int ==0.0.2.0, + hwk ==0.6, + hw-kafka-client ==5.3.0, + hworker ==0.1.0.1, + hw-parser ==0.1.1.0, + hw-prim ==0.6.3.2, + hw-string-parse ==0.0.0.5, + hxt ==9.3.1.22, + hxt-charproperties ==9.5.0.0, + hxt-css ==0.1.0.3, + hxt-curl ==9.1.1.1, + hxt-expat ==9.1.1, + hxt-http ==9.1.5.2, + hxt-regex-xmlschema ==9.2.0.7, + hxt-tagsoup ==9.1.4, + hxt-unicode ==9.0.2.4, + hybrid-vectors ==0.2.4, + hyper ==0.2.1.1, + hyperloglog ==0.4.6, + hyphenation ==0.8.2, + hyraxAbif ==0.2.4.5, + iconv ==0.4.1.3, + identicon ==0.2.3, + ieee754 ==0.8.0, + if ==0.1.0.0, + IfElse ==0.85, + iff ==0.0.6.1, + ihaskell ==0.10.4.0, + ihaskell-hvega ==0.5.0.5, + ihs ==0.1.0.3, + ilist ==0.4.0.1, + imagesize-conduit ==1.1, + Imlib ==0.1.2, + immortal ==0.3, + immortal-queue ==0.1.0.1, + inbox ==0.2.0, + incipit-base ==0.5.1.0, + incipit-core ==0.5.1.0, + include-file ==0.1.0.4, + incremental ==0.3.1, + incremental-parser ==0.5.1, + indents ==0.5.0.1, + indexed ==0.1.3, + indexed-containers ==0.1.0.2, + indexed-list-literals ==0.2.1.3, + indexed-profunctors ==0.1.1.1, + indexed-traversable ==0.1.4, + indexed-traversable-instances ==0.1.2, + inf-backprop ==0.1.0.2, + infer-license ==0.2.0, + infinite-list ==0.1.1, + inflections ==0.4.0.7, + influxdb ==1.9.3.2, + ini ==0.4.2, + inj ==1.0, + inline-c ==0.9.1.10, + inline-c-cpp ==0.5.0.2, + inline-r ==1.0.1, + input-parsers ==0.3.0.2, + insert-ordered-containers ==0.2.5.3, + inspection-testing ==0.5.0.3, + int-cast ==0.2.0.0, + integer-conversion ==0.1.0.1, + integer-gmp installed, + integer-logarithms ==1.0.3.1, + integer-roots ==1.0.2.0, + integer-types ==0.1.4.0, + integration ==0.2.1, + intern ==0.9.5, + interpolate ==0.2.1, + interpolatedstring-perl6 ==1.0.2, + interpolation ==0.1.1.2, + Interpolation ==0.3.0, + IntervalMap ==0.6.2.1, + intervals ==0.9.2, + intset-imperative ==0.1.0.0, + int-supply ==1.0.0, + invariant ==0.6.3, + invert ==1.0.0.4, + invertible ==0.2.0.8, + invertible-grammar ==0.1.3.5, + io-machine ==0.2.0.0, + io-manager ==0.1.0.4, + io-memoize ==1.1.1.0, + io-region ==0.1.1, + io-storage ==0.3, + io-streams ==1.5.2.2, + io-streams-haproxy ==1.0.1.0, + ip ==1.7.8, + ip6addr ==1.0.4, + iproute ==1.7.14, + IPv6Addr ==2.0.6, + ipynb ==0.2, + ipython-kernel ==0.11.0.0, + irc ==0.6.1.1, + irc-ctcp ==0.1.3.1, + isbn ==1.1.0.5, + islink ==0.1.0.0, + iso3166-country-codes ==0.20140203.8, + iso639 ==0.1.0.3, + iso8601-time ==0.1.5, + isocline ==1.0.9, + isomorphism-class ==0.1.1, + ixset-typed ==0.5.1.0, + ixset-typed-binary-instance ==0.1.0.2, + ixset-typed-hashable-instance ==0.1.0.2, + ix-shapable ==0.1.0, + jack ==0.7.2.2, + jailbreak-cabal ==1.4, + jalaali ==1.0.0.0, + java-adt ==1.0.20231204, + jira-wiki-markup ==1.5.1, + jmacro ==0.6.18, + jose ==0.11, + jose-jwt ==0.9.6, + journalctl-stream ==0.6.0.6, + jsaddle ==0.9.9.2, + js-chart ==2.9.4.1, + js-dgtable ==0.5.2, + js-flot ==0.8.3, + js-jquery ==3.3.1, + json ==0.11, + json-feed ==2.0.0.12, + jsonifier ==0.2.1.3, + jsonpath ==0.3.0.0, + json-rpc ==1.0.4, + json-stream ==0.4.6.0, + JuicyPixels ==3.3.9, + JuicyPixels-extra ==0.6.0, + JuicyPixels-scale-dct ==0.1.2, + junit-xml ==0.1.0.3, + justified-containers ==0.3.0.0, + jwt ==0.11.0, + kan-extensions ==5.2.6, + kansas-comet ==0.4.2, + katip ==0.8.8.2, + katip-logstash ==0.1.0.2, + katip-wai ==0.1.2.4, + kazura-queue ==0.1.0.4, + kdt ==0.2.6, + keep-alive ==0.2.1.0, + keter ==2.1.5, + keycode ==0.2.2, + keyed-vals ==0.2.3.1, + keyed-vals-hspec-tests ==0.2.3.1, + keyed-vals-mem ==0.2.3.1, + keyed-vals-redis ==0.2.3.1, + keys ==3.12.3, + ki ==1.0.1.2, + kind-apply ==0.4.0.0, + kind-generics ==0.5.0.0, + kind-generics-th ==0.2.3.3, + ki-unlifted ==1.0.0.2, + kleene ==0.1, + kmeans ==0.1.3, + knob ==0.2.2, + koji ==0.0.2, + koji-tool ==1.1.1, + kvitable ==1.0.3.0, + labels ==0.3.3, + lackey ==2.0.0.8, + lambdabot-core ==5.3.1.2, + lambdabot-irc-plugins ==5.3.1.2, + LambdaHack ==0.11.0.1, + lame ==0.2.2, + language-avro ==0.1.4.0, + language-c ==0.9.3, + language-c99 ==0.2.0, + language-c99-simple ==0.3.0, + language-c99-util ==0.2.0, + language-c-quote ==0.13.0.2, + language-docker ==12.1.0, + language-dot ==0.1.2, + language-glsl ==0.3.0, + language-java ==0.2.9, + language-javascript ==0.7.1.0, + language-lua ==0.11.0.2, + language-nix ==2.2.0, + language-protobuf ==1.0.1, + language-python ==0.5.8, + lapack ==0.5.2, + lapack-carray ==0.0.3, + lapack-comfort-array ==0.0.1, + lapack-ffi ==0.0.3, + lapack-ffi-tools ==0.1.3.1, + lapack-hmatrix ==0.0.0.2, + largeword ==1.2.5, + latex ==0.1.0.4, + lattices ==2.2.1, + lawful ==0.1.0.0, + lazy-csv ==0.5.1, + lazyio ==0.1.0.4, + lazysmallcheck ==0.6, + lca ==0.4, + leancheck ==1.0.2, + leancheck-instances ==0.0.5, + leapseconds-announced ==2017.1.0.1, + leb128-cereal ==1.2, + lens ==5.2.3, + lens-action ==0.2.6, + lens-aeson ==1.2.3, + lens-csv ==0.1.1.0, + lens-family ==2.1.3, + lens-family-core ==2.1.3, + lens-misc ==0.0.2.0, + lens-properties ==4.11.1, + lens-regex ==0.1.3, + lens-regex-pcre ==1.1.0.0, + lentil ==1.5.6.0, + LetsBeRational ==1.0.0.0, + leveldb-haskell ==0.6.5, + lexer-applicative ==2.1.0.2, + libBF ==0.6.8, + libffi ==0.2.1, + libiserv installed, + liboath-hs ==0.0.1.2, + libyaml ==0.1.4, + libyaml-clib ==0.2.5, + lifted-async ==0.10.2.5, + lifted-base ==0.2.3.12, + lift-generics ==0.2.1, + lift-type ==0.1.2.0, + line ==4.0.1, + linear ==1.22, + linear-base ==0.4.0, + linear-circuit ==0.1.0.4, + linear-generics ==0.2.3, + linear-programming ==0.0.1, + linebreak ==1.1.0.4, + linux-capabilities ==0.1.1.0, + linux-file-extents ==0.2.0.1, + linux-namespaces ==0.1.3.1, + List ==0.6.2, + ListLike ==4.7.8.2, + list-predicate ==0.1.0.1, + listsafe ==0.1.0.1, + list-shuffle ==1.0.0.1, + list-t ==1.0.5.7, + list-transformer ==1.1.1, + ListTree ==0.2.3, + ListZipper ==1.2.0.2, + literatex ==0.3.0.0, + little-logger ==1.0.2, + little-rio ==2.0.1, + lmdb ==0.2.5, + load-env ==0.2.1.0, + loc ==0.2.0.0, + locators ==0.3.0.5, + loch-th ==0.2.2, + lockfree-queue ==0.2.4, + log-base ==0.12.0.1, + log-domain ==0.13.2, + logfloat ==0.14.0, + logger-thread ==0.1.0.2, + logging ==3.0.5, + logging-effect ==1.4.0, + logging-facade ==0.3.1, + logging-facade-syslog ==1, + logict ==0.8.1.0, + logstash ==0.1.0.4, + loop ==0.3.0, + lpeg ==1.0.4, + LPFP-core ==1.1.1, + lrucache ==1.2.0.1, + lsp ==2.3.0.0, + lsp-test ==0.16.0.1, + lsp-types ==2.1.1.0, + lua ==2.3.3, + lua-arbitrary ==1.0.1.1, + lucid ==2.11.20230408, + lucid2 ==0.0.20240424, + lucid-cdn ==0.2.2.0, + lucid-extras ==0.2.2, + lukko ==0.1.1.3, + lumberjack ==1.0.3.0, + lz4 ==0.2.3.1, + lz4-frame-conduit ==0.1.0.1, + lzma ==0.0.1.1, + lzma-clib ==5.2.2, + machines ==0.7.3, + magic ==1.1, + magico ==0.0.2.3, + mailtrap ==0.1.2.1, + mainland-pretty ==0.7.1.1, + main-tester ==0.2.0.1, + managed ==1.0.10, + mandrill ==0.5.7.0, + mappings ==0.3.1.0, + map-syntax ==0.3, + markdown ==0.1.17.5, + markdown-unlit ==0.6.0, + markov-chain ==0.0.3.4, + markov-chain-usage-model ==0.0.0, + markup-parse ==0.1.1, + mason ==0.2.6, + massiv ==1.0.4.0, + massiv-io ==1.0.0.1, + massiv-serialise ==1.0.0.2, + massiv-test ==1.0.0.0, + matchable ==0.1.2.1, + mathexpr ==0.3.1.0, + math-extras ==0.1.1.0, + math-functions ==0.3.4.4, + mathlist ==0.2.0.0, + matplotlib ==0.7.7, + matrices ==0.5.0, + matrix ==0.3.6.3, + matrix-as-xyz ==0.1.2.2, + matrix-market-attoparsec ==0.1.1.3, + matrix-static ==0.3, + maximal-cliques ==0.1.1, + mbox-utility ==0.0.3.1, + mcmc ==0.8.2.0, + mcmc-types ==1.0.3, + median-stream ==0.7.0.0, + med-module ==0.1.3, + megaparsec ==9.5.0, + megaparsec-tests ==9.5.0, + mega-sdist ==0.4.3.1, + membership ==0.0.1, + memcache ==0.3.0.2, + memfd ==1.0.1.3, + memory ==0.18.0, + MemoTrie ==0.6.11, + mergeful ==0.3.0.0, + mergeful-persistent ==0.3.0.1, + mergeless ==0.4.0.0, + mergeless-persistent ==0.1.0.1, + merkle-tree ==0.1.1, + mersenne-random ==1.0.0.1, + mersenne-random-pure64 ==0.2.2.0, + messagepack ==0.5.5, + metrics ==0.4.1.1, + mfsolve ==0.3.2.2, + microaeson ==0.1.0.2, + microlens ==0.4.13.1, + microlens-aeson ==2.5.2, + microlens-contra ==0.1.0.3, + microlens-ghc ==0.4.14.3, + microlens-mtl ==0.2.0.3, + microlens-platform ==0.4.3.5, + microlens-th ==0.4.3.15, + microspec ==0.2.1.3, + microstache ==1.0.2.3, + midair ==0.2.0.1, + midi ==0.2.2.4, + midi-alsa ==0.2.1, + midi-music-box ==0.0.1.2, + mighty-metropolis ==2.0.0, + mime-mail ==0.5.1, + mime-mail-ses ==0.4.3, + mime-types ==0.1.2.0, + minimal-configuration ==0.1.4, + minimorph ==0.3.0.1, + minisat-solver ==0.1, + miniterion ==0.1.1.1, + miniutter ==0.5.1.2, + min-max-pqueue ==0.1.0.2, + mintty ==0.1.4, + misfortune ==0.1.2.1, + miso ==1.8.4.0, + missing-foreign ==0.1.1, + MissingH ==1.6.0.1, + mixed-types-num ==0.5.12, + mmap ==0.5.9, + mmark ==0.0.8.0, + mmark-cli ==0.0.5.2, + mmark-ext ==0.2.1.5, + mmorph ==1.2.0, + mnist-idx ==0.1.3.2, + mnist-idx-conduit ==0.4.0.0, + mockery ==0.3.5, + mod ==0.2.0.1, + modern-uri ==0.3.6.1, + modular ==0.1.0.8, + moffy ==0.1.1.0, + moffy-samples ==0.1.0.3, + moffy-samples-events ==0.2.2.5, + monad-chronicle ==1.0.2, + monad-control ==1.0.3.1, + monad-control-aligned ==0.0.2.1, + monad-control-identity ==0.2.0.0, + monad-coroutine ==0.9.2, + monad-extras ==0.6.0, + monad-interleave ==0.2.0.1, + monadlist ==0.0.2, + monad-logger ==0.3.40, + monad-logger-aeson ==0.4.1.3, + monad-logger-json ==0.1.0.0, + monad-logger-logstash ==0.2.0.2, + monad-loops ==0.4.3, + monad-memo ==0.5.4, + monad-metrics ==0.2.2.2, + monadoid ==0.0.3, + monadology ==0.3, + monad-par ==0.3.6, + monad-parallel ==0.8, + monad-par-extras ==0.3.3, + monad-peel ==0.3, + MonadPrompt ==1.0.0.5, + MonadRandom ==0.6, + monad-resumption ==0.1.4.0, + monad-schedule ==0.1.2.2, + monad-st ==0.2.4.1, + monads-tf ==0.3.0.1, + monad-time ==0.4.0.0, + mongoDB ==2.7.1.4, + monoidal-containers ==0.6.5.0, + monoidal-functors ==0.2.3.0, + monoid-extras ==0.6.3, + monoid-subclasses ==1.2.5.1, + monoid-transformer ==0.0.4, + monomer ==1.6.0.1, + mono-traversable ==1.0.20.0, + mono-traversable-instances ==0.1.1.0, + mono-traversable-keys ==0.3.0, + more-containers ==0.2.2.2, + morpheus-graphql-app ==0.27.3, + morpheus-graphql-client ==0.27.3, + morpheus-graphql-code-gen-utils ==0.27.3, + morpheus-graphql-core ==0.27.3, + morpheus-graphql-server ==0.27.3, + morpheus-graphql-subscriptions ==0.27.3, + morpheus-graphql-tests ==0.27.3, + moss ==0.2.0.1, + mountpoints ==1.0.2, + mpi-hs ==0.7.2.0, + mpi-hs-binary ==0.1.1.0, + mpi-hs-cereal ==0.1.0.0, + msgpack ==1.0.1.0, + mtl installed, + mtl-compat ==0.2.2, + mtl-prelude ==2.0.3.2, + multiarg ==0.30.0.10, + multi-containers ==0.2, + multimap ==1.2.1, + multipart ==0.2.1, + MultipletCombiner ==0.0.7, + multiset ==0.3.4.3, + multistate ==0.8.0.4, + murmur3 ==1.0.5, + murmur-hash ==0.1.0.10, + MusicBrainz ==0.4.1, + mustache ==2.4.2, + mutable-containers ==0.3.4.1, + mwc-probability ==2.3.1, + mwc-random ==0.15.1.0, + mx-state-codes ==1.0.0.0, + myers-diff ==0.3.0.0, + mysql ==0.2.1, + mysql-haskell ==1.1.5, + mysql-haskell-nem ==0.1.0.0, + mysql-json-table ==0.1.4.0, + mysql-simple ==0.4.9, + n2o ==0.11.1, + n2o-nitro ==0.11.2, + nagios-check ==0.3.2, + named ==0.3.0.1, + names-th ==0.3.0.1, + nano-erl ==0.1.0.1, + nanospec ==0.2.2, + nanovg ==0.8.1.0, + nats ==1.1.2, + natural-arithmetic ==0.1.4.0, + natural-induction ==0.2.0.0, + natural-sort ==0.1.2, + natural-transformation ==0.4, + ndjson-conduit ==0.1.0.5, + neat-interpolation ==0.5.1.4, + netcode-io ==0.0.3, + netlib-carray ==0.1, + netlib-comfort-array ==0.0.0.2, + netlib-ffi ==0.1.2, + net-mqtt ==0.8.6.1, + net-mqtt-lens ==0.1.1.0, + netpbm ==1.0.4, + netrc ==0.2.0.1, + netwire ==5.0.3, + netwire-input ==0.0.7, + network ==3.1.4.0, + network-bsd ==2.8.1.0, + network-byte-order ==0.1.7, + network-conduit-tls ==1.4.0.1, + network-control ==0.0.2, + network-info ==0.2.1, + network-ip ==0.3.0.3, + network-messagepack-rpc ==0.1.2.0, + network-messagepack-rpc-websocket ==0.1.1.1, + network-multicast ==0.3.2, + network-run ==0.2.8, + network-simple ==0.4.5, + network-transport ==0.5.8, + network-uri ==2.6.4.2, + network-wait ==0.2.0.0, + newtype ==0.2.2.0, + newtype-generics ==0.6.2, + nfc ==0.1.1, + nicify-lib ==1.0.1, + NineP ==0.0.2.1, + nix-derivation ==1.1.3, + nix-paths ==1.0.1, + NoHoed ==0.1.1, + nonce ==1.0.7, + nondeterminism ==1.5, + non-empty ==0.3.5, + nonempty-containers ==0.3.4.5, + non-empty-sequence ==0.2.0.4, + non-empty-text ==0.2.1, + nonempty-vector ==0.2.3, + nonempty-zipper ==1.0.0.4, + non-negative ==0.1.2, + normaldistribution ==1.1.0.3, + nothunks ==0.1.5, + no-value ==1.0.0.0, + nowdoc ==0.1.1.0, + nqe ==0.6.5, + nsis ==0.3.3, + n-tuple ==0.0.3, + numbers ==3000.2.0.2, + numeric-extras ==0.1, + numeric-limits ==0.1.0.0, + numeric-prelude ==0.4.4, + numeric-quest ==0.2.0.2, + numhask ==0.11.1.0, + numhask-array ==0.11.1.0, + numhask-space ==0.11.1.0, + NumInstances ==1.4, + numtype-dk ==0.5.0.3, + nuxeo ==0.3.2, + nvim-hs ==2.3.2.3, + nvim-hs-contrib ==2.0.0.2, + nvim-hs-ghcid ==2.0.1.0, + nvvm ==0.10.0.1, + ObjectName ==1.1.0.2, + oblivious-transfer ==0.1.0, + o-clock ==1.4.0, + ods2csv ==0.1, + ofx ==0.4.4.0, + old-locale ==1.0.0.7, + old-time ==1.1.0.4, + om-elm ==2.0.0.7, + once ==0.4, + one-liner ==2.1, + one-liner-instances ==0.1.3.0, + OneTuple ==0.4.2, + Only ==0.1, + oo-prototypes ==0.1.0.0, + oops ==0.2.0.1, + opaleye ==0.10.3.1, + OpenAL ==1.7.0.5, + openapi3 ==3.2.4, + open-browser ==0.2.1.0, + openexr-write ==0.1.0.2, + OpenGL ==3.0.3.0, + OpenGLRaw ==3.3.4.1, + openpgp-asciiarmor ==0.1.2, + opensource ==0.1.1.0, + openssl-streams ==1.2.3.0, + opentelemetry ==0.8.0, + opentelemetry-extra ==0.8.0, + opentelemetry-lightstep ==0.8.0, + opentelemetry-wai ==0.8.0, + open-witness ==0.6, + operational ==0.2.4.2, + opml-conduit ==0.9.0.0, + optics ==0.4.2.1, + optics-core ==0.4.1.1, + optics-extra ==0.4.2.1, + optics-operators ==0.1.0.1, + optics-th ==0.4.1, + optics-vl ==0.2.1, + optima ==0.4.0.5, + optional-args ==1.0.2, + options ==1.2.1.2, + optparse-applicative ==0.18.1.0, + optparse-enum ==1.0.0.0, + optparse-generic ==1.5.2, + optparse-simple ==0.1.1.4, + optparse-text ==0.1.1.0, + OrderedBits ==0.0.2.0, + ordered-containers ==0.2.4, + ormolu ==0.7.2.0, + os-string ==2.0.6, + overhang ==1.0.0, + packcheck ==0.6.0, + pager ==0.1.1.0, + pagination ==0.2.2, + pagure ==0.1.2, + pagure-cli ==0.2.1, + palette ==0.3.0.3, + pandoc ==3.1.11.1, + pandoc-cli ==3.1.11.1, + pandoc-dhall-decoder ==0.1.0.1, + pandoc-lua-engine ==0.2.1.2, + pandoc-lua-marshal ==0.2.8, + pandoc-plot ==1.8.0, + pandoc-server ==0.1.0.5, + pandoc-throw ==0.1.0.0, + pandoc-types ==1.23.1, + pango ==0.13.11.0, + panic ==0.4.0.1, + pantry ==0.9.3.2, + parallel ==3.2.2.0, + parallel-io ==0.3.5, + parameterized ==0.5.0.0, + parameterized-utils ==2.1.9.0, + park-bench ==0.1.1.0, + parseargs ==0.2.0.9, + parsec installed, + parsec-class ==1.0.1.0, + parsec-numbers ==0.1.0, + parsec-numeric ==0.1.0.0, + ParsecTools ==0.0.2.0, + parser-combinators ==1.3.0, + parser-combinators-tests ==1.3.0, + parsers ==0.12.11, + partial-handler ==1.0.3, + partial-isomorphisms ==0.2.3.0, + partialord ==0.0.2, + partial-order ==0.2.0.0, + partial-semigroup ==0.6.0.2, + password ==3.0.4.0, + password-instances ==3.0.0.0, + password-types ==1.0.0.0, + path ==0.9.5, + path-binary-instance ==0.1.0.1, + path-dhall-instance ==0.2.1.0, + path-extensions ==0.1.1.0, + path-extra ==0.3.1, + path-io ==1.8.2, + path-like ==0.2.0.2, + path-pieces ==0.2.1, + pathtype ==0.8.1.3, + path-utils ==0.1.1.0, + pathwalk ==0.3.1.2, + patrol ==1.0.0.8, + pava ==0.1.1.4, + pcf-font ==0.2.2.1, + pcg-random ==0.1.4.0, + pcre2 ==2.2.1, + pcre-heavy ==1.0.0.3, + pcre-light ==0.4.1.2, + pcre-utils ==0.1.9, + pdc ==0.1.1, + pdf-toolbox-content ==0.1.2, + pdf-toolbox-core ==0.1.3, + pdf-toolbox-document ==0.1.4, + peano ==0.1.0.2, + pedersen-commitment ==0.2.0, + pem ==0.2.4, + percent-format ==0.0.4, + peregrin ==0.4.2, + perf ==0.12.0.1, + perfect-hash-generator ==1.0.0, + persistable-record ==0.6.0.6, + persistable-types-HDBC-pg ==0.0.3.5, + persistent ==2.14.6.3, + persistent-discover ==0.1.0.7, + persistent-iproute ==0.2.5, + persistent-lens ==1.0.0, + persistent-mongoDB ==2.13.1.0, + persistent-mtl ==0.5.1, + persistent-mysql ==2.13.1.5, + persistent-pagination ==0.1.1.2, + persistent-postgresql ==2.13.6.2, + persistent-qq ==2.12.0.6, + persistent-redis ==2.13.0.2, + persistent-sqlite ==2.13.3.0, + persistent-template ==2.12.0.0, + persistent-test ==2.13.1.3, + persistent-typed-db ==0.1.0.7, + pfile ==0.1.0.1, + pg-harness-client ==0.6.0, + pg-transact ==0.3.2.0, + phantom-state ==0.2.1.4, + phatsort ==0.6.0.0, + pid1 ==0.1.3.1, + pinch ==0.5.2.0, + pipes ==4.3.16, + pipes-attoparsec ==0.6.0, + pipes-binary ==0.4.4, + pipes-bytestring ==2.1.7, + pipes-concurrency ==2.0.14, + pipes-csv ==1.4.3, + pipes-extras ==1.0.15, + pipes-fastx ==0.3.0.0, + pipes-fluid ==0.6.0.1, + pipes-group ==1.0.12, + pipes-http ==1.0.6, + pipes-mongodb ==0.1.0.0, + pipes-ordered-zip ==1.2.1, + pipes-parse ==3.0.9, + pipes-random ==1.0.0.5, + pipes-safe ==2.3.5, + pipes-text ==1.0.1, + pipes-wai ==3.2.0, + pipes-zlib ==0.4.4.2, + pkgtreediff ==0.6.0, + place-cursor-at ==1.0.1, + placeholders ==0.1, + plaid ==0.1.0.4, + plotlyhs ==0.2.3, + Plural ==0.0.2, + pointed ==5.0.4, + pointedlist ==0.6.1, + pointless-fun ==1.1.0.8, + poll ==0.0.0.2, + poly ==0.5.1.0, + poly-arity ==0.1.0, + polynomials-bernstein ==1.1.2, + polyparse ==1.13, + polysemy ==1.9.2.0, + polysemy-fs ==0.1.0.0, + polysemy-plugin ==0.4.5.2, + polysemy-webserver ==0.2.1.2, + pontarius-xmpp ==0.5.7.0, + pooled-io ==0.0.2.3, + portable-lines ==0.1, + port-utils ==0.2.1.0, + posix-paths ==0.3.0.0, + posix-pty ==0.2.2, + possibly ==1.0.0.0, + postgres-options ==0.2.2.0, + postgresql-binary ==0.13.1.3, + postgresql-libpq ==0.10.0.0, + postgresql-libpq-notify ==0.2.0.0, + postgresql-migration ==0.2.1.8, + postgresql-query ==3.10.0, + postgresql-schema ==0.1.14, + postgresql-simple ==0.7.0.0, + postgresql-simple-url ==0.2.1.0, + postgresql-syntax ==0.4.1.1, + postgresql-typed ==0.6.2.5, + post-mess-age ==0.2.1.0, + pptable ==0.3.0.0, + pqueue ==1.5.0.0, + pred-set ==0.0.1, + prefix-units ==0.3.0.1, + prelude-compat ==0.0.0.2, + prelude-safeenum ==0.1.1.3, + pretty installed, + pretty-class ==1.0.1.1, + prettyclass ==1.0.0.0, + pretty-hex ==1.1, + prettyprinter ==1.7.1, + prettyprinter-ansi-terminal ==1.1.3, + prettyprinter-combinators ==0.1.3, + prettyprinter-compat-annotated-wl-pprint ==1.1, + prettyprinter-compat-ansi-wl-pprint ==1.0.2, + prettyprinter-compat-wl-pprint ==1.0.1, + prettyprinter-interp ==0.2.0.0, + pretty-relative-time ==0.3.0.0, + pretty-show ==1.10, + pretty-simple ==4.1.2.0, + pretty-sop ==0.2.0.3, + pretty-terminal ==0.1.0.0, + primecount ==0.1.0.1, + primes ==0.2.1.0, + primitive ==0.8.0.0, + primitive-addr ==0.1.0.3, + primitive-extras ==0.10.2, + primitive-offset ==0.2.0.1, + primitive-serial ==0.1, + primitive-unaligned ==0.1.1.2, + primitive-unlifted ==2.1.0.0, + prim-uniq ==0.2, + print-console-colors ==0.1.0.0, + probability ==0.2.8, + process installed, + process-extras ==0.7.4, + product-isomorphic ==0.0.3.4, + product-profunctors ==0.11.1.1, + profunctors ==5.6.2, + projectroot ==0.2.0.1, + project-template ==0.2.1.0, + prometheus ==2.2.4, + prometheus-client ==1.1.1, + prometheus-metrics-ghc ==1.0.1.2, + promises ==0.3, + prospect ==0.1.0.0, + protobuf ==0.2.1.3, + protobuf-simple ==0.1.1.1, + protocol-radius ==0.0.1.2, + protocol-radius-test ==0.1.0.1, + proto-lens ==0.7.1.5, + proto-lens-arbitrary ==0.1.2.13, + proto-lens-optparse ==0.1.1.12, + proto-lens-runtime ==0.7.0.6, + protolude ==0.3.4, + proxied ==0.3.2, + psql-helpers ==0.1.0.0, + PSQueue ==1.2.0, + psqueues ==0.2.8.0, + pthread ==0.2.1, + ptr ==0.16.8.6, + ptr-poker ==0.1.2.14, + pulse-simple ==0.1.14, + pureMD5 ==2.1.4, + purescript-bridge ==0.15.0.0, + purview ==0.2.0.2, + pusher-http-haskell ==2.1.0.18, + pvar ==1.0.0.0, + pwstore-fast ==2.4.4, + PyF ==0.11.3.0, + qchas ==1.1.0.1, + qm-interpolated-string ==0.3.1.0, + qrcode-core ==0.9.9, + qrcode-juicypixels ==0.8.5, + quaalude ==0.0.0.1, + quadratic-irrational ==0.1.1, + QuasiText ==0.1.2.6, + QuickCheck ==2.14.3, + quickcheck-arbitrary-adt ==0.3.1.0, + quickcheck-assertions ==0.3.0, + quickcheck-classes ==0.6.5.0, + quickcheck-classes-base ==0.6.2.0, + quickcheck-groups ==0.0.1.3, + quickcheck-higherorder ==0.1.0.1, + quickcheck-instances ==0.3.30, + quickcheck-io ==0.2.0, + quickcheck-monoid-subclasses ==0.3.0.4, + quickcheck-simple ==0.1.1.1, + quickcheck-special ==0.1.0.6, + quickcheck-state-machine ==0.8.0, + quickcheck-text ==0.1.2.1, + quickcheck-transformer ==0.3.1.2, + quickcheck-unicode ==1.0.1.0, + quicklz ==1.5.0.11, + quiet ==0.2, + quote-quot ==0.2.1.0, + radius ==0.7.1.0, + rainbow ==0.34.2.2, + rainbox ==0.26.0.0, + ral ==0.2.1, + rampart ==2.0.0.8, + ramus ==0.1.2, + rando ==0.0.0.4, + random ==1.2.1.2, + random-bytestring ==0.1.4, + random-fu ==0.3.0.1, + random-shuffle ==0.0.4, + random-tree ==0.6.0.5, + range ==0.3.0.2, + ranged-list ==0.1.2.1, + Ranged-sets ==0.4.0, + ranges ==0.2.4, + range-set-list ==0.1.3.1, + rank1dynamic ==0.4.2, + rank2classes ==1.5.3.1, + Rasterific ==0.7.5.4, + rasterific-svg ==0.3.3.2, + ratel ==2.0.0.12, + rate-limit ==1.4.3, + ratel-wai ==2.0.0.7, + ratio-int ==0.1.2, + rattle ==0.2, + rattletrap ==12.1.3, + Rattus ==0.5.1.1, + rawfilepath ==1.1.1, + rawstring-qm ==0.2.3.0, + raw-strings-qq ==1.1, + rcu ==0.2.7, + rdf ==0.1.0.8, + rdtsc ==1.3.0.1, + re2 ==0.3, + reactive-balsa ==0.4.0.1, + reactive-banana ==1.3.2.0, + reactive-banana-bunch ==1.0.0.1, + reactive-jack ==0.4.1.2, + reactive-midyim ==0.4.1.1, + readable ==0.3.1, + read-editor ==0.1.0.2, + read-env-var ==1.0.0.0, + rebase ==1.20.2, + rec-def ==0.2.2, + record-hasfield ==1.0.1, + records-sop ==0.1.1.1, + recursion-schemes ==5.2.3, + recv ==0.1.0, + redact ==0.5.0.0, + reddit-scrape ==0.0.1, + redis-glob ==0.1.0.8, + redis-resp ==1.0.0, + reducers ==3.12.4, + refact ==0.3.0.2, + ref-fd ==0.5.0.1, + refined ==0.8.2, + reflection ==2.1.8, + RefSerialize ==0.4.0, + ref-tf ==0.5.0.1, + regex ==1.1.0.2, + regex-applicative ==0.3.4, + regex-base ==0.94.0.2, + regex-compat ==0.95.2.1, + regex-pcre ==0.95.0.0, + regex-pcre-builtin ==0.95.2.3.8.44, + regex-posix ==0.96.0.1, + regex-posix-clib ==2.7, + regex-tdfa ==1.3.2.2, + regex-with-pcre ==1.1.0.2, + regression-simple ==0.2.1, + reinterpret-cast ==0.1.0, + relapse ==1.0.0.1, + relational-query ==0.12.3.1, + relational-query-HDBC ==0.7.2.1, + relational-record ==0.2.2.0, + relational-schemas ==0.1.8.1, + reliable-io ==0.0.2, + relude ==1.2.1.0, + renderable ==0.2.0.1, + replace-attoparsec ==1.5.0.0, + replace-megaparsec ==1.5.0.1, + repline ==0.4.2.0, + req ==3.13.2, + req-conduit ==1.0.2, + rerebase ==1.20.2, + reroute ==0.7.0.0, + resistor-cube ==0.0.1.4, + resolv ==0.2.0.2, + resource-pool ==0.4.0.0, + resourcet ==1.3.0, + rest-rewrite ==0.4.4, + result ==0.2.6.0, + retry ==0.9.3.1, + rex ==0.6.2, + rfc1751 ==0.1.3, + rfc5051 ==0.2, + rg ==1.4.0.0, + riak-protobuf ==0.25.0.0, + richenv ==0.1.0.2, + rio ==0.1.22.0, + rio-orphans ==0.1.2.0, + rio-prettyprint ==0.1.8.0, + rng-utils ==0.3.1, + roc-id ==0.2.0.3, + rocksdb-haskell ==1.0.1, + rocksdb-haskell-jprupp ==2.1.6, + rocksdb-query ==0.4.2, + roles ==0.2.1.0, + rollbar ==1.1.3, + rope-utf16-splay ==0.4.0.0, + rosezipper ==0.2, + rot13 ==0.2.0.1, + row-types ==1.0.1.2, + rpmbuild-order ==0.4.12, + rpm-nvr ==0.1.2, + rp-tree ==0.7.1, + rrb-vector ==0.2.1.0, + RSA ==2.4.1, + rss ==3000.2.0.8, + rss-conduit ==0.6.0.1, + run-haskell-module ==0.0.2, + runmemo ==1.0.0.1, + run-st ==0.1.3.3, + rvar ==0.3.0.2, + rzk ==0.7.5, + s3-signer ==0.5.0.0, + safe ==0.3.21, + safe-coloured-text ==0.2.0.2, + safe-coloured-text-gen ==0.0.0.2, + safe-coloured-text-layout ==0.0.0.0, + safe-coloured-text-layout-gen ==0.0.0.0, + safe-coloured-text-terminfo ==0.1.0.0, + safecopy ==0.10.4.2, + safe-decimal ==0.2.1.0, + safe-exceptions ==0.1.7.4, + safe-foldable ==0.1.0.0, + safe-gen ==1.0.1, + safeio ==0.0.6.0, + safe-json ==1.2.0.1, + safe-money ==0.9.1, + SafeSemaphore ==0.10.1, + saltine ==0.2.1.0, + salve ==2.0.0.5, + sample-frame ==0.0.4, + sample-frame-np ==0.0.5, + sampling ==0.3.5, + sandi ==0.5, + sandwich ==0.2.2.0, + sandwich-hedgehog ==0.1.3.1, + sandwich-quickcheck ==0.1.0.7, + sandwich-slack ==0.1.2.0, + sandwich-webdriver ==0.2.3.1, + say ==0.1.0.1, + sbp ==5.0.7, + sbv ==10.2, + scalpel ==0.6.2.2, + scalpel-core ==0.6.2.2, + scanf ==0.1.0.0, + scanner ==0.3.1, + s-cargot ==0.1.6.0, + scheduler ==2.0.0.1, + SciBaseTypes ==0.1.1.0, + scientific ==0.3.7.0, + scientist ==0.0.0.0, + scotty ==0.20.1, + scrypt ==0.5.0, + sdl2 ==2.5.5.0, + sdl2-gfx ==0.3.0.0, + sdl2-image ==2.1.0.0, + sdl2-mixer ==1.2.0.0, + sdl2-ttf ==2.1.3, + search-algorithms ==0.3.2, + secp256k1-haskell ==1.1.0, + securemem ==0.1.10, + selections ==0.3.0.0, + selective ==0.7.0.1, + semialign ==1.3.1, + semigroupoids ==6.0.1, + semigroups ==0.20, + semirings ==0.6, + semiring-simple ==1.0.0.1, + semver ==0.4.0.1, + sendfile ==0.7.11.6, + sendgrid-v3 ==1.0.0.1, + seqalign ==0.2.0.4, + seqid ==0.6.3, + seqid-streams ==0.7.2, + sequence-formats ==1.8.1.1, + sequenceTools ==1.5.3.1, + serialise ==0.2.6.1, + servant ==0.20.2, + servant-auth ==0.4.2.0, + servant-auth-client ==0.4.2.0, + servant-auth-docs ==0.2.11.0, + servant-auth-server ==0.4.9.0, + servant-auth-swagger ==0.2.11.0, + servant-blaze ==0.9.1, + servant-checked-exceptions ==2.2.0.1, + servant-checked-exceptions-core ==2.2.0.1, + servant-client ==0.20.2, + servant-client-core ==0.20.2, + servant-conduit ==0.16.1, + servant-docs ==0.13.1, + servant-elm ==0.7.3, + servant-exceptions ==0.2.1, + servant-exceptions-server ==0.2.1, + servant-foreign ==0.16.1, + servant-http-streams ==0.20.2, + servant-JuicyPixels ==0.3.1.1, + servant-lucid ==0.9.0.6, + servant-machines ==0.16.1, + servant-multipart ==0.12.1, + servant-multipart-api ==0.12.1, + servant-multipart-client ==0.12.2, + servant-openapi3 ==2.0.1.6, + servant-pipes ==0.16.1, + servant-rate-limit ==0.2.0.0, + servant-rawm ==1.0.0.0, + servant-server ==0.20.2, + servant-static-th ==1.0.0.0, + servant-subscriber ==0.7.0.0, + servant-swagger ==1.2.1, + servant-swagger-ui ==0.3.5.5.0.0, + servant-swagger-ui-core ==0.3.5, + servant-swagger-ui-redoc ==0.3.4.1.22.3, + servant-websockets ==2.0.0, + servant-xml ==1.0.3, + serversession ==1.0.3, + serversession-backend-redis ==1.0.5, + serversession-frontend-wai ==1.0.1, + serversession-frontend-yesod ==1.0.1, + servius ==1.2.3.0, + ses-html ==0.4.0.0, + set-cover ==0.1.1.1, + setenv ==0.1.1.3, + setlocale ==1.0.0.10, + set-monad ==0.3.0.0, + sexp-grammar ==2.3.4.2, + SHA ==1.6.4.4, + shake ==0.19.8, + shake-language-c ==0.12.0, + shake-plus ==0.3.4.0, + shake-plus-extended ==0.4.1.0, + shakespeare ==2.1.1, + shakespeare-text ==1.1.0, + shared-memory ==0.2.0.1, + ShellCheck ==0.9.0, + shell-conduit ==5.0.0, + shell-escape ==0.2.0, + shellify ==0.11.0.1, + shellmet ==0.0.4.1, + shelltestrunner ==1.10, + shell-utility ==0.1, + shellwords ==0.1.3.1, + shelly ==1.12.1, + should-not-typecheck ==2.1.0, + show-combinators ==0.2.0.0, + siggy-chardust ==1.0.0, + signal ==0.1.0.4, + silently ==1.2.5.3, + simple ==2.0.0, + simple-affine-space ==0.2.1, + simple-cabal ==0.1.3.1, + simple-cairo ==0.1.0.6, + simple-cmd ==0.2.7, + simple-cmd-args ==0.1.8, + simple-expr ==0.1.1.0, + simple-media-timestamp ==0.2.1.0, + simple-media-timestamp-attoparsec ==0.1.0.0, + simple-pango ==0.1.0.1, + simple-prompt ==0.2.3, + simple-reflect ==0.3.3, + simple-sendfile ==0.2.32, + simple-session ==2.0.0, + simple-templates ==2.0.0, + simple-vec3 ==0.6.0.1, + since ==0.0.0, + singleton-bool ==0.1.8, + singleton-nats ==0.4.7, + singletons ==3.0.3, + singletons-base ==3.2, + singletons-presburger ==0.7.4.0, + singletons-th ==3.2, + Sit ==0.2023.8.3, + sitemap-gen ==0.1.0.0, + size-based ==0.1.3.3, + sized ==1.1.0.2, + skein ==1.0.9.4, + skews ==0.1.0.3, + skip-var ==0.1.1.0, + skylighting ==0.14.3, + skylighting-core ==0.14.3, + skylighting-format-ansi ==0.1, + skylighting-format-blaze-html ==0.1.1.2, + skylighting-format-context ==0.1.0.2, + skylighting-format-latex ==0.1, + slave-thread ==1.1.0.3, + slick ==1.2.1.0, + slist ==0.2.1.0, + slynx ==0.7.2.2, + smallcheck ==1.2.1.1, + snap ==1.1.3.3, + snap-blaze ==0.2.1.5, + snap-core ==1.0.5.1, + snap-server ==1.1.2.1, + snowflake ==0.1.1.1, + socket ==0.8.3.0, + socks ==0.6.1, + solana-staking-csvs ==0.1.3.0, + some ==1.0.6, + some-dict-of ==0.1.0.2, + sop-core ==0.5.0.2, + sort ==1.0.0.0, + sorted-list ==0.2.2.0, + sound-collage ==0.2.1, + sourcemap ==0.1.7, + sox ==0.2.3.2, + soxlib ==0.0.3.2, + SpatialMath ==0.2.7.1, + special-values ==0.1.0.0, + speculate ==0.4.20, + speedy-slice ==0.3.2, + splice ==0.6.1.1, + split ==0.2.5, + splitmix ==0.1.0.5, + splitmix-distributions ==1.0.0, + split-record ==0.1.1.4, + Spock-api ==0.14.0.0, + spoon ==0.3.1, + spreadsheet ==0.1.3.10, + sqids ==0.2.2.0, + sqlite-simple ==0.4.19.0, + sql-words ==0.1.6.5, + squeal-postgresql ==0.9.1.3, + squeather ==0.8.0.0, + srcloc ==0.6.0.1, + srt ==0.1.2.0, + srtree ==1.0.0.5, + stache ==2.3.4, + stack ==2.13.1, + stack-all ==0.4.2, + stack-clean-old ==0.5.1, + stack-templatizer ==0.1.1.0, + state-codes ==0.1.3, + stateref ==0.3, + statestack ==0.3.1.1, + StateVar ==1.2.2, + stateWriter ==0.4.0, + static-bytes ==0.1.0, + static-canvas ==0.2.0.3, + static-text ==0.2.0.7, + statistics ==0.16.2.1, + statistics-linreg ==0.3, + status-notifier-item ==0.3.1.0, + step-function ==0.2.1, + stitch ==0.6.0.0, + stm installed, + stm-chans ==3.0.0.9, + stm-conduit ==4.0.1, + stm-containers ==1.2.1, + stm-delay ==0.1.1.1, + stm-extras ==0.1.0.3, + stm-hamt ==1.2.1, + STMonadTrans ==0.4.8, + stm-split ==0.0.2.1, + stm-supply ==0.2.0.0, + storable-complex ==0.2.3.0, + storable-endian ==0.2.6.1, + storable-record ==0.0.7, + storable-tuple ==0.1, + storablevector ==0.2.13.2, + store ==0.7.18, + store-core ==0.4.4.7, + store-streaming ==0.2.0.5, + stratosphere ==0.60.0, + Stream ==0.4.7.2, + streaming ==0.2.4.0, + streaming-attoparsec ==1.0.0.1, + streaming-bytestring ==0.3.2, + streaming-commons ==0.2.2.6, + streaming-wai ==0.1.1, + streamly ==0.10.1, + streamly-core ==0.2.2, + streams ==3.3.2, + strict ==0.5, + strict-base-types ==0.8, + strict-concurrency ==0.2.4.3, + strict-lens ==0.4.0.3, + strict-list ==0.1.7.5, + strict-tuple ==0.1.5.4, + strict-wrapper ==0.0.1.0, + stringable ==0.1.3, + stringbuilder ==0.5.1, + string-class ==0.1.7.2, + string-combinators ==0.6.0.5, + string-conv ==0.2.0, + string-conversions ==0.4.0.1, + string-interpolate ==0.3.4.0, + stringprep ==1.0.0, + string-qq ==0.0.6, + string-random ==0.1.4.3, + stringsearch ==0.3.6.6, + string-transform ==1.1.1, + stripe-concepts ==1.0.3.3, + stripe-signature ==1.0.0.16, + stripe-wreq ==1.0.1.16, + strive ==6.0.0.12, + structs ==0.1.9, + structured ==0.1.1, + stylish-haskell ==0.14.5.0, + subcategories ==0.2.1.1, + sundown ==0.6, + superbuffer ==0.3.1.2, + svg-builder ==0.1.1, + SVGFonts ==1.8.0.1, + svg-tree ==0.6.2.4, + swagger2 ==2.8.9, + swish ==0.10.9.0, + syb ==0.7.2.4, + sydtest ==0.15.1.3, + sydtest-aeson ==0.1.0.0, + sydtest-amqp ==0.1.0.0, + sydtest-autodocodec ==0.0.0.0, + sydtest-discover ==0.0.0.4, + sydtest-hedgehog ==0.4.0.0, + sydtest-hedis ==0.0.0.0, + sydtest-hspec ==0.4.0.2, + sydtest-mongo ==0.0.0.0, + sydtest-persistent ==0.0.0.2, + sydtest-persistent-sqlite ==0.2.0.3, + sydtest-process ==0.0.0.0, + sydtest-rabbitmq ==0.1.0.0, + sydtest-servant ==0.2.0.2, + sydtest-typed-process ==0.0.0.0, + sydtest-wai ==0.2.0.2, + sydtest-webdriver ==0.0.0.1, + sydtest-webdriver-screenshot ==0.0.0.2, + sydtest-webdriver-yesod ==0.0.0.1, + sydtest-yesod ==0.3.0.2, + symbol ==0.2.4.1, + symengine ==0.1.2.0, + symmetry-operations-symbols ==0.0.2.1, + synthesizer-alsa ==0.5.0.6, + synthesizer-core ==0.8.4, + synthesizer-dimensional ==0.8.1.1, + synthesizer-midi ==0.6.1.2, + sysinfo ==0.1.1, + system-argv0 ==0.1.1, + systemd ==2.3.0, + systemd-socket-activation ==1.1.0.1, + system-fileio ==0.3.16.4, + system-filepath ==0.4.14, + system-info ==0.5.2, + system-linux-proc ==0.1.1.1, + tabular ==0.2.2.8, + tagchup ==0.4.1.2, + tagged ==0.8.8, + tagged-binary ==0.2.0.1, + tagged-identity ==0.1.4, + tagged-transformer ==0.8.2, + tagsoup ==0.14.8, + tagstream-conduit ==0.5.6, + tao ==1.0.0, + tao-example ==1.0.0, + tar ==0.5.1.1, + tar-conduit ==0.4.1, + tasty ==1.4.3, + tasty-ant-xml ==1.1.9, + tasty-autocollect ==0.4.3, + tasty-bench ==0.3.5, + tasty-bench-fit ==0.1, + tasty-checklist ==1.0.6.0, + tasty-dejafu ==2.1.0.1, + tasty-discover ==5.0.0, + tasty-expected-failure ==0.12.3, + tasty-fail-fast ==0.0.3, + tasty-focus ==1.0.1, + tasty-golden ==2.3.5, + tasty-hedgehog ==1.4.0.2, + tasty-hslua ==1.1.1, + tasty-hspec ==1.2.0.4, + tasty-html ==0.4.2.1, + tasty-hunit ==0.10.2, + tasty-hunit-compat ==0.2.0.1, + tasty-inspection-testing ==0.2.1, + tasty-kat ==0.0.3, + tasty-leancheck ==0.0.2, + tasty-lua ==1.1.1, + tasty-papi ==0.1.2.0, + tasty-program ==1.1.0, + tasty-quickcheck ==0.10.2, + tasty-rerun ==1.1.19, + tasty-silver ==3.3.2, + tasty-smallcheck ==0.8.2, + tasty-sugar ==2.2.1.0, + tasty-tap ==0.1.0, + tasty-th ==0.1.7, + tasty-wai ==0.1.2.0, + TCache ==0.13.3, + tce-conf ==1.3, + tdigest ==0.3.1, + teardown ==0.5.0.1, + tempgres-client ==1.0.0, + template ==0.2.0.10, + template-haskell installed, + template-haskell-compat-v0208 ==0.1.9.4, + temporary ==1.3, + temporary-rc ==1.2.0.3, + temporary-resourcet ==0.1.0.1, + tensorflow-test ==0.1.0.0, + tensors ==0.1.5, + termbox ==2.0.0.1, + termbox-banana ==2.0.0, + termbox-bindings-c ==0.1.0.1, + termbox-bindings-hs ==1.0.0, + termbox-tea ==1.0.0, + terminal-progress-bar ==0.4.2, + terminal-size ==0.3.4, + terminfo installed, + termonad ==4.5.0.0, + test-framework ==0.8.2.0, + test-framework-hunit ==0.3.0.2, + test-framework-leancheck ==0.0.4, + test-framework-quickcheck2 ==0.3.0.5, + test-framework-smallcheck ==0.2, + test-fun ==0.1.0.0, + testing-feat ==1.1.1.1, + testing-type-modifiers ==0.1.0.1, + texmath ==0.12.8.7, + text installed, + text-ansi ==0.3.0.1, + text-binary ==0.2.1.1, + text-builder ==0.6.7.2, + text-builder-dev ==0.3.5, + text-builder-linear ==0.1.3, + text-conversions ==0.3.1.1, + text-format ==0.3.2.1, + text-icu ==0.8.0.5, + text-iso8601 ==0.1.1, + text-latin1 ==0.3.1, + text-ldap ==0.1.1.14, + textlocal ==0.1.0.5, + text-manipulate ==0.3.1.0, + text-metrics ==0.3.2, + text-postgresql ==0.0.3.1, + text-printer ==0.5.0.2, + text-regex-replace ==0.1.1.5, + text-rope ==0.2, + text-short ==0.1.6, + text-show ==3.10.5, + text-show-instances ==3.9.8, + text-zipper ==0.13, + tfp ==1.0.2, + tf-random ==0.5, + th-abstraction ==0.5.0.0, + th-bang-compat ==0.0.1.0, + th-compat ==0.1.5, + th-constraint-compat ==0.0.1.0, + th-data-compat ==0.1.3.1, + th-desugar ==1.15, + th-env ==0.1.1, + these ==1.2.1, + these-lens ==1.0.2, + these-optics ==1.0.2, + these-skinny ==0.7.6, + th-expand-syns ==0.4.11.0, + th-extras ==0.0.0.8, + th-lego ==0.3.0.3, + th-lift ==0.8.4, + th-lift-instances ==0.1.20, + th-nowq ==0.1.0.5, + th-orphans ==0.13.14, + th-printf ==0.8, + thread-hierarchy ==0.3.0.2, + thread-local-storage ==0.2, + threads ==0.5.1.8, + threads-extras ==0.1.0.3, + thread-supervisor ==0.2.0.0, + threepenny-gui ==0.9.4.1, + th-reify-compat ==0.0.1.5, + th-reify-many ==0.1.10, + th-strict-compat ==0.1.0.1, + th-test-utils ==1.2.1, + th-utilities ==0.2.5.0, + thyme ==0.4, + tidal ==1.9.5, + tidal-link ==1.0.3, + tile ==0.3.0.0, + time installed, + time-compat ==1.9.6.1, + time-domain ==0.1.0.5, + timeit ==2.0, + time-lens ==0.4.0.2, + timelens ==0.2.0.2, + time-locale-compat ==0.1.1.5, + time-locale-vietnamese ==1.0.0.0, + time-manager ==0.0.1, + time-parsers ==0.2, + timerep ==2.1.0.0, + timers-tick ==0.5.0.4, + timer-wheel ==1.0.0.1, + timespan ==0.4.0.0, + time-units ==1.0.0, + time-units-types ==0.2.0.1, + timezone-olson ==0.2.1, + timezone-olson-th ==0.1.0.11, + timezone-series ==0.1.13, + titlecase ==1.0.1, + tldr ==0.9.2, + tls ==1.8.0, + tls-session-manager ==0.0.4, + tlynx ==0.7.2.2, + tmapchan ==0.0.3, + tmapmvar ==0.0.4, + tmp-proc ==0.5.3.0, + tmp-proc-postgres ==0.5.3.1, + tmp-proc-rabbitmq ==0.5.3.1, + tmp-proc-redis ==0.5.3.1, + token-bucket ==0.1.0.1, + toml-parser ==1.3.2.0, + toml-reader ==0.2.1.0, + toml-reader-parse ==0.1.1.1, + tophat ==1.0.8.0, + topograph ==1.0.1, + torrent ==10000.1.3, + torsor ==0.1.0.1, + tostring ==0.2.1.1, + tracing ==0.0.7.4, + transaction ==0.1.1.4, + transformers installed, + transformers-base ==0.4.6, + transformers-compat ==0.7.2, + transformers-either ==0.1.4, + traverse-with-class ==1.0.1.1, + tree-diff ==0.3.0.1, + tree-fun ==0.8.1.0, + tree-view ==0.5.1, + trie-simple ==0.4.2, + trifecta ==2.1.4, + trimdent ==0.1.0.0, + trivial-constraint ==0.7.0.0, + tsv2csv ==0.1.0.2, + ttc ==1.4.0.0, + ttrie ==0.1.2.2, + tuple ==0.3.0.2, + tuples ==0.1.0.0, + tuples-homogenous-h98 ==0.1.1.0, + tuple-sop ==0.3.1.0, + tuple-th ==0.2.5, + turtle ==1.6.2, + twitter-conduit ==0.6.1, + twitter-types ==0.11.0, + twitter-types-lens ==0.11.0, + typecheck-plugin-nat-simple ==0.1.0.9, + typed-process ==0.2.12.0, + typed-uuid ==0.2.0.0, + type-equality ==1.0.1, + type-errors ==0.2.0.2, + type-flip ==0.1.0.0, + type-fun ==0.1.3, + type-hint ==0.1, + type-level-integers ==0.0.1, + type-level-kv-list ==2.0.2.0, + type-level-natural-number ==2.0, + type-level-numbers ==0.1.1.2, + typelits-witnesses ==0.4.1.0, + type-map ==0.1.7.0, + type-natural ==1.3.0.1, + typenums ==0.1.4, + type-of-html ==1.6.2.0, + type-of-html-static ==0.1.0.2, + type-rig ==0.1, + type-set ==0.1.0.0, + type-spec ==0.4.0.0, + typography-geometry ==1.0.1.0, + typst ==0.5.0.1, + typst-symbols ==0.1.5, + tz ==0.1.3.6, + tzdata ==0.2.20240201.0, + tztime ==0.1.1.0, + ua-parser ==0.7.7.0, + uglymemo ==0.1.0.1, + ulid ==0.3.2.0, + unagi-chan ==0.4.1.4, + unbounded-delays ==0.1.1.1, + unboxed-ref ==0.4.0.0, + unboxing-vector ==0.2.0.0, + uncaught-exception ==0.1.0, + unconstrained ==0.1.0.2, + unexceptionalio ==0.5.1, + unfork ==1.0.0.1, + unicode ==0.0.1.1, + unicode-collation ==0.1.3.6, + unicode-data ==0.4.0.1, + unicode-show ==0.1.1.1, + unicode-transforms ==0.4.0.1, + unidecode ==0.1.0.4, + union-angle ==0.1.0.1, + union-color ==0.1.2.1, + unipatterns ==0.0.0.0, + uniplate ==1.6.13, + uniq-deep ==1.2.1, + unique ==0.0.1, + unique-logic ==0.4.0.1, + unique-logic-tf ==0.5.1, + unit-constraint ==0.0.0, + units ==2.4.1.5, + units-defs ==2.2.1, + units-parser ==0.1.1.5, + universe ==1.2.2, + universe-base ==1.1.3.1, + universe-dependent-sum ==1.3, + universe-instances-extended ==1.1.3, + universe-reverse-instances ==1.1.1, + universe-some ==1.2.1, + universum ==1.8.2.1, + unix installed, + unix-bytestring ==0.4.0.2, + unix-compat ==0.7.2, + unix-time ==0.4.15, + unjson ==0.15.4, + unliftio ==0.2.25.0, + unliftio-core ==0.2.1.0, + unliftio-path ==0.0.2.0, + unliftio-pool ==0.4.3.0, + unliftio-streams ==0.2.0.0, + unlit ==0.4.0.0, + unordered-containers ==0.2.20, + unsafe ==0.0, + uri-bytestring ==0.3.3.1, + uri-bytestring-aeson ==0.1.0.8, + uri-encode ==1.5.0.7, + url ==2.1.3, + urlpath ==11.0.2, + users ==0.5.0.0, + users-test ==0.5.0.1, + utf8-light ==0.4.4.0, + utf8-string ==1.0.2, + utility-ht ==0.0.17.2, + uuid ==1.3.15, + uuid-types ==1.0.5.1, + valida ==1.1.0, + valida-base ==0.2.0, + validate-input ==0.5.0.0, + validation ==1.1.3, + validity ==0.12.1.0, + validity-aeson ==0.2.0.5, + validity-bytestring ==0.4.1.1, + validity-case-insensitive ==0.0.0.0, + validity-containers ==0.5.0.5, + validity-network-uri ==0.0.0.1, + validity-path ==0.4.0.1, + validity-persistent ==0.0.0.0, + validity-primitive ==0.0.0.1, + validity-scientific ==0.2.0.3, + validity-text ==0.3.1.3, + validity-time ==0.5.0.0, + validity-unordered-containers ==0.2.0.3, + validity-uuid ==0.1.0.3, + validity-vector ==0.2.0.3, + valor ==1.0.0.0, + varying ==0.8.1.0, + vault ==0.3.1.5, + vcs-ignore ==0.0.2.0, + vec ==0.5, + vector ==0.13.1.0, + vector-algorithms ==0.9.0.2, + vector-binary-instances ==0.2.5.2, + vector-buffer ==0.4.1, + vector-builder ==0.3.8.5, + vector-bytes-instances ==0.1.1, + vector-extras ==0.2.8.2, + vector-hashtables ==0.1.2.0, + vector-instances ==3.4.2, + vector-mmap ==0.0.3, + vector-rotcev ==0.1.0.2, + vector-sized ==1.5.0, + vector-space ==0.16, + vector-split ==1.0.0.3, + vector-stream ==0.1.0.1, + vector-th-unbox ==0.2.2, + verbosity ==0.4.0.0, + verset ==0.0.1.9, + versions ==6.0.7, + vformat ==0.14.1.0, + vformat-time ==0.1.0.0, + ViennaRNAParser ==1.3.3, + vinyl ==0.14.3, + vinyl-loeb ==0.0.1.0, + Vis ==0.7.7.1, + vivid-osc ==0.5.0.0, + vivid-supercollider ==0.4.1.2, + void ==0.7.3, + vty ==6.1, + vty-crossplatform ==0.4.0.0, + vty-unix ==0.2.0.0, + wai ==3.2.4, + wai-app-static ==3.1.9, + wai-cli ==0.2.3, + wai-conduit ==3.0.0.4, + wai-control ==0.2.0.0, + wai-cors ==0.2.7, + wai-enforce-https ==1.0.0.0, + wai-eventsource ==3.0.0, + wai-extra ==3.1.15, + wai-feature-flags ==0.1.0.8, + wai-handler-launch ==3.0.3.1, + wai-logger ==2.4.1, + wai-middleware-bearer ==1.0.3, + wai-middleware-caching ==0.1.0.2, + wai-middleware-caching-lru ==0.1.0.0, + wai-middleware-caching-redis ==0.2.0.0, + wai-middleware-clacks ==0.1.0.1, + wai-middleware-delegate ==0.1.4.1, + wai-middleware-metrics ==0.2.4, + wai-middleware-prometheus ==1.0.1.0, + wai-middleware-static ==0.9.2, + wai-middleware-throttle ==0.3.0.1, + wai-rate-limit ==0.3.0.0, + wai-rate-limit-redis ==0.2.0.1, + wai-saml2 ==0.5, + wai-session ==0.3.3, + wai-session-postgresql ==0.2.1.3, + wai-session-redis ==0.1.0.5, + wai-slack-middleware ==0.2.0, + wai-transformers ==0.1.0, + wai-websockets ==3.0.1.2, + wakame ==0.1.0.0, + warp ==3.3.31, + warp-tls ==3.4.7, + wave ==0.2.1, + wcwidth ==0.0.2, + webdriver ==0.12.0.0, + webex-teams-api ==0.2.0.1, + webex-teams-conduit ==0.2.0.1, + webpage ==0.0.5.1, + webrtc-vad ==0.1.0.3, + websockets ==0.12.7.3, + websockets-simple ==0.2.0, + websockets-snap ==0.10.3.1, + weigh ==0.0.17, + welford-online-mean-variance ==0.2.0.0, + what4 ==1.5.1, + wide-word ==0.1.6.0, + Win32 installed, + Win32-notify ==0.3.0.3, + windns ==0.1.0.1, + witch ==1.2.1.1, + withdependencies ==0.3.0, + witherable ==0.4.2, + within ==0.2.0.1, + with-location ==0.1.0, + with-utf8 ==1.0.2.4, + witness ==0.6.2, + wizards ==1.0.3, + wl-pprint ==1.2.1, + wl-pprint-annotated ==0.1.0.1, + wl-pprint-text ==1.2.0.2, + word8 ==0.1.3, + word-compat ==0.0.6, + word-trie ==0.3.0, + word-wrap ==0.5, + world-peace ==1.0.2.0, + wrap ==0.0.0, + wraxml ==0.5, + wreq ==0.5.4.3, + wreq-stringless ==0.5.9.1, + writer-cps-transformers ==0.5.6.1, + ws ==0.0.6, + wss-client ==0.3.0.0, + wuss ==2.0.2.0, + X11 ==1.10.3, + X11-xft ==0.3.4, + x11-xim ==0.0.9.0, + x509 ==1.7.7, + x509-store ==1.6.9, + x509-system ==1.6.7, + x509-validation ==1.6.12, + Xauth ==0.1, + xdg-basedir ==0.2.2, + xdg-userdirs ==0.1.0.2, + xeno ==0.6, + xhtml installed, + xlsx ==1.1.2.2, + xml ==1.3.14, + xml-basic ==0.1.3.2, + xmlbf ==0.7, + xmlbf-xeno ==0.2.2, + xmlbf-xmlhtml ==0.2.2, + xml-conduit ==1.9.1.3, + xmlgen ==0.6.2.2, + xml-hamlet ==0.5.0.2, + xml-helpers ==1.0.0, + xmlhtml ==0.2.5.4, + xml-html-qq ==0.1.0.1, + xml-indexed-cursor ==0.1.1.0, + xml-lens ==0.3.1, + xml-picklers ==0.3.6, + xml-to-json-fast ==2.0.0, + xml-types ==0.3.8, + xmonad ==0.17.2, + xor ==0.0.1.3, + xss-sanitize ==0.3.7.2, + xxhash-ffi ==0.2.0.0, + yaml ==0.11.11.2, + yaml-unscrambler ==0.1.0.19, + Yampa ==0.14.10, + yarn-lock ==0.6.5, + yeshql-core ==4.2.0.0, + yesod ==1.6.2.1, + yesod-auth ==1.6.11.3, + yesod-auth-basic ==0.1.0.3, + yesod-auth-hashdb ==1.7.1.7, + yesod-auth-oauth2 ==0.7.2.0, + yesod-core ==1.6.26.0, + yesod-eventsource ==1.6.0.1, + yesod-fb ==0.6.1, + yesod-form ==1.7.6, + yesod-form-bootstrap4 ==3.0.1.1, + yesod-gitrepo ==0.3.0, + yesod-gitrev ==0.2.2, + yesod-markdown ==0.12.6.14, + yesod-middleware-csp ==1.2.0, + yesod-newsfeed ==1.7.0.0, + yesod-page-cursor ==2.0.1.0, + yesod-paginator ==1.1.2.2, + yesod-persistent ==1.6.0.8, + yesod-recaptcha2 ==1.0.2.1, + yesod-routes-flow ==3.0.0.2, + yesod-sitemap ==1.6.0, + yesod-static ==1.6.1.0, + yesod-test ==1.6.16, + yesod-websockets ==0.3.0.3, + yes-precure5-command ==5.5.3, + yi-rope ==0.11, + yjsvg ==0.2.0.1, + yjtools ==0.9.18, + yoga ==0.0.0.8, + youtube ==0.2.1.1, + zenacy-html ==2.1.0, + zenacy-unicode ==1.0.2, + zenc ==0.1.2, + zeromq4-haskell ==0.8.0, + zeromq4-patterns ==0.3.1.0, + zigzag ==0.0.1.0, + zim-parser ==0.2.1.0, + zip ==2.0.1, + zip-archive ==0.4.3.2, + zippers ==0.3.2, + zip-stream ==0.2.2.0, + zlib ==0.6.3.0, + zlib-bindings ==0.1.1.5, + zot ==0.0.3, + zstd ==0.1.3.0, + zxcvbn-hs ==0.3.6 diff --git a/ci/configs/ghc-9.8.2.project b/ci/configs/ghc-9.8.2.project new file mode 100644 index 0000000..c487e40 --- /dev/null +++ b/ci/configs/ghc-9.8.2.project @@ -0,0 +1,3133 @@ +-- NOTE: Due to revisions, this file may not work. See: +-- https://github.com/fpco/stackage-server/issues/232 + +-- Stackage snapshot from: http://www.stackage.org/snapshot/nightly-2024-09-30 +-- Please place this file next to your .cabal file as cabal.config +-- To only use tested packages, uncomment the following line: +-- remote-repo: stackage-nightly-2024-09-30:http://www.stackage.org/nightly-2024-09-30 +with-compiler: ghc-9.8.2 +constraints: abstract-deque ==0.3, + abstract-deque-tests ==0.3, + abstract-par ==0.3.3, + AC-Angle ==1.0, + acc ==0.2.0.3, + ace ==0.6, + acid-state ==0.16.1.3, + action-permutations ==0.0.0.1, + active ==0.2.1, + ad ==4.5.6, + ad-delcont ==0.5.0.0, + adjunctions ==4.4.2, + adler32 ==0.1.2.0, + advent-of-code-api ==0.2.9.1, + aern2-mp ==0.2.16.0, + aern2-real ==0.2.16.0, + aeson ==2.2.3.0, + aeson-attoparsec ==0.0.0, + aeson-casing ==0.2.0.0, + aeson-combinators ==0.1.2.1, + aeson-diff ==1.1.0.13, + aeson-extra ==0.5.1.3, + aeson-generic-compat ==0.0.2.0, + aeson-optics ==1.2.1, + aeson-pretty ==0.8.10, + aeson-qq ==0.8.4, + aeson-schemas ==1.4.2.1, + aeson-typescript ==0.6.3.0, + aeson-unqualified-ast ==1.0.0.3, + aeson-value-parser ==0.19.7.2, + aeson-warning-parser ==0.1.1, + aeson-yak ==0.1.1.3, + aeson-yaml ==1.1.0.1, + Agda ==2.7.0.1, + agda2lagda ==0.2023.6.9, + agreeing ==0.2.2.0, + alarmclock ==0.7.0.6, + alex ==3.5.1.0, + alex-meta ==0.3.0.13, + alex-tools ==0.6.1, + algebra ==4.3.1, + algebraic-graphs ==0.7, + align-audio ==0.0.0.1, + almost-fix ==0.0.2, + alsa-core ==0.5.0.1, + alsa-mixer ==0.3.0.1, + alsa-pcm ==0.6.1.1, + alsa-seq ==0.6.0.9, + alternative-vector ==0.0.0, + alternators ==1.0.0.0, + ALUT ==2.4.0.3, + amqp ==0.23.0, + annotated-exception ==0.3.0.1, + annotated-wl-pprint ==0.7.0, + ansi-terminal ==1.1.1, + ansi-terminal-game ==1.9.3.0, + ansi-terminal-types ==1.1, + ansi-wl-pprint ==1.0.2, + ANum ==0.2.0.2, + aos-signature ==0.1.1, + apecs ==0.9.6, + apecs-gloss ==0.2.4, + apecs-physics ==0.4.6, + api-field-json-th ==0.1.0.2, + ap-normalize ==0.1.0.1, + appar ==0.1.8, + appendful ==0.1.0.0, + appendful-persistent ==0.1.0.1, + appendmap ==0.1.5, + apply-merge ==0.1.1.0, + apply-refact ==0.14.0.0, + apportionment ==0.0.0.4, + approximate ==0.3.5, + approximate-equality ==1.1.0.2, + arbor-lru-cache ==0.1.1.1, + arithmoi ==0.13.0.0, + array installed, + array-memoize ==0.6.0, + arrow-extras ==0.1.0.1, + arrows ==0.4.4.2, + ascii-char ==1.0.1.0, + ascii-group ==1.0.0.17, + ascii-progress ==0.3.3.0, + asn1-encoding ==0.9.6, + asn1-parse ==0.9.5, + asn1-types ==0.3.4, + assert-failure ==0.1.3.0, + assignment ==0.0.1.0, + assoc ==1.1.1, + astro ==0.4.3.0, + async ==2.2.5, + async-extra ==0.2.0.0, + async-pool ==0.9.2, + async-refresh ==0.3.0.0, + async-refresh-tokens ==0.4.0.0, + atom-basic ==0.2.5, + atom-conduit ==0.9.0.1, + atomic-counter ==0.1.2.1, + atomic-primops ==0.8.8, + atomic-write ==0.2.0.7, + attoparsec ==0.14.4, + attoparsec-aeson ==2.2.2.0, + attoparsec-base64 ==0.0.0, + attoparsec-binary ==0.2, + attoparsec-data ==1.0.5.4, + attoparsec-expr ==0.1.1.2, + attoparsec-framer ==0.1.0.9, + attoparsec-iso8601 ==1.1.1.0, + attoparsec-path ==0.0.0.1, + attoparsec-time ==1.0.3.1, + attoparsec-uri ==0.0.9, + audacity ==0.0.2.2, + authenticate ==1.3.5.2, + authenticate-oauth ==1.7, + autodocodec ==0.4.2.2, + autodocodec-nix ==0.0.1.4, + autodocodec-openapi3 ==0.2.1.4, + autodocodec-schema ==0.2.0.0, + autodocodec-servant-multipart ==0.0.0.1, + autodocodec-swagger2 ==0.1.0.0, + autodocodec-yaml ==0.4.0.0, + autoexporter ==2.0.0.12, + automaton ==1.4, + auto-update ==0.2.1, + avro ==0.6.2.1, + aws ==0.24.2, + aws-lambda-haskell-runtime ==4.3.2, + aws-lambda-haskell-runtime-wai ==2.0.2, + aws-sns-verify ==0.0.0.3, + aws-xray-client ==0.1.0.2, + aws-xray-client-persistent ==0.1.0.5, + aws-xray-client-wai ==0.1.0.2, + backprop ==0.2.6.5, + backtracking ==0.1.0, + bank-holiday-germany ==1.3.0.0, + bank-holidays-england ==0.2.0.9, + barbies ==2.1.1.0, + base installed, + base16 ==1.0, + base16-bytestring ==1.0.2.0, + base32 ==0.4, + base32string ==0.9.1, + base58-bytestring ==0.1.0, + base58string ==0.10.0, + base64 ==1.0, + base64-bytestring ==1.2.1.0, + base64-bytestring-type ==1.0.1, + base64-string ==0.2, + base-compat ==0.13.1, + base-compat-batteries ==0.13.1, + basement ==0.0.16, + base-orphans ==0.9.2, + base-prelude ==1.6.1.1, + base-unicode-symbols ==0.2.4.2, + basic-prelude ==0.7.0, + battleship-combinatorics ==0.0.1, + bazel-runfiles ==0.12, + bbdb ==0.8, + bcrypt ==0.0.11, + beam-core ==0.10.1.0, + beam-migrate ==0.5.2.1, + beam-postgres ==0.5.3.1, + beam-sqlite ==0.5.3.0, + bech32 ==1.1.7, + bech32-th ==1.1.7, + benchpress ==0.2.2.23, + bench-show ==0.3.2, + bencode ==0.6.1.1, + bencoding ==0.4.5.5, + benri-hspec ==0.1.0.3, + between ==0.11.0.0, + bhoogle ==0.1.4.3, + bibtex ==0.1.0.7, + bifunctor-classes-compat ==0.1, + bifunctors ==5.6.2, + bimap ==0.5.0, + bimaps ==0.1.0.2, + bin ==0.1.4, + binance-exports ==0.1.2.0, + binary installed, + binary-conduit ==1.3.1, + binaryen ==0.0.6.0, + binary-generic-combinators ==0.4.4.0, + binary-ieee754 ==0.1.0.0, + binary-instances ==1.0.5, + binary-list ==1.1.1.2, + binary-orphans ==1.0.5, + binary-parser ==0.5.7.6, + binary-search ==2.0.0, + binary-shared ==0.8.3, + binary-tagged ==0.3.1, + bindings-DSL ==1.0.25, + bindings-GLFW ==3.3.9.2, + bindings-libzip ==1.0.1, + bindings-uname ==0.1, + BiobaseNewick ==0.0.0.2, + bitarray ==0.0.1.1, + bits ==0.6, + bitset-word8 ==0.1.1.2, + bits-extra ==0.0.2.3, + bitvec ==1.1.5.0, + bitwise ==1.0.0.1, + bitwise-enum ==1.0.1.2, + Blammo ==2.1.1.0, + blank-canvas ==0.7.4, + blas-carray ==0.1.0.2, + blas-comfort-array ==0.0.0.3, + blas-ffi ==0.1, + blas-hs ==0.1.1.0, + blaze-bootstrap ==0.1.0.1, + blaze-builder ==0.4.2.3, + blaze-html ==0.9.2.0, + blaze-markup ==0.8.3.0, + blaze-svg ==0.3.7, + blaze-textual ==0.2.3.1, + bloodhound ==0.23.0.0, + bloomfilter ==2.0.1.2, + bluefin ==0.0.7.0, + bluefin-internal ==0.0.7.0, + bm ==0.2.0.0, + bmp ==1.2.6.4, + bnb-staking-csvs ==0.2.2.0, + BNFC ==2.9.5, + BNFC-meta ==0.6.1, + board-games ==0.4, + bodhi ==0.1.0, + boltzmann-samplers ==0.1.1.0, + Boolean ==0.2.4, + boolsimplifier ==0.1.8, + boomerang ==1.4.9.3, + boomwhacker ==0.0.2, + bordacount ==0.1.0.0, + boring ==0.2.2, + bound ==2.0.7, + BoundedChan ==1.0.3.0, + bounded-qsem ==0.1.0.2, + bounded-queue ==1.0.0, + boundingboxes ==0.2.3, + box ==0.9.3.1, + boxes ==0.1.5, + breakpoint ==0.1.4.0, + brick ==2.4, + brotli ==0.0.0.2, + brotli-streams ==0.0.0.0, + bsb-http-chunked ==0.0.0.4, + bson ==0.4.0.1, + bson-lens ==0.1.1, + btrfs ==0.2.1.0, + buffer-pipe ==0.0, + bugsnag ==1.1.0.0, + bugsnag-hs ==0.2.0.12, + bugsnag-wai ==1.0.0.1, + bugsnag-yesod ==1.0.1.0, + bugzilla-redhat ==1.0.1.1, + burrito ==2.0.1.10, + bv ==0.5, + bv-little ==1.3.2, + bv-sized ==1.0.5, + byteable ==0.1.1, + bytebuild ==0.3.16.2, + byte-count-reader ==0.10.1.11, + bytedump ==1.0, + byte-order ==0.1.3.1, + byteorder ==1.0.4, + bytes ==0.17.3, + byteset ==0.1.1.1, + byteslice ==0.2.13.2, + bytesmith ==0.3.11.1, + bytestring installed, + bytestring-builder ==0.10.8.2.0, + bytestring-conversion ==0.3.2, + bytestring-lexing ==0.5.0.14, + bytestring-strict-builder ==0.4.5.7, + bytestring-to-vector ==0.3.0.1, + bytestring-tree-builder ==0.2.7.12, + bytestring-trie ==0.2.7.5, + bytezap ==1.6.0, + bz2 ==1.0.1.2, + bzip2-clib ==1.0.8, + bzlib ==0.5.2.0, + bzlib-conduit ==0.3.0.3, + c14n ==0.1.0.3, + c2hs ==0.28.8, + Cabal installed, + cabal2nix ==2.19.1, + cabal2spec ==2.7.1, + cabal-add ==0.1, + cabal-appimage ==0.4.0.5, + cabal-clean ==0.2.20230609, + cabal-debian ==5.2.3, + cabal-doctest ==1.0.10, + cabal-file ==0.1.1, + cabal-flatpak ==0.1.2, + cabal-gild ==1.5.0.1, + cabal-install-parsers ==0.6.1.1, + cabal-install-solver ==3.10.2.1, + cabal-plan ==0.7.4.0, + cabal-rpm ==2.2.1, + cabal-sort ==0.1.2, + Cabal-syntax installed, + cache ==0.1.3.0, + cached-json-file ==0.1.1, + cacophony ==0.10.1, + cairo ==0.13.11.0, + cairo-image ==0.1.0.3, + calendar-recycling ==0.0.0.1, + call-alloy ==0.5.0.1, + calligraphy ==0.1.6, + call-plantuml ==0.0.1.3, + call-stack ==0.4.0, + can-i-haz ==0.3.1.1, + capability ==0.5.0.1, + ca-province-codes ==1.0.0.0, + cardano-coin-selection ==1.0.1, + carray ==0.1.6.8, + casa-client ==0.0.2, + casa-types ==0.0.2, + cased ==0.1.0.0, + case-insensitive ==1.2.1.0, + cases ==0.1.4.3, + casing ==0.1.4.1, + cassava ==0.5.3.2, + cassava-conduit ==0.6.6, + cassava-megaparsec ==2.1.1, + cast ==0.1.0.2, + caster ==0.0.3.0, + cayley-client ==0.4.19.4, + cborg ==0.2.10.0, + cborg-json ==0.2.6.0, + cdar-mBound ==0.1.0.4, + c-enum ==0.1.1.3, + cereal ==0.5.8.3, + cereal-conduit ==0.8.0, + cereal-text ==0.1.0.2, + cereal-unordered-containers ==0.1.0.1, + cereal-vector ==0.2.0.1, + cfenv ==0.1.0.0, + cgi ==3001.5.0.1, + chan ==0.0.4.1, + ChannelT ==0.0.0.7, + character-cases ==0.1.0.6, + character-ps ==0.1, + charset ==0.3.10, + Chart ==1.9.5, + Chart-cairo ==1.9.4.1, + Chart-diagrams ==1.9.5.1, + chart-svg ==0.6.1.0, + ChasingBottoms ==1.3.1.15, + check-email ==1.0.2, + checkers ==0.6.0, + checksum ==0.0.0.1, + chimera ==0.4.1.0, + choice ==0.2.4.1, + chronologique ==0.3.1.3, + chronos ==1.1.6.1, + chunked-data ==0.3.1, + cipher-aes ==0.2.11, + cipher-camellia ==0.0.2, + cipher-rc4 ==0.1.4, + circle-packing ==0.1.0.6, + circular ==0.4.0.3, + citeproc ==0.8.1.1, + clash-ghc ==1.8.1, + clash-lib ==1.8.1, + clash-prelude ==1.8.1, + classy-prelude ==1.5.0.3, + classy-prelude-conduit ==1.5.0, + classy-prelude-yesod ==1.5.0, + clay ==0.15.0, + clientsession ==0.9.3.0, + Clipboard ==2.3.2.0, + clock ==0.8.4, + closed ==0.2.0.2, + clumpiness ==0.17.0.2, + ClustalParser ==1.3.0, + cmark ==0.6.1, + cmark-gfm ==0.2.6, + cmark-lucid ==0.1.0.0, + cmdargs ==0.10.22, + codec-beam ==0.2.0, + code-conjure ==0.5.14, + code-page ==0.2.1, + coinor-clp ==0.0.0.2, + cointracking-imports ==0.1.0.2, + collect-errors ==0.1.6.0, + co-log ==0.6.1.0, + co-log-core ==0.3.2.2, + co-log-polysemy ==0.0.1.5, + Color ==0.3.3, + colorful-monoids ==0.2.1.3, + colorize-haskell ==1.0.1, + colour ==2.3.6, + colourista ==0.1.0.2, + columnar ==1.0.0.0, + combinatorial ==0.1.1, + comfort-array ==0.5.5, + comfort-array-shape ==0.0, + comfort-blas ==0.0.3, + comfort-fftw ==0.0.0.1, + comfort-glpk ==0.1, + comfort-graph ==0.0.4, + commonmark ==0.2.6, + commonmark-extensions ==0.2.5.5, + commonmark-pandoc ==0.2.2.1, + commutative ==0.0.2, + commutative-semigroups ==0.2.0.1, + comonad ==5.0.8, + compact ==0.2.0.0, + compactmap ==0.1.4.4, + companion ==0.1.0, + compdata ==0.13.1, + compensated ==0.8.3, + compiler-warnings ==0.1.0, + componentm ==0.0.0.2, + componentm-devel ==0.0.0.2, + composable-associations ==0.1.0.0, + composition ==1.0.2.2, + composition-extra ==2.1.0, + composition-prelude ==3.0.1.0, + concise ==0.1.0.1, + concurrency ==1.11.0.3, + concurrent-extra ==0.7.0.12, + concurrent-output ==1.10.21, + concurrent-split ==0.0.1.1, + concurrent-supply ==0.1.8, + cond ==0.5.1, + conduino ==0.2.4.0, + conduit ==1.3.6, + conduit-aeson ==0.1.1.0, + conduit-algorithms ==0.0.14.0, + conduit-combinators ==1.3.0, + conduit-concurrent-map ==0.1.3, + conduit-extra ==1.3.6, + conduit-parse ==0.2.1.1, + conduit-zstd ==0.0.2.0, + conferer ==1.1.0.0, + conferer-aeson ==1.1.0.2, + config-ini ==0.2.7.0, + configuration-tools ==0.7.0, + configurator ==0.3.0.0, + configurator-export ==0.1.0.1, + configurator-pg ==0.2.10, + config-value ==0.8.3, + constraints ==0.14.2, + constraints-extras ==0.4.0.1, + constraint-tuples ==0.2, + construct ==0.3.1.2, + containers installed, + context ==0.2.1.0, + context-http-client ==0.2.0.2, + context-resource ==0.2.0.2, + context-wai-middleware ==0.2.0.2, + contiguous ==0.6.4.2, + contravariant ==1.5.5, + contravariant-extras ==0.3.5.4, + control-bool ==0.2.1, + control-dsl ==0.2.1.3, + control-monad-free ==0.6.2, + control-monad-omega ==0.3.2, + convertible ==1.1.1.1, + cookie ==0.5.0, + copilot ==4.0, + copilot-c99 ==4.0, + copilot-core ==4.0, + copilot-interpreter ==4.0, + copilot-language ==4.0, + copilot-libraries ==4.0, + copilot-prettyprinter ==4.0, + copilot-theorem ==4.0, + copr-api ==0.2.0, + core-data ==0.3.9.1, + core-program ==0.7.0.0, + core-telemetry ==0.2.9.4, + core-text ==0.3.8.1, + countable ==1.2, + covariance ==0.2.0.1, + cpphs ==1.20.9.1, + cpu ==0.1.2, + cql ==4.0.4, + cql-io ==1.1.1, + crackNum ==3.14, + crc32c ==0.2.2, + credential-store ==0.1.2, + criterion ==1.6.3.0, + criterion-measurement ==0.2.2.0, + cron ==0.7.1, + crypto-api ==0.13.3, + crypto-api-tests ==0.3, + crypto-cipher-tests ==0.0.11, + crypto-cipher-types ==0.0.9, + cryptocompare ==0.1.2, + cryptohash ==0.11.9, + cryptohash-cryptoapi ==0.1.4, + cryptohash-md5 ==0.11.101.0, + cryptohash-sha1 ==0.11.101.0, + cryptohash-sha256 ==0.11.102.1, + cryptohash-sha512 ==0.11.102.0, + crypton ==1.0.0, + crypton-conduit ==0.2.3, + crypton-connection ==0.4.1, + cryptonite ==0.30, + cryptonite-conduit ==0.2.2, + cryptonite-openssl ==0.7, + crypton-x509 ==1.7.7, + crypton-x509-store ==1.6.9, + crypton-x509-system ==1.6.7, + crypton-x509-validation ==1.6.12, + crypto-pubkey-types ==0.4.3, + crypto-random-api ==0.2.0, + crypto-token ==0.1.1, + crypt-sha512 ==0, + csp ==1.4.0, + css-text ==0.1.3.0, + c-struct ==0.1.3.0, + csv ==0.1.2, + ctrie ==0.2, + cubicbezier ==0.6.0.7, + cubicspline ==0.1.2, + cuda ==0.11.0.1, + cue-sheet ==2.0.2, + curl ==1.3.8, + curly-expander ==0.3.0.4, + currency ==0.2.0.0, + currycarbon ==0.3.0.1, + cursor ==0.3.2.0, + cursor-brick ==0.1.0.1, + cursor-fuzzy-time ==0.1.0.0, + cursor-gen ==0.4.0.0, + cutter ==0.0, + cyclotomic ==1.1.2, + data-accessor ==0.2.3.1, + data-accessor-mtl ==0.2.0.5, + data-accessor-transformers ==0.2.1.8, + data-array-byte ==0.1.0.1, + data-binary-ieee754 ==0.4.4, + data-bword ==0.1.0.2, + data-checked ==0.3, + data-clist ==0.2, + data-default ==0.7.1.1, + data-default-class ==0.1.2.0, + data-default-instances-base ==0.1.0.1, + data-default-instances-bytestring ==0.0.1, + data-default-instances-case-insensitive ==0.0.1, + data-default-instances-containers ==0.0.1, + data-default-instances-dlist ==0.0.1, + data-default-instances-old-locale ==0.0.1, + data-default-instances-unordered-containers ==0.0.1, + data-default-instances-vector ==0.0.1, + data-diverse ==4.7.1.0, + data-dword ==0.3.2.1, + data-endian ==0.1.1, + data-fix ==0.3.4, + data-functor-logistic ==0.0, + data-has ==0.4.0.0, + data-hash ==0.2.0.1, + data-interval ==2.1.2, + data-inttrie ==0.1.4, + data-lens-light ==0.1.2.4, + data-memocombinators ==0.5.1, + data-msgpack ==0.0.13, + data-msgpack-types ==0.0.3, + data-or ==1.0.0.7, + data-ordlist ==0.4.7.0, + data-ref ==0.1, + data-reify ==0.6.3, + data-serializer ==0.3.5, + data-sketches ==0.3.1.0, + data-sketches-core ==0.1.0.0, + data-textual ==0.3.0.3, + dataurl ==0.1.0.0, + DAV ==1.3.4, + dbcleaner ==0.1.3, + DBFunctor ==0.1.2.1, + dbus ==1.3.6, + dbus-hslogger ==0.1.0.1, + debian ==4.0.5, + debian-build ==0.10.2.1, + debug-trace-var ==0.2.0, + dec ==0.0.6, + decidable ==0.3.1.1, + Decimal ==0.5.2, + declarative ==0.5.4, + deepseq installed, + deepseq-generics ==0.2.0.0, + deferred-folds ==0.9.18.6, + defun-core ==0.1, + dejafu ==2.4.0.5, + dense-linear-algebra ==0.1.0.0, + dependent-map ==0.4.0.0, + dependent-sum ==0.7.2.0, + dependent-sum-template ==0.2.0.1, + depq ==0.4.2, + deque ==0.4.4.1, + deriveJsonNoPrefix ==0.1.0.1, + derive-storable ==0.3.1.0, + derive-topdown ==0.1.0.0, + deriving-aeson ==0.2.9, + deriving-compat ==0.6.6, + deriving-trans ==0.9.1.0, + detour-via-sci ==1.0.0, + df1 ==0.4.3, + di ==1.3, + diagrams-cairo ==1.4.2.1, + diagrams-core ==1.5.1.1, + diagrams-lib ==1.4.6.2, + diagrams-postscript ==1.5.1.1, + diagrams-rasterific ==1.4.2.3, + diagrams-solve ==0.1.3, + diagrams-svg ==1.4.3.2, + dice ==0.1.1, + di-core ==1.0.4, + dictionary-sharing ==0.1.0.0, + di-df1 ==1.2.1, + Diff ==0.5, + diff-loc ==0.1.0.0, + digest ==0.0.2.1, + digits ==0.3.1, + di-handle ==1.0.1, + dimensional ==1.6, + di-monad ==1.3.5, + directory installed, + directory-ospath-streaming ==0.1.0.2, + directory-tree ==0.12.1, + direct-sqlite ==2.3.29, + dirichlet ==0.1.0.7, + discount ==0.1.1, + discover-instances ==0.1.0.0, + discrimination ==0.5, + disk-free-space ==0.1.0.1, + distributed-closure ==0.5.0.0, + distributed-process ==0.7.7, + distributed-process-monad-control ==0.5.1.3, + distributed-static ==0.3.11, + distribution-nixpkgs ==1.7.1, + distribution-opensuse ==1.1.4, + distributive ==0.6.2.1, + djinn-lib ==0.0.1.4, + djot ==0.1.2.1, + dl-fedora ==1.2, + dlist ==1.0, + dlist-instances ==0.1.1.1, + dlist-nonempty ==0.1.3, + dns ==4.2.0, + dockerfile ==0.2.0, + doclayout ==0.5, + docopt ==0.7.0.8, + doctemplates ==0.11.0.1, + doctest ==0.22.6, + doctest-discover ==0.2.0.0, + doctest-driver-gen ==0.3.0.8, + doctest-exitcode-stdio ==0.0, + doctest-extract ==0.1.2, + doctest-lib ==0.1.1.1, + doctest-parallel ==0.3.1.1, + doldol ==0.4.1.2, + do-list ==1.0.1, + domain ==0.1.1.5, + domain-aeson ==0.1.1.2, + domain-cereal ==0.1.0.1, + domain-core ==0.1.0.4, + domain-optics ==0.1.0.4, + do-notation ==0.1.0.2, + dot ==0.3, + dotenv ==0.12.0.0, + dotgen ==0.4.3, + dotnet-timespan ==0.0.1.0, + double-conversion ==2.0.5.0, + download ==0.3.2.7, + download-curl ==0.1.4, + DPutils ==0.1.1.0, + drawille ==0.1.3.0, + drifter ==0.3.0, + drifter-postgresql ==0.2.1, + drifter-sqlite ==0.1.0.0, + dsp ==0.2.5.2, + dual-tree ==0.2.3.1, + dublincore-xml-conduit ==0.1.0.3, + duration ==0.2.0.0, + dvorak ==0.1.0.0, + dynamic-state ==0.3.1, + dyre ==0.9.2, + eap ==0.9.0.2, + Earley ==0.13.0.1, + easy-file ==0.2.5, + easy-logger ==0.1.0.7, + Ebnf2ps ==1.0.15, + echo ==0.1.4, + ecstasy ==0.2.1.0, + ed25519 ==0.0.5.0, + edit-distance ==0.2.2.1, + edit-distance-vector ==1.0.0.4, + editor-open ==0.6.0.0, + effectful ==2.3.1.0, + effectful-core ==2.3.1.0, + effectful-plugin ==1.1.0.3, + effectful-th ==1.0.0.2, + egison-pattern-src ==0.2.1.2, + either ==5.0.2, + either-unwrap ==1.1, + ekg ==0.4.1.0, + ekg-core ==0.1.1.7, + ekg-json ==0.1.1.0, + ekg-statsd ==0.2.6.0, + elerea ==2.9.0, + elf ==0.31, + eliminators ==0.9.4, + elm2nix ==0.4.0, + elm-core-sources ==1.0.0, + elm-export ==0.6.0.1, + elm-street ==0.2.2.1, + elm-syntax ==0.3.3.0, + elynx ==0.7.2.2, + elynx-markov ==0.7.2.2, + elynx-nexus ==0.7.2.2, + elynx-seq ==0.7.2.2, + elynx-tools ==0.7.2.2, + elynx-tree ==0.7.2.2, + emacs-module ==0.2.1, + email-validate ==2.3.2.21, + emd ==0.2.0.0, + emojis ==0.1.4.1, + enclosed-exceptions ==1.0.3, + encoding ==0.8.9, + ENIG ==0.0.1.0, + entropy ==0.4.1.10, + enummapset ==0.7.3.0, + enumset ==0.1, + enum-subset-generate ==0.1.0.3, + enum-text ==0.5.3.0, + envelope ==0.2.2.0, + envparse ==0.6.0, + envy ==2.1.3.0, + epub-metadata ==5.4, + eq ==4.3, + equal-files ==0.0.5.4, + equational-reasoning ==0.7.0.3, + equivalence ==0.4.1, + erf ==2.0.0.0, + errata ==0.4.0.2, + error ==1.0.0.0, + errorcall-eq-instance ==0.3.0, + error-or ==0.3.0, + error-or-utils ==0.2.0, + errors ==2.3.0, + errors-ext ==0.4.2, + ersatz ==0.5, + esqueleto ==3.5.11.2, + event-list ==0.1.3, + every ==0.0.1, + evm-opcodes ==0.1.2, + exact-combinatorics ==0.2.0.11, + exact-pi ==0.5.0.2, + exception-hierarchy ==0.1.0.11, + exception-mtl ==0.4.0.2, + exceptions installed, + exception-transformers ==0.4.0.12, + executable-hash ==0.2.0.4, + executable-path ==0.0.3.1, + exinst ==0.9, + exit-codes ==1.0.0, + exomizer ==1.0.0, + exon ==1.7.0.0, + expiring-cache-map ==0.0.6.1, + explainable-predicates ==0.1.2.4, + explicit-exception ==0.2, + exp-pairs ==0.2.1.0, + express ==1.0.16, + extended-reals ==0.2.4.0, + extensible ==0.9.1, + extensible-effects ==5.0.0.1, + extensible-exceptions ==0.1.1.4, + extra ==1.7.16, + extractable-singleton ==0.0.1, + extra-data-yj ==0.1.0.0, + extrapolate ==0.4.6, + fail ==4.9.0.0, + FailT ==0.1.2.0, + fakedata-parser ==0.1.0.0, + fakefs ==0.3.0.2, + fakepull ==0.3.0.2, + faktory ==1.1.3.0, + falsify ==0.2.0, + fast-builder ==0.1.4.0, + fast-digits ==0.3.2.0, + fast-logger ==3.2.3, + fast-math ==1.0.2, + fast-myers-diff ==0.0.1, + fbrnch ==1.5, + fcf-family ==0.2.0.1, + fdo-notify ==0.3.1, + feature-flags ==0.1.0.1, + fedora-releases ==0.1.0, + fedora-repoquery ==0.7.1, + feed ==1.3.2.1, + FenwickTree ==0.1.2.1, + fft ==0.1.8.7, + fftw-ffi ==0.1, + fgl ==5.8.2.0, + fgl-arbitrary ==0.2.0.6, + fields-and-cases ==0.2.0.0, + fields-json ==0.4.0.0, + filecache ==0.5.1, + file-embed ==0.0.16.0, + file-embed-lzma ==0.1, + file-io ==0.1.4, + filelock ==0.1.1.7, + filemanip ==0.3.6.3, + file-modules ==0.1.2.4, + filepath installed, + file-path-th ==0.1.0.0, + filepattern ==0.1.3, + fileplow ==0.1.0.0, + filter-logger ==0.6.0.0, + filtrable ==0.1.6.0, + fin ==0.3.1, + FindBin ==0.0.5, + fingertree ==0.1.5.0, + finite-typelits ==0.2.1.0, + first-class-families ==0.8.1.0, + fits-parse ==0.4.2, + fitspec ==0.4.10, + fixed ==0.3, + fixed-length ==0.2.3.1, + fixed-vector ==1.2.3.0, + fixed-vector-hetero ==0.6.1.1, + fix-whitespace ==0.1, + flac ==0.2.1, + flac-picture ==0.1.3, + flags-applicative ==0.1.0.3, + flat ==0.6, + flatparse ==0.5.1.0, + flay ==0.5, + flexible-defaults ==0.0.3, + FloatingHex ==0.5, + floatshow ==0.2.4, + flow ==2.0.0.5, + flush-queue ==1.0.0, + fmlist ==0.9.4, + fmt ==0.6.3.0, + fn ==0.3.0.2, + focus ==1.0.3.2, + focuslist ==0.1.1.0, + foldable1-classes-compat ==0.1, + fold-debounce ==0.2.0.12, + foldl ==1.4.17, + folds ==0.7.8, + FontyFruity ==0.5.3.5, + force-layout ==0.4.0.6, + foreign-store ==0.2.1, + ForestStructures ==0.0.1.1, + forkable-monad ==0.2.0.3, + forma ==1.2.0, + formatn ==0.3.0.1, + format-numbers ==0.1.0.1, + formatting ==7.2.0, + foundation ==0.0.30, + fourmolu ==0.15.0.0, + Frames ==0.7.4.2, + free ==5.2, + free-alacarte ==1.0.0.7, + free-categories ==0.2.0.2, + free-foil ==0.1.0, + freenect ==1.2.1, + freer-par-monad ==0.1.0.0, + freer-simple ==1.2.1.2, + freetype2 ==0.2.0, + free-vl ==0.1.4, + friendly-time ==0.4.1, + frisby ==0.2.5, + from-sum ==0.2.3.0, + frontmatter ==0.1.0.2, + fsnotify ==0.4.1.0, + ftp-client ==0.5.1.6, + funcmp ==1.9, + function-builder ==0.3.0.1, + functor-classes-compat ==2.0.0.2, + functor-combinators ==0.4.1.3, + functor-products ==0.1.2.2, + fused-effects ==1.1.2.3, + fusion-plugin ==0.2.7, + fusion-plugin-types ==0.1.0, + fuzzcheck ==0.1.1, + fuzzy ==0.1.1.0, + fuzzy-dates ==0.1.1.2, + fuzzyset ==0.3.2, + fuzzy-time ==0.3.0.0, + gauge ==0.2.5, + gd ==3000.7.3, + gdp ==0.0.3.0, + gemini-exports ==0.1.0.2, + general-games ==1.1.1, + generically ==0.1.1, + generic-arbitrary ==1.0.1, + generic-constraints ==1.1.1.1, + generic-data ==1.1.0.0, + generic-data-functions ==0.6.0, + generic-data-surgery ==0.3.0.0, + generic-deriving ==1.14.5, + generic-functor ==1.1.0.0, + generic-lens ==2.2.2.0, + generic-lens-core ==2.2.1.0, + generic-monoid ==0.1.0.1, + generic-optics ==2.2.1.0, + GenericPretty ==1.2.2, + generic-random ==1.5.0.1, + generics-eot ==0.4.0.1, + generics-sop ==0.5.1.4, + generics-sop-lens ==0.2.1, + generic-type-asserts ==0.3.0, + generic-type-functions ==0.1.0, + geniplate-mirror ==0.7.10, + genvalidity ==1.1.1.0, + genvalidity-aeson ==1.0.0.1, + genvalidity-appendful ==0.1.0.0, + genvalidity-bytestring ==1.0.0.1, + genvalidity-case-insensitive ==0.0.0.1, + genvalidity-containers ==1.0.0.2, + genvalidity-criterion ==1.1.0.0, + genvalidity-hspec ==1.0.0.3, + genvalidity-hspec-aeson ==1.0.0.0, + genvalidity-hspec-binary ==1.0.0.0, + genvalidity-hspec-cereal ==1.0.0.0, + genvalidity-hspec-hashable ==1.0.0.1, + genvalidity-hspec-optics ==1.0.0.0, + genvalidity-hspec-persistent ==1.0.0.0, + genvalidity-mergeful ==0.3.0.1, + genvalidity-mergeless ==0.3.0.0, + genvalidity-network-uri ==0.0.0.0, + genvalidity-path ==1.0.0.1, + genvalidity-persistent ==1.0.0.2, + genvalidity-property ==1.0.0.0, + genvalidity-scientific ==1.0.0.0, + genvalidity-sydtest ==1.0.0.0, + genvalidity-sydtest-aeson ==1.0.0.0, + genvalidity-sydtest-hashable ==1.0.0.1, + genvalidity-sydtest-lens ==1.0.0.0, + genvalidity-sydtest-persistent ==1.0.0.0, + genvalidity-text ==1.0.0.1, + genvalidity-time ==1.0.0.1, + genvalidity-typed-uuid ==0.1.0.1, + genvalidity-unordered-containers ==1.0.0.1, + genvalidity-uuid ==1.0.0.1, + genvalidity-vector ==1.0.0.0, + geodetics ==0.1.2, + getopt-generics ==0.13.1.0, + ghc installed, + ghc-bignum installed, + ghc-bignum-orphans ==0.1.1, + ghc-byteorder ==4.11.0.0.10, + ghc-check ==0.5.0.8, + ghc-compact installed, + ghc-core ==0.5.6, + ghc-events ==0.19.0.1, + ghc-exactprint ==1.8.0.0, + ghc-hs-meta ==0.1.4.0, + ghcid ==0.8.9, + ghci-hexcalc ==0.1.1.0, + ghcjs-codemirror ==0.0.0.2, + ghcjs-dom ==0.9.9.2, + ghcjs-dom-jsaddle ==0.9.9.0, + ghcjs-perch ==0.3.3.3, + ghc-lib ==9.8.2.20240223, + ghc-lib-parser ==9.8.2.20240223, + ghc-lib-parser-ex ==9.8.0.2, + ghc-parser ==0.2.6.0, + ghc-paths ==0.1.0.12, + ghc-prim installed, + ghc-source-gen ==0.4.5.0, + ghc-syntax-highlighter ==0.0.11.0, + ghc-tcplugins-extra ==0.4.6, + ghc-trace-events ==0.1.2.9, + ghc-typelits-extra ==0.4.7, + ghc-typelits-knownnat ==0.7.12, + ghc-typelits-natnormalise ==0.7.10, + ghc-typelits-presburger ==0.7.4.0, + ghost-buster ==0.1.1.0, + ghostscript-parallel ==0.0.1, + gi-atk ==2.0.28, + gi-cairo ==1.0.30, + gi-cairo-connector ==0.1.1, + gi-cairo-render ==0.1.2, + gi-dbusmenu ==0.4.14, + gi-dbusmenugtk3 ==0.4.15, + gi-freetype2 ==2.0.5, + gi-gdk ==3.0.29, + gi-gdkpixbuf ==2.0.32, + gi-gdkx11 ==3.0.16, + gi-gio ==2.0.35, + gi-glib ==2.0.30, + gi-gmodule ==2.0.6, + gi-gobject ==2.0.31, + gi-graphene ==1.0.8, + gi-gtk ==3.0.43, + gi-gtk-hs ==0.3.16, + gi-gtksource ==3.0.29, + gi-harfbuzz ==0.0.10, + gi-javascriptcore ==4.0.28, + gio ==0.13.11.0, + gi-pango ==1.0.30, + gi-soup ==2.4.29, + githash ==0.1.7.0, + github ==0.29, + github-release ==2.0.0.11, + github-rest ==1.2.1, + github-types ==0.2.1, + github-webhooks ==0.17.0, + gitlab-haskell ==1.0.1.0, + git-lfs ==1.2.2, + gitlib ==3.1.3, + git-mediate ==1.1.0, + gitrev ==1.3.1, + gi-vte ==2.91.33, + gi-webkit2 ==4.0.31, + gi-xlib ==2.0.14, + gl ==0.9, + glabrous ==2.0.6.3, + glasso ==0.1.0, + GLFW-b ==3.3.9.1, + glib ==0.13.11.0, + glib-stopgap ==0.1.0.0, + Glob ==0.10.2, + glob-posix ==0.2.0.1, + gloss ==1.13.2.2, + gloss-algorithms ==1.13.0.3, + gloss-rendering ==1.13.1.2, + glpk-headers ==0.5.1, + GLURaw ==2.0.0.5, + GLUT ==2.7.0.16, + gnuplot ==0.5.7, + goldplate ==0.2.1.1, + google-isbn ==1.0.3, + google-oauth2-jwt ==0.3.3.1, + gopher-proxy ==0.1.1.3, + gpolyline ==0.1.0.1, + graph-core ==0.3.0.0, + graphite ==0.10.0.1, + graphql ==1.3.0.0, + graphql-client ==1.2.4, + graphql-spice ==1.0.3.0, + graphs ==0.7.2, + graphula ==2.1.0.0, + graphviz ==2999.20.2.0, + graph-wrapper ==0.2.6.0, + gravatar ==0.8.1, + greskell ==2.0.3.1, + greskell-core ==1.0.0.2, + greskell-websocket ==1.0.0.2, + gridtables ==0.1.0.0, + grisette ==0.8.0.0, + groom ==0.1.2.1, + group-by-date ==0.1.0.5, + groups ==0.5.3, + gtk ==0.15.9, + gtk2hs-buildtools ==0.13.11.0, + gtk3 ==0.15.9, + gtk-sni-tray ==0.1.8.1, + gtk-strut ==0.1.3.2, + guarded-allocation ==0.0.1, + hackage-cli ==0.1.0.2, + hackage-db ==2.1.3, + hackage-security ==0.6.2.6, + hackage-security-HTTP ==0.1.1.2, + haddock-library ==1.11.0, + haha ==0.3.1.1, + hakyll ==4.16.2.2, + hakyll-convert ==0.3.0.5, + hal ==1.1, + half ==0.3.1, + hall-symbols ==0.1.0.6, + hamlet ==1.2.0, + hamtsolo ==1.0.4, + HandsomeSoup ==0.4.2, + handwriting ==0.1.0.3, + happstack-jmacro ==7.0.12.6, + happstack-server ==7.9.2.1, + happstack-server-tls ==7.2.1.6, + happy ==2.0.2, + happy-lib ==2.0.2, + happy-meta ==0.2.1.0, + HasBigDecimal ==0.2.0.0, + hashable ==1.4.7.0, + hashids ==1.1.1.0, + hashmap ==1.3.3, + hashtables ==1.3.1, + haskeline installed, + haskell-gi ==0.26.11, + haskell-gi-base ==0.26.8, + haskell-gi-overloading ==1.0, + haskell-lexer ==1.1.1, + haskell-src ==1.0.4.1, + haskell-src-exts ==1.23.1, + haskell-src-exts-simple ==1.23.0.0, + haskell-src-exts-util ==0.2.5, + haskell-src-meta ==0.8.14, + haskey-btree ==0.3.0.1, + haskintex ==0.8.0.2, + haskoin-core ==1.1.0, + haskoin-node ==1.1.3, + haskoin-store-data ==1.4.0, + hasktags ==0.73.0, + hasql ==1.8.1.1, + hasql-dynamic-statements ==0.3.1.7, + hasql-implicits ==0.2, + hasql-interpolate ==1.0.1.0, + hasql-listen-notify ==0.1.0.1, + hasql-migration ==0.3.1, + hasql-optparse-applicative ==0.8.0.1, + hasql-pool ==1.2.0.2, + hasql-th ==0.4.0.22, + hasql-transaction ==1.1.1.2, + has-transformers ==0.1.0.4, + hasty-hamiltonian ==1.3.4, + HaTeX ==3.22.4.2, + HaXml ==1.25.13, + haxr ==3000.11.5.1, + HCodecs ==0.5.2, + hdaemonize ==0.5.7, + HDBC ==2.4.0.4, + HDBC-session ==0.1.2.1, + headed-megaparsec ==0.2.1.3, + heap ==1.0.4, + heaps ==0.4, + heatshrink ==0.1.0.0, + hebrew-time ==0.1.2, + hedgehog ==1.5, + hedgehog-classes ==0.2.5.4, + hedgehog-corpus ==0.2.0, + hedgehog-fn ==1.0, + hedgehog-quickcheck ==0.1.1, + hedis ==0.15.2, + hedn ==0.3.0.4, + hegg ==0.5.0.0, + heist ==1.1.1.2, + here ==1.2.14, + heredoc ==0.2.0.0, + heterocephalus ==1.0.5.7, + hex ==0.2.0, + hexml ==0.3.5, + hexml-lens ==0.2.2, + hexpat ==0.20.13, + hex-text ==0.1.0.9, + hformat ==0.3.3.1, + hfsevents ==0.1.7, + hgal ==2.0.0.3, + hidapi ==0.1.8, + hie-bios ==0.14.0, + hi-file-parser ==0.1.6.0, + hindent ==6.2.0, + hinfo ==0.0.3.0, + hinotify ==0.4.1, + hint ==0.9.0.8, + histogram-fill ==0.9.1.0, + hjsmin ==0.2.1, + hkd-default ==1.1.0.0, + hkgr ==0.4.6, + hledger ==1.40, + hledger-lib ==1.40, + hledger-stockquotes ==0.1.3.1, + hledger-ui ==1.40, + hledger-web ==1.40, + hlibcpuid ==0.2.0, + hlibgit2 ==0.18.0.16, + hlibsass ==0.1.10.1, + hlint ==3.8, + hmatrix ==0.20.2, + hmatrix-backprop ==0.1.3.0, + hmatrix-gsl ==0.19.0.1, + hmatrix-gsl-stats ==0.4.1.8, + hmatrix-morpheus ==0.1.1.2, + hmatrix-special ==0.19.0.0, + hmatrix-vector-sized ==0.1.3.0, + hmm-lapack ==0.5.0.1, + HMock ==0.5.1.2, + hmpfr ==0.4.5, + hnix-store-core ==0.8.0.0, + hoauth2 ==2.14.0, + hoogle ==5.0.18.4, + hopenssl ==2.2.5, + horizontal-rule ==0.6.0.0, + hosc ==0.20, + hostname ==1.0, + hostname-validate ==1.0.0, + hourglass ==0.2.12, + hourglass-orphans ==0.1.0.0, + hp2pretty ==0.10, + hpack ==0.37.0, + hpc installed, + hpc-codecov ==0.6.2.0, + hpc-lcov ==1.1.2, + HPDF ==1.7, + hpp ==0.6.5, + hpqtypes ==1.12.0.0, + hpqtypes-extras ==1.16.4.4, + hquantlib-time ==0.1.0, + hreader ==1.1.1, + hreader-lens ==0.1.3.0, + hruby ==0.5.1.0, + hsass ==0.8.0, + hs-bibutils ==6.10.0.0, + hsc2hs ==0.68.10, + hs-captcha ==1.0, + hscolour ==1.25, + hsdns ==1.8, + hse-cpp ==0.2, + hsemail ==2.2.2, + hset ==2.2.0, + HSet ==0.0.2, + hs-GeoIP ==0.3, + hsignal ==0.2.7.5, + hsini ==0.5.2.2, + hsinstall ==2.8, + HSlippyMap ==3.0.1, + hslogger ==1.3.1.1, + hslua ==2.3.1, + hslua-aeson ==2.3.1.1, + hslua-classes ==2.3.1, + hslua-cli ==1.4.3, + hslua-core ==2.3.2, + hslua-list ==1.1.3, + hslua-marshalling ==2.3.1, + hslua-module-doclayout ==1.1.1.2, + hslua-module-path ==1.1.1, + hslua-module-system ==1.1.2, + hslua-module-text ==1.1.1, + hslua-module-version ==1.1.1, + hslua-module-zip ==1.1.3, + hslua-objectorientation ==2.3.1, + hslua-packaging ==2.3.1, + hslua-repl ==0.1.2, + hslua-typing ==0.1.1, + hsndfile ==0.8.0, + hsndfile-vector ==0.5.2, + HsOpenSSL ==0.11.7.8, + HsOpenSSL-x509-system ==0.1.0.4, + hspec ==2.11.9, + hspec-api ==2.11.9, + hspec-attoparsec ==0.1.0.2, + hspec-checkers ==0.1.0.2, + hspec-contrib ==0.5.2, + hspec-core ==2.11.9, + hspec-discover ==2.11.9, + hspec-expectations ==0.8.4, + hspec-expectations-json ==1.0.2.1, + hspec-expectations-lifted ==0.10.0, + hspec-expectations-pretty-diff ==0.7.2.6, + hspec-golden ==0.2.2.0, + hspec-golden-aeson ==0.9.0.0, + hspec-hedgehog ==0.3.0.0, + hspec-junit-formatter ==1.1.2.1, + hspec-leancheck ==0.0.6, + hspec-megaparsec ==2.2.1, + hspec-meta ==2.11.9, + hspec-need-env ==0.1.0.11, + hspec-parsec ==0, + hspec-smallcheck ==0.5.3, + hspec-tmp-proc ==0.7.0.0, + hspec-wai ==0.11.1, + hspec-wai-json ==0.11.0, + hspec-webdriver ==1.2.2, + hs-php-session ==0.0.9.3, + hstatistics ==0.3.1, + HStringTemplate ==0.8.8, + HSvm ==1.0.3.32, + HsYAML ==0.2.1.4, + HsYAML-aeson ==0.2.0.1, + hsyslog ==5.0.2, + htaglib ==1.2.1, + HTF ==0.15.0.2, + html ==1.0.1.2, + html-conduit ==1.3.2.2, + html-email-validate ==0.2.0.0, + html-entities ==1.1.4.7, + html-entity-map ==0.1.0.0, + html-parse ==0.2.1.0, + HTTP ==4000.4.1, + http2 ==5.3.4, + http-api-data ==0.6.1, + http-api-data-qq ==0.1.0.0, + http-client ==0.7.17, + http-client-openssl ==0.3.3, + http-client-overrides ==0.1.1.0, + http-client-restricted ==0.1.0, + http-client-tls ==0.3.6.3, + http-common ==0.8.3.4, + http-conduit ==2.3.9, + http-date ==0.0.11, + http-directory ==0.1.10, + http-download ==0.2.1.0, + httpd-shed ==0.4.1.2, + http-io-streams ==0.1.7.0, + http-link-header ==1.2.1, + http-media ==0.8.1.1, + http-query ==0.1.3, + http-reverse-proxy ==0.6.1.0, + http-semantics ==0.2.1, + http-streams ==0.8.9.9, + http-types ==0.12.4, + human-readable-duration ==0.2.1.4, + HUnit ==1.6.2.0, + HUnit-approx ==1.1.1.1, + hunit-dejafu ==2.0.0.6, + hvect ==0.4.0.1, + hvega ==0.12.0.7, + hw-bits ==0.7.2.2, + hw-conduit-merges ==0.2.1.0, + hw-diagnostics ==0.0.1.0, + hweblib ==0.6.3, + hw-excess ==0.2.3.0, + hw-hedgehog ==0.1.1.1, + hw-int ==0.0.2.0, + hw-json-simd ==0.1.1.2, + hwk ==0.6, + hw-kafka-client ==5.3.0, + hw-parser ==0.1.1.0, + hw-prim ==0.6.3.2, + hw-rankselect-base ==0.3.4.1, + hw-streams ==0.0.1.1, + hw-string-parse ==0.0.0.5, + hxt ==9.3.1.22, + hxt-charproperties ==9.5.0.0, + hxt-css ==0.1.0.3, + hxt-curl ==9.1.1.1, + hxt-expat ==9.1.1, + hxt-http ==9.1.5.2, + hxt-regex-xmlschema ==9.2.0.7, + hxt-tagsoup ==9.1.4, + hxt-unicode ==9.0.2.4, + hybrid-vectors ==0.2.4, + hyper ==0.2.1.1, + hyperloglog ==0.4.6, + hyphenation ==0.8.2, + iconv ==0.4.1.3, + identicon ==0.2.3, + ieee754 ==0.8.0, + if ==0.1.0.0, + IfElse ==0.85, + iff ==0.0.6.1, + ihaskell ==0.11.0.0, + ihaskell-hvega ==0.5.0.5, + ihs ==0.1.0.3, + ilist ==0.4.0.1, + imagesize-conduit ==1.1, + Imlib ==0.1.2, + immortal ==0.3, + immortal-queue ==0.1.0.1, + imp ==1.0.2.1, + inbox ==0.2.0, + incipit-base ==0.6.0.0, + incipit-core ==0.6.0.0, + include-file ==0.1.0.4, + incremental ==0.3.1, + incremental-parser ==0.5.1, + indents ==0.5.0.1, + indexed ==0.1.3, + indexed-containers ==0.1.0.2, + indexed-list-literals ==0.2.1.3, + indexed-profunctors ==0.1.1.1, + indexed-transformers ==0.1.0.4, + indexed-traversable ==0.1.4, + indexed-traversable-instances ==0.1.2, + inf-backprop ==0.1.0.2, + infer-license ==0.2.0, + infinite-list ==0.1.1, + influxdb ==1.9.3.2, + ini ==0.4.2, + inj ==1.0, + inline-c ==0.9.1.10, + inline-c-cpp ==0.5.0.2, + input-parsers ==0.3.0.2, + insert-ordered-containers ==0.2.6, + inspection-testing ==0.5.0.3, + int-cast ==0.2.0.0, + integer-conversion ==0.1.1, + integer-gmp installed, + integer-logarithms ==1.0.3.1, + integer-roots ==1.0.2.0, + integration ==0.2.1, + intern ==0.9.5, + interpolate ==0.2.1, + interpolatedstring-perl6 ==1.0.2, + interpolation ==0.1.1.2, + Interpolation ==0.3.0, + IntervalMap ==0.6.2.1, + intervals ==0.9.2, + intset-imperative ==0.1.0.0, + int-supply ==1.0.0, + invariant ==0.6.3, + invertible ==0.2.0.8, + invertible-grammar ==0.1.3.5, + io-machine ==0.2.0.0, + io-manager ==0.1.0.4, + io-memoize ==1.1.1.0, + io-region ==0.1.1, + io-storage ==0.3, + io-streams ==1.5.2.2, + io-streams-haproxy ==1.0.1.0, + ip ==1.7.8, + ip6addr ==2.0.0, + iproute ==1.7.14, + IPv6Addr ==2.0.6, + IPv6DB ==0.3.3.3, + ipynb ==0.2, + ipython-kernel ==0.11.0.0, + irc ==0.6.1.1, + irc-ctcp ==0.1.3.1, + isbn ==1.1.0.5, + islink ==0.1.0.0, + iso3166-country-codes ==0.20140203.8, + iso639 ==0.1.0.3, + iso8601-time ==0.1.5, + isocline ==1.0.9, + isomorphism-class ==0.1.1, + ix-shapable ==0.1.0, + jack ==0.7.2.2, + jailbreak-cabal ==1.4, + jalaali ==1.0.0.0, + java-adt ==1.0.20231204, + jira-wiki-markup ==1.5.1, + jmacro ==0.6.18, + jose ==0.11, + jose-jwt ==0.10.0, + journalctl-stream ==0.6.0.6, + jsaddle ==0.9.9.2, + jsaddle-dom ==0.9.9.2, + js-chart ==2.9.4.1, + js-dgtable ==0.5.2, + js-flot ==0.8.3, + js-jquery ==3.3.1, + json ==0.11, + json-feed ==2.0.0.12, + jsonifier ==0.2.1.3, + jsonpath ==0.3.0.0, + json-rpc ==1.1.1, + json-spec ==1.1.0.0, + json-spec-elm ==0.4.0.5, + json-spec-elm-servant ==0.4.2.2, + json-spec-openapi ==1.0.0.0, + json-stream ==0.4.6.0, + JuicyCairo ==0.1.0.0, + JuicyPixels ==3.3.9, + JuicyPixels-extra ==0.6.0, + JuicyPixels-scale-dct ==0.1.2, + junit-xml ==0.1.0.3, + justified-containers ==0.3.0.0, + kan-extensions ==5.2.6, + kansas-comet ==0.4.2, + katip ==0.8.8.2, + katip-logstash ==0.1.0.2, + katip-wai ==0.2.0.0, + kazura-queue ==0.1.0.4, + kdt ==0.2.6, + keep-alive ==0.2.1.0, + keter ==2.1.7, + keuringsdienst ==1.0.2.0, + keycode ==0.2.2, + keyed-vals ==0.2.3.1, + keyed-vals-hspec-tests ==0.2.3.1, + keyed-vals-mem ==0.2.3.1, + keyed-vals-redis ==0.2.3.1, + keys ==3.12.3, + ki ==1.0.1.2, + kind-apply ==0.4.0.0, + kind-generics ==0.5.0.0, + ki-unlifted ==1.0.0.2, + kmeans ==0.1.3, + knob ==0.2.2, + koji ==0.0.2, + koji-tool ==1.2, + kvitable ==1.1.0.1, + labels ==0.3.3, + lackey ==2.0.0.8, + lame ==0.2.2, + language-avro ==0.1.4.0, + language-c ==0.9.3, + language-c99 ==0.2.0, + language-c99-simple ==0.3.0, + language-c99-util ==0.2.0, + language-c-quote ==0.13.0.2, + language-docker ==13.0.0, + language-dot ==0.1.2, + language-glsl ==0.3.0, + language-java ==0.2.9, + language-javascript ==0.7.1.0, + language-lua ==0.11.0.2, + language-nix ==2.2.0, + language-protobuf ==1.0.1, + language-python ==0.5.8, + language-thrift ==0.13.0.0, + lapack ==0.5.2, + lapack-carray ==0.0.3, + lapack-comfort-array ==0.0.1, + lapack-ffi ==0.0.3, + lapack-ffi-tools ==0.1.3.1, + lapack-hmatrix ==0.0.0.2, + largeword ==1.2.5, + latex ==0.1.0.4, + lattices ==2.2.1, + lawful ==0.1.0.0, + lazy-csv ==0.5.1, + lazyio ==0.1.0.4, + lazyppl ==1.0, + lazysmallcheck ==0.6, + lca ==0.4, + leancheck ==1.0.2, + leancheck-instances ==0.0.5, + leapseconds-announced ==2017.1.0.1, + learn-physics ==0.6.7, + leb128-cereal ==1.2, + lens ==5.3.2, + lens-action ==0.2.6, + lens-aeson ==1.2.3, + lens-csv ==0.1.1.0, + lens-family ==2.1.3, + lens-family-core ==2.1.3, + lens-family-th ==0.5.3.1, + lens-misc ==0.0.2.0, + lens-properties ==4.11.1, + lens-regex ==0.1.3, + lens-regex-pcre ==1.1.0.0, + lentil ==1.5.7.0, + LetsBeRational ==1.0.0.0, + leveldb-haskell ==0.6.5, + lexer-applicative ==2.1.0.2, + libBF ==0.6.8, + libffi ==0.2.1, + libmpd ==0.10.0.1, + liboath-hs ==0.0.1.2, + libyaml ==0.1.4, + libyaml-clib ==0.2.5, + lifted-async ==0.10.2.5, + lifted-base ==0.2.3.12, + lift-generics ==0.2.1, + lift-type ==0.1.2.0, + linear ==1.23, + linear-base ==0.4.0, + linear-circuit ==0.1.0.4, + linear-generics ==0.2.3, + linear-programming ==0.0.1, + linebreak ==1.1.0.4, + linux-capabilities ==0.1.1.0, + linux-file-extents ==0.2.0.1, + linux-namespaces ==0.1.3.1, + List ==0.6.2, + ListLike ==4.7.8.2, + list-predicate ==0.1.0.1, + listsafe ==0.1.0.1, + list-shuffle ==1.0.0.1, + list-t ==1.0.5.7, + list-transformer ==1.1.1, + ListTree ==0.2.3, + list-witnesses ==0.1.4.1, + ListZipper ==1.2.0.2, + literatex ==0.3.0.0, + lmdb ==0.2.5, + load-env ==0.2.1.0, + locators ==0.3.0.5, + loch-th ==0.2.2, + lockfree-queue ==0.2.4, + log-base ==0.12.0.1, + log-domain ==0.13.2, + logfloat ==0.14.0, + logger-thread ==0.1.0.2, + logging ==3.0.5, + logging-effect ==1.4.0, + logging-facade ==0.3.1, + logging-facade-syslog ==1, + logict ==0.8.1.0, + logstash ==0.1.0.4, + loop ==0.3.0, + lpeg ==1.1.0, + LPFP ==1.1.4, + LPFP-core ==1.1.1, + lrucache ==1.2.0.1, + lrucaching ==0.3.4, + lsp ==2.7.0.0, + lsp-test ==0.17.1.0, + lsp-types ==2.3.0.0, + lsql-csv ==0.1.0.6, + lua ==2.3.3, + lua-arbitrary ==1.0.1.1, + lucid ==2.11.20230408, + lucid2 ==0.0.20240424, + lucid-cdn ==0.2.2.0, + lucid-extras ==0.2.2, + lukko ==0.1.2, + lumberjack ==1.0.3.0, + lz4 ==0.2.3.1, + lzma ==0.0.1.1, + lzma-clib ==5.2.2, + machines ==0.7.3, + magic ==1.1, + magico ==0.0.2.3, + mailtrap ==0.1.2.1, + mainland-pretty ==0.7.1.1, + main-tester ==0.2.0.1, + managed ==1.0.10, + mappings ==0.3.1.0, + map-syntax ==0.3, + markdown ==0.1.17.5, + markdown-unlit ==0.6.0, + markov-chain ==0.0.3.4, + markov-chain-usage-model ==0.0.0, + markup-parse ==0.1.1, + massiv ==1.0.4.0, + massiv-io ==1.0.0.1, + massiv-serialise ==1.0.0.2, + massiv-test ==1.1.0.0, + matchable ==0.1.2.1, + mathexpr ==0.3.1.0, + math-extras ==0.1.1.0, + math-functions ==0.3.4.4, + mathlist ==0.2.0.0, + matplotlib ==0.7.7, + matrices ==0.5.0, + matrix ==0.3.6.3, + matrix-as-xyz ==0.1.2.2, + matrix-market-attoparsec ==0.1.1.3, + matrix-static ==0.3, + maximal-cliques ==0.1.1, + mbox-utility ==0.0.3.1, + mcmc ==0.8.2.0, + mcmc-types ==1.0.3, + median-stream ==0.7.0.0, + med-module ==0.1.3, + megaparsec ==9.6.1, + megaparsec-tests ==9.6.1, + melf ==1.3.1, + membership ==0.0.1, + memcache ==0.3.0.2, + mem-info ==0.3.0.0, + memory ==0.18.0, + MemoTrie ==0.6.11, + mergeful ==0.3.0.0, + mergeful-persistent ==0.3.0.1, + mergeless ==0.4.0.0, + mergeless-persistent ==0.1.0.1, + merkle-tree ==0.1.1, + mersenne-random ==1.0.0.1, + mersenne-random-pure64 ==0.2.2.0, + messagepack ==0.5.5, + metrics ==0.4.1.1, + mfsolve ==0.3.2.2, + microaeson ==0.1.0.2, + microlens ==0.4.13.1, + microlens-aeson ==2.5.2, + microlens-contra ==0.1.0.3, + microlens-ghc ==0.4.14.3, + microlens-mtl ==0.2.0.3, + microlens-platform ==0.4.3.5, + microlens-th ==0.4.3.15, + microspec ==0.2.1.3, + microstache ==1.0.3, + midair ==0.2.0.1, + midi ==0.2.2.4, + midi-alsa ==0.2.1, + midi-music-box ==0.0.1.2, + mighty-metropolis ==2.0.0, + mime-mail ==0.5.1, + mime-mail-ses ==0.4.3, + mime-types ==0.1.2.0, + minimal-configuration ==0.1.4, + minimorph ==0.3.0.1, + minisat-solver ==0.1, + miniterion ==0.1.1.1, + miniutter ==0.5.1.2, + min-max-pqueue ==0.1.0.2, + mintty ==0.1.4, + misfortune ==0.1.2.1, + miso ==1.8.4.0, + missing-foreign ==0.1.1, + MissingH ==1.6.0.1, + mixed-types-num ==0.6.1, + mmap ==0.5.9, + mmark ==0.0.8.0, + mmark-cli ==0.0.5.2, + mmark-ext ==0.2.1.5, + mmorph ==1.2.0, + mnist-idx ==0.1.3.2, + mnist-idx-conduit ==0.4.0.0, + mockcat ==0.5.1.0, + mockery ==0.3.5, + mod ==0.2.0.1, + modern-uri ==0.3.6.1, + modular ==0.1.0.8, + moffy ==0.1.1.0, + moffy-samples ==0.1.0.3, + moffy-samples-events ==0.2.2.5, + moffy-samples-gtk3 ==0.1.0.0, + moffy-samples-gtk3-run ==0.1.0.7, + monad-bayes ==1.3.0.3, + monad-chronicle ==1.0.2, + monad-control ==1.0.3.1, + monad-control-aligned ==0.0.2.1, + monad-control-identity ==0.2.0.0, + monad-coroutine ==0.9.2, + monad-extras ==0.6.0, + monad-interleave ==0.2.0.1, + monadlist ==0.0.2, + monad-logger ==0.3.40, + monad-logger-aeson ==0.4.1.3, + monad-logger-json ==0.1.0.0, + monad-logger-logstash ==0.2.0.2, + monad-loops ==0.4.3, + monad-memo ==0.5.4, + monad-metrics ==0.2.2.2, + monadoid ==0.0.3, + monadology ==0.3, + monad-par ==0.3.6, + monad-parallel ==0.8, + monad-par-extras ==0.3.3, + monad-peel ==0.3, + MonadPrompt ==1.0.0.5, + MonadRandom ==0.6, + monad-resumption ==0.1.4.0, + monad-schedule ==0.2.0.1, + monad-st ==0.2.4.1, + monads-tf ==0.3.0.1, + monad-time ==0.4.0.0, + mongoDB ==2.7.1.4, + monoidal-containers ==0.6.5.0, + monoidal-functors ==0.2.3.0, + monoid-extras ==0.6.3, + monoidmap ==0.0.1.6, + monoid-subclasses ==1.2.5.1, + monoid-transformer ==0.0.4, + mono-traversable ==1.0.20.0, + mono-traversable-instances ==0.1.1.0, + mono-traversable-keys ==0.3.0, + more-containers ==0.2.2.2, + morpheus-graphql ==0.28.1, + morpheus-graphql-app ==0.28.1, + morpheus-graphql-client ==0.28.1, + morpheus-graphql-code-gen ==0.28.1, + morpheus-graphql-code-gen-utils ==0.28.1, + morpheus-graphql-core ==0.28.1, + morpheus-graphql-server ==0.28.1, + morpheus-graphql-subscriptions ==0.28.1, + morpheus-graphql-tests ==0.28.1, + moss ==0.2.0.1, + mountpoints ==1.0.2, + mpi-hs ==0.7.3.0, + mpi-hs-binary ==0.1.1.0, + mpi-hs-cereal ==0.1.0.0, + msgpack ==1.0.1.0, + mt19937 ==0.1.1, + mtl installed, + mtl-compat ==0.2.2, + mtl-prelude ==2.0.3.2, + multiarg ==0.30.0.10, + multi-containers ==0.2, + multimap ==1.2.1, + multipart ==0.2.1, + MultipletCombiner ==0.0.7, + multiset ==0.3.4.3, + multistate ==0.8.0.4, + murmur3 ==1.0.5, + murmur-hash ==0.1.0.10, + MusicBrainz ==0.4.1, + mustache ==2.4.2, + mutable-containers ==0.3.4.1, + mwc-probability ==2.3.1, + mwc-random ==0.15.1.0, + mx-state-codes ==1.0.0.0, + myers-diff ==0.3.0.0, + mysql ==0.2.1, + mysql-haskell ==1.1.5, + mysql-haskell-nem ==0.1.0.0, + mysql-json-table ==0.1.4.0, + mysql-simple ==0.4.9, + n2o ==0.11.1, + n2o-nitro ==0.11.2, + nagios-check ==0.3.2, + named ==0.3.0.1, + named-text ==1.2.1.0, + names-th ==0.3.0.1, + nano-erl ==0.1.0.1, + NanoID ==3.4.0.2, + nanospec ==0.2.2, + nanovg ==0.8.1.0, + nats ==1.1.2, + natural-arithmetic ==0.2.1.0, + natural-induction ==0.2.0.0, + natural-sort ==0.1.2, + natural-transformation ==0.4, + neat-interpolation ==0.5.1.4, + netcode-io ==0.0.3, + netlib-carray ==0.1, + netlib-comfort-array ==0.0.0.2, + netlib-ffi ==0.1.2, + netpbm ==1.0.4, + netrc ==0.2.0.1, + nettle ==0.3.1.1, + netwire ==5.0.3, + netwire-input ==0.0.7, + netwire-input-glfw ==0.0.12, + network ==3.2.4.0, + network-bsd ==2.8.1.0, + network-byte-order ==0.1.7, + network-conduit-tls ==1.4.0.1, + network-control ==0.1.3, + network-info ==0.2.1, + network-ip ==0.3.0.3, + network-messagepack-rpc ==0.1.2.0, + network-multicast ==0.3.2, + network-run ==0.4.0, + network-simple ==0.4.5, + network-simple-tls ==0.4.2, + network-transport ==0.5.8, + network-transport-inmemory ==0.5.41, + network-transport-tcp ==0.8.5, + network-transport-tests ==0.3.3, + network-uri ==2.6.4.2, + network-wait ==0.2.0.0, + newtype ==0.2.2.0, + newtype-generics ==0.6.2, + nfc ==0.1.1, + nicify-lib ==1.0.1, + NineP ==0.0.2.1, + nix-derivation ==1.1.3, + nix-paths ==1.0.1, + NoHoed ==0.1.1, + nonce ==1.0.7, + nondeterminism ==1.5, + non-empty ==0.3.5, + nonempty-containers ==0.3.4.5, + non-empty-sequence ==0.2.0.4, + non-empty-text ==0.2.1, + nonempty-vector ==0.2.3, + nonempty-zipper ==1.0.0.4, + non-negative ==0.1.2, + normaldistribution ==1.1.0.3, + nothunks ==0.3.0.0, + no-value ==1.0.0.0, + nowdoc ==0.1.1.0, + nqe ==0.6.5, + nsis ==0.3.3, + n-tuple ==0.0.3, + numbers ==3000.2.0.2, + numeric-extras ==0.1, + numeric-limits ==0.1.0.0, + numeric-prelude ==0.4.4, + numeric-quest ==0.2.0.2, + numhask ==0.12.0.3, + numhask-array ==0.11.1.0, + numhask-space ==0.11.1.0, + NumInstances ==1.4, + numtype-dk ==0.5.0.3, + nuxeo ==0.3.2, + nvim-hs ==2.3.2.3, + nvim-hs-contrib ==2.0.0.2, + nvim-hs-ghcid ==2.0.1.0, + nvvm ==0.10.0.1, + ObjectName ==1.1.0.2, + oblivious-transfer ==0.1.0, + o-clock ==1.4.0, + odbc ==0.3.0, + ods2csv ==0.1, + oeis2 ==1.0.8, + ofx ==0.4.4.0, + old-locale ==1.0.0.7, + old-time ==1.1.0.4, + om-elm ==2.0.0.7, + om-show ==0.1.2.10, + once ==0.4, + one-liner ==2.1, + one-liner-instances ==0.1.3.0, + OneTuple ==0.4.2, + Only ==0.1, + oo-prototypes ==0.1.0.0, + oops ==0.2.0.1, + opaleye ==0.10.3.1, + OpenAL ==1.7.0.5, + openapi3 ==3.2.4, + open-browser ==0.2.1.0, + openexr-write ==0.1.0.2, + OpenGL ==3.0.3.0, + OpenGLRaw ==3.3.4.1, + openpgp-asciiarmor ==0.1.2, + opensource ==0.1.1.0, + openssl-streams ==1.2.3.0, + opentelemetry ==0.8.0, + opentelemetry-extra ==0.8.0, + opentelemetry-lightstep ==0.8.0, + opentelemetry-wai ==0.8.0, + open-witness ==0.6, + operational ==0.2.4.2, + opml-conduit ==0.9.0.0, + opt-env-conf ==0.5.1.0, + optics ==0.4.2.1, + optics-core ==0.4.1.1, + optics-extra ==0.4.2.1, + optics-operators ==0.1.0.1, + optics-th ==0.4.1, + optics-vl ==0.2.1, + optima ==0.4.0.5, + optional-args ==1.0.2, + options ==1.2.1.2, + optparse-applicative ==0.18.1.0, + optparse-enum ==1.0.0.0, + optparse-generic ==1.5.2, + optparse-simple ==0.1.1.4, + optparse-text ==0.1.1.0, + OrderedBits ==0.0.2.0, + ordered-containers ==0.2.4, + ormolu ==0.7.4.0, + os-string ==2.0.6, + overhang ==1.0.0, + packcheck ==0.7.0, + pager ==0.1.1.0, + pagination ==0.2.2, + pagure ==0.2.1, + pagure-cli ==0.2.2, + palette ==0.3.0.3, + pandoc ==3.4, + pandoc-cli ==3.4, + pandoc-lua-engine ==0.3.2, + pandoc-lua-marshal ==0.2.8, + pandoc-plot ==1.9.1, + pandoc-server ==0.1.0.8, + pandoc-throw ==0.1.0.0, + pandoc-types ==1.23.1, + pango ==0.13.11.0, + panic ==0.4.0.1, + pantry ==0.10.0, + parallel ==3.2.2.0, + parallel-io ==0.3.5, + parameterized ==0.5.0.0, + parameterized-utils ==2.1.9.0, + park-bench ==0.1.1.0, + parseargs ==0.2.0.9, + parsec installed, + parsec-class ==1.0.1.0, + parsec-numbers ==0.1.0, + parsec-numeric ==0.1.0.0, + ParsecTools ==0.0.2.0, + parser-combinators ==1.3.0, + parser-combinators-tests ==1.3.0, + parsers ==0.12.11, + partial-handler ==1.0.3, + partial-isomorphisms ==0.2.4.0, + partialord ==0.0.2, + partial-order ==0.2.0.0, + password ==3.0.4.0, + password-instances ==3.0.0.0, + password-types ==1.0.0.0, + path ==0.9.5, + path-binary-instance ==0.1.0.1, + path-extensions ==0.1.1.0, + path-extra ==0.3.1, + path-io ==1.8.2, + path-like ==0.2.0.2, + path-pieces ==0.2.1, + pathtype ==0.8.1.3, + path-utils ==0.1.1.0, + pathwalk ==0.3.1.2, + patrol ==1.0.0.8, + pava ==0.1.1.4, + pcg-random ==0.1.4.0, + pcre2 ==2.2.1, + pcre-heavy ==1.0.0.3, + pcre-light ==0.4.1.2, + pcre-utils ==0.1.9, + pdf-toolbox-content ==0.1.2, + pdf-toolbox-core ==0.1.3, + pdf-toolbox-document ==0.1.4, + peano ==0.1.0.2, + pedersen-commitment ==0.2.0, + pem ==0.2.4, + percent-format ==0.0.4, + perf ==0.12.0.1, + perfect-hash-generator ==1.0.0, + persistable-record ==0.6.0.6, + persistable-types-HDBC-pg ==0.0.3.5, + persistent ==2.14.6.3, + persistent-discover ==0.1.0.7, + persistent-documentation ==0.1.0.5, + persistent-lens ==1.0.0, + persistent-mongoDB ==2.13.1.0, + persistent-mtl ==0.5.1, + persistent-mysql ==2.13.1.5, + persistent-pagination ==0.1.1.2, + persistent-postgresql ==2.13.6.2, + persistent-qq ==2.12.0.6, + persistent-redis ==2.13.0.2, + persistent-sqlite ==2.13.3.0, + persistent-template ==2.12.0.0, + persistent-test ==2.13.1.3, + persistent-typed-db ==0.1.0.7, + pfile ==0.1.0.1, + pg-harness-client ==0.6.0, + pg-transact ==0.3.2.0, + phantom-state ==0.2.1.4, + phatsort ==0.6.0.0, + pid1 ==0.1.3.1, + pinch ==0.5.2.0, + pipes ==4.3.16, + pipes-aeson ==0.4.2, + pipes-attoparsec ==0.6.0, + pipes-binary ==0.4.4, + pipes-bytestring ==2.1.7, + pipes-concurrency ==2.0.14, + pipes-csv ==1.4.3, + pipes-extras ==1.0.15, + pipes-fastx ==0.3.0.0, + pipes-fluid ==0.6.0.1, + pipes-group ==1.0.12, + pipes-mongodb ==0.1.0.0, + pipes-ordered-zip ==1.2.1, + pipes-parse ==3.0.9, + pipes-random ==1.0.0.5, + pipes-safe ==2.3.5, + pipes-wai ==3.2.0, + pipes-zlib ==0.4.4.2, + pkgtreediff ==0.6.0, + place-cursor-at ==1.0.1, + placeholders ==0.1, + plaid ==0.1.0.4, + plot ==0.2.3.12, + plotlyhs ==0.2.3, + Plural ==0.0.2, + pointed ==5.0.4, + pointedlist ==0.6.1, + pointless-fun ==1.1.0.8, + poll ==0.0.0.2, + poly ==0.5.1.0, + poly-arity ==0.1.0, + polynomials-bernstein ==1.1.2, + polyparse ==1.13, + polysemy ==1.9.2.0, + polysemy-fs ==0.1.0.0, + polysemy-plugin ==0.4.5.2, + polysemy-webserver ==0.2.1.2, + pontarius-xmpp ==0.5.7.0, + pooled-io ==0.0.2.3, + portable-lines ==0.1, + port-utils ==0.2.1.0, + posix-paths ==0.3.0.0, + posix-pty ==0.2.2, + possibly ==1.0.0.0, + postgres-options ==0.2.2.0, + postgresql-binary ==0.14, + postgresql-libpq ==0.10.2.0, + postgresql-libpq-configure ==0.10.0.1, + postgresql-libpq-notify ==0.2.0.0, + postgresql-migration ==0.2.1.8, + postgresql-schema ==0.1.14, + postgresql-simple ==0.7.0.0, + postgresql-simple-url ==0.2.1.0, + postgresql-syntax ==0.4.1.1, + postgresql-typed ==0.6.2.5, + post-mess-age ==0.2.1.0, + pptable ==0.3.0.0, + pqueue ==1.5.0.0, + prairie ==0.0.4.0, + pred-set ==0.0.1, + prefix-units ==0.3.0.1, + prelude-compat ==0.0.0.2, + prelude-safeenum ==0.1.1.3, + pretty installed, + pretty-class ==1.0.1.1, + prettyclass ==1.0.0.0, + pretty-hex ==1.1, + prettyprinter ==1.7.1, + prettyprinter-ansi-terminal ==1.1.3, + prettyprinter-combinators ==0.1.3, + prettyprinter-compat-annotated-wl-pprint ==1.1, + prettyprinter-compat-ansi-wl-pprint ==1.0.2, + prettyprinter-compat-wl-pprint ==1.0.1, + prettyprinter-interp ==0.2.0.0, + pretty-relative-time ==0.3.0.0, + pretty-show ==1.10, + pretty-simple ==4.1.2.0, + pretty-sop ==0.2.0.3, + pretty-terminal ==0.1.0.0, + primecount ==0.1.0.1, + primes ==0.2.1.0, + primitive ==0.9.0.0, + primitive-addr ==0.1.0.3, + primitive-extras ==0.10.2, + primitive-offset ==0.2.0.1, + primitive-serial ==0.1, + primitive-unaligned ==0.1.1.2, + primitive-unlifted ==2.1.0.0, + prim-uniq ==0.2, + print-console-colors ==0.1.0.0, + probability ==0.2.8, + process installed, + process-extras ==0.7.4, + product-isomorphic ==0.0.3.4, + product-profunctors ==0.11.1.1, + profunctors ==5.6.2, + projectroot ==0.2.0.1, + project-template ==0.2.1.0, + prometheus ==2.3.0, + prometheus-client ==1.1.1, + prometheus-metrics-ghc ==1.0.1.2, + promises ==0.3, + prospect ==0.1.0.0, + protobuf ==0.2.1.3, + protobuf-simple ==0.1.1.1, + protocol-radius ==0.0.1.2, + protocol-radius-test ==0.1.0.1, + proto-lens ==0.7.1.5, + proto-lens-arbitrary ==0.1.2.13, + proto-lens-optparse ==0.1.1.12, + proto-lens-protobuf-types ==0.7.2.1, + proto-lens-protoc ==0.8.0.1, + proto-lens-runtime ==0.7.0.6, + proto-lens-setup ==0.4.0.8, + protolude ==0.3.4, + proxied ==0.3.2, + psql-helpers ==0.1.0.0, + PSQueue ==1.2.0, + psqueues ==0.2.8.0, + pthread ==0.2.1, + ptr ==0.16.8.6, + ptr-poker ==0.1.2.14, + pulse-simple ==0.1.14, + pureMD5 ==2.1.4, + purescript-bridge ==0.15.0.0, + pusher-http-haskell ==2.1.0.18, + pvar ==1.0.0.0, + pwstore-fast ==2.4.4, + PyF ==0.11.3.0, + qchas ==1.1.0.1, + quaalude ==0.0.0.1, + quadratic-irrational ==0.1.1, + QuasiText ==0.1.2.6, + queues ==1.0.0, + quickbench ==1.0.1, + QuickCheck ==2.14.3, + quickcheck-arbitrary-adt ==0.3.1.0, + quickcheck-assertions ==0.3.0, + quickcheck-classes ==0.6.5.0, + quickcheck-classes-base ==0.6.2.0, + quickcheck-groups ==0.0.1.3, + quickcheck-higherorder ==0.1.0.1, + quickcheck-instances ==0.3.31, + quickcheck-io ==0.2.0, + quickcheck-monoid-subclasses ==0.3.0.4, + quickcheck-quid ==0.0.1.5, + quickcheck-simple ==0.1.1.1, + quickcheck-state-machine ==0.10.1, + quickcheck-text ==0.1.2.1, + quickcheck-transformer ==0.3.1.2, + quickcheck-unicode ==1.0.1.0, + quicklz ==1.5.0.11, + quiet ==0.2, + quote-quot ==0.2.1.0, + radius ==0.7.1.0, + radix-tree ==1.0.0.2, + rainbow ==0.34.2.2, + rainbox ==0.26.0.0, + ral ==0.2.2, + rampart ==2.0.0.8, + ramus ==0.1.2, + rando ==0.0.0.4, + random ==1.2.1.2, + random-bytestring ==0.1.4, + random-fu ==0.3.0.1, + random-shuffle ==0.0.4, + random-tree ==0.6.0.5, + range ==0.3.0.2, + ranged-list ==0.1.2.1, + Ranged-sets ==0.4.0, + ranges ==0.2.4, + range-set-list ==0.1.4, + rank1dynamic ==0.4.2, + rank2classes ==1.5.3.1, + Rasterific ==0.7.5.4, + rasterific-svg ==0.3.3.2, + ratel ==2.0.0.12, + rate-limit ==1.4.3, + ratel-wai ==2.0.0.7, + ratio-int ==0.1.2, + rattle ==0.2, + rattletrap ==13.1.0, + Rattus ==0.5.1.1, + rawfilepath ==1.1.1, + rawstring-qm ==0.2.3.0, + raw-strings-qq ==1.1, + rcu ==0.2.7, + rdf ==0.1.0.8, + rdtsc ==1.3.0.1, + reactive-balsa ==0.4.0.1, + reactive-banana ==1.3.2.0, + reactive-banana-bunch ==1.0.0.1, + reactive-jack ==0.4.1.2, + reactive-midyim ==0.4.1.1, + readable ==0.3.1, + read-editor ==0.1.0.2, + read-env-var ==1.0.0.0, + real-dice ==0.1.0.3, + rebase ==1.21.1, + rec-def ==0.2.2, + record-dot-preprocessor ==0.2.17, + record-hasfield ==1.0.1, + recursion-schemes ==5.2.3, + recv ==0.1.0, + redact ==0.5.0.0, + reddit-scrape ==0.0.1, + redis-glob ==0.1.0.8, + redis-resp ==1.0.0, + reducers ==3.12.4, + refact ==0.3.0.2, + ref-fd ==0.5.0.1, + refined ==0.8.2, + reflection ==2.1.8, + RefSerialize ==0.4.0, + ref-tf ==0.5.0.1, + regex ==1.1.0.2, + regex-applicative ==0.3.4, + regex-base ==0.94.0.2, + regex-compat ==0.95.2.1, + regex-pcre ==0.95.0.0, + regex-pcre-builtin ==0.95.2.3.8.44, + regex-posix ==0.96.0.1, + regex-posix-clib ==2.7, + regex-tdfa ==1.3.2.2, + regex-with-pcre ==1.1.0.2, + regression-simple ==0.2.1, + reinterpret-cast ==0.1.0, + relapse ==1.0.0.1, + relational-query ==0.12.3.1, + relational-query-HDBC ==0.7.2.1, + relational-record ==0.2.2.0, + relational-schemas ==0.1.8.1, + reliable-io ==0.0.2, + relude ==1.2.1.0, + renderable ==0.2.0.1, + reorder-expression ==0.1.0.1, + replace-attoparsec ==1.5.0.0, + replace-megaparsec ==1.5.0.1, + repline ==0.4.2.0, + req ==3.13.4, + req-conduit ==1.0.2, + rerebase ==1.21.1, + rerefined ==0.5.1, + reroute ==0.7.0.0, + resistor-cube ==0.0.1.4, + resolv ==0.2.0.2, + resource-pool ==0.4.0.0, + resourcet ==1.3.0, + rest-rewrite ==0.4.4, + result ==0.2.6.0, + retry ==0.9.3.1, + rev-state ==0.2.0.1, + rex ==0.6.2, + rfc1751 ==0.1.3, + rfc5051 ==0.2, + rg ==1.4.0.0, + rhine ==1.4.0.1, + rhine-bayes ==1.4.0.1, + rhine-gloss ==1.4.0.1, + rhine-terminal ==1.4.0.1, + riak-protobuf ==0.25.0.0, + richenv ==0.1.0.2, + rio ==0.1.22.0, + rio-orphans ==0.1.2.0, + rio-prettyprint ==0.1.8.0, + rng-utils ==0.3.1, + roc-id ==0.2.0.3, + rocksdb-haskell ==1.0.1, + rocksdb-haskell-jprupp ==2.1.6, + rocksdb-query ==0.4.2, + roles ==0.2.1.0, + rollbar ==1.1.3, + rope-utf16-splay ==0.4.0.0, + rosezipper ==0.2, + rot13 ==0.2.0.1, + RoundingFiasco ==0.1.0.0, + row-types ==1.0.1.2, + rpmbuild-order ==0.4.12, + rpm-nvr ==0.1.2, + rp-tree ==0.7.1, + rrb-vector ==0.2.2.1, + RSA ==2.4.1, + rss ==3000.2.0.8, + rss-conduit ==0.6.0.1, + run-haskell-module ==0.0.2, + runmemo ==1.0.0.1, + run-st ==0.1.3.3, + rvar ==0.3.0.2, + rzk ==0.7.5, + s3-signer ==0.5.0.0, + safe ==0.3.21, + safe-coloured-text ==0.3.0.2, + safe-coloured-text-gen ==0.0.0.3, + safe-coloured-text-layout ==0.2.0.1, + safe-coloured-text-layout-gen ==0.0.0.1, + safe-coloured-text-terminfo ==0.3.0.0, + safecopy ==0.10.4.2, + safe-decimal ==0.2.1.0, + safe-exceptions ==0.1.7.4, + safe-foldable ==0.1.0.0, + safe-gen ==1.0.1, + safeio ==0.0.6.0, + safe-json ==1.2.0.1, + safe-money ==0.9.1, + SafeSemaphore ==0.10.1, + salve ==2.0.0.5, + sample-frame ==0.0.4, + sample-frame-np ==0.0.5, + sampling ==0.3.5, + samsort ==0.1.0.0, + sandi ==0.5, + sandwich ==0.2.2.0, + sandwich-hedgehog ==0.1.3.1, + sandwich-quickcheck ==0.1.0.7, + sandwich-slack ==0.1.2.0, + sandwich-webdriver ==0.2.3.1, + saturn ==1.0.0.5, + say ==0.1.0.1, + sayable ==1.2.5.0, + sbp ==6.1.0, + sbv ==10.12, + scalpel ==0.6.2.2, + scalpel-core ==0.6.2.2, + scanf ==0.1.0.0, + scanner ==0.3.1, + s-cargot ==0.1.6.0, + scheduler ==2.0.0.1, + SciBaseTypes ==0.1.1.0, + scientific ==0.3.8.0, + scientist ==0.0.0.0, + scotty ==0.22, + scrypt ==0.5.0, + search-algorithms ==0.3.2, + secp256k1-haskell ==1.4.0, + securemem ==0.1.10, + selections ==0.3.0.0, + selective ==0.7.0.1, + select-rpms ==0.1.0, + semaphore-compat installed, + semialign ==1.3.1, + semigroupoids ==6.0.1, + semigroups ==0.20, + semirings ==0.7, + semiring-simple ==1.0.0.1, + semver ==0.4.0.1, + sendfile ==0.7.11.6, + sendgrid-v3 ==1.0.0.1, + seqalign ==0.2.0.4, + seqid ==0.6.3, + seqid-streams ==0.7.2, + sequence-formats ==1.8.1.1, + sequenceTools ==1.5.3.1, + serialise ==0.2.6.1, + servant ==0.20.2, + servant-auth ==0.4.2.0, + servant-auth-client ==0.4.2.0, + servant-auth-docs ==0.2.11.0, + servant-auth-server ==0.4.9.0, + servant-auth-swagger ==0.2.11.0, + servant-blaze ==0.9.1, + servant-checked-exceptions ==2.2.0.1, + servant-checked-exceptions-core ==2.2.0.1, + servant-cli ==0.1.1.0, + servant-client ==0.20.2, + servant-client-core ==0.20.2, + servant-conduit ==0.16.1, + servant-docs ==0.13.1, + servant-exceptions ==0.2.1, + servant-exceptions-server ==0.2.1, + servant-foreign ==0.16.1, + servant-http-streams ==0.20.2, + servant-JuicyPixels ==0.3.1.1, + servant-lucid ==0.9.0.6, + servant-machines ==0.16.1, + servant-multipart ==0.12.1, + servant-multipart-api ==0.12.1, + servant-multipart-client ==0.12.2, + servant-openapi3 ==2.0.1.6, + servant-pipes ==0.16.1, + servant-quickcheck ==0.1.1.0, + servant-rate-limit ==0.2.0.0, + servant-rawm ==1.0.0.0, + servant-server ==0.20.2, + servant-static-th ==1.0.0.0, + servant-swagger ==1.2.1, + servant-swagger-ui ==0.3.5.5.0.1, + servant-swagger-ui-core ==0.3.5, + servant-websockets ==2.0.0, + servant-xml ==1.0.3, + serversession ==1.0.3, + serversession-backend-acid-state ==1.0.5, + serversession-backend-persistent ==2.0.3, + serversession-backend-redis ==1.0.5, + serversession-frontend-wai ==1.0.1, + serversession-frontend-yesod ==1.0.1, + servius ==1.2.3.0, + ses-html ==0.4.0.0, + set-cover ==0.1.1.1, + setenv ==0.1.1.3, + setlocale ==1.0.0.10, + set-monad ==0.3.0.0, + sexp-grammar ==2.3.4.2, + SHA ==1.6.4.4, + shake ==0.19.8, + shake-plus ==0.3.4.0, + shakespeare ==2.1.1, + shakespeare-text ==1.1.0, + shared-memory ==0.2.0.1, + ShellCheck ==0.10.0, + shell-conduit ==5.0.0, + shell-escape ==0.2.0, + shellify ==0.11.0.1, + shelltestrunner ==1.10, + shell-utility ==0.1, + shellwords ==0.1.3.1, + shelly ==1.12.1, + should-not-typecheck ==2.1.0, + show-combinators ==0.2.0.0, + siggy-chardust ==1.0.0, + signal ==0.1.0.4, + silently ==1.2.5.3, + simple ==2.0.0, + simple-affine-space ==0.2.1, + simple-cabal ==0.1.3.1, + simple-cairo ==0.1.0.6, + simple-cmd ==0.2.7, + simple-cmd-args ==0.1.8, + simple-expr ==0.1.1.0, + simple-media-timestamp ==0.2.1.0, + simple-media-timestamp-attoparsec ==0.1.0.0, + simple-pango ==0.1.0.1, + simple-prompt ==0.2.3, + simple-reflect ==0.3.3, + simple-sendfile ==0.2.32, + simple-session ==2.0.0, + simple-templates ==2.0.0, + simple-vec3 ==0.6.0.1, + since ==0.0.0, + singleraeh ==0.4.0, + singleton-bool ==0.1.8, + singleton-nats ==0.4.7, + singletons ==3.0.3, + singletons-base ==3.3, + singletons-presburger ==0.7.4.0, + singletons-th ==3.3, + Sit ==0.2023.8.3, + sitemap-gen ==0.1.0.0, + size-based ==0.1.3.3, + sized ==1.1.0.2, + skein ==1.0.9.4, + skews ==0.1.0.3, + skip-var ==0.1.1.0, + skylighting ==0.14.3, + skylighting-core ==0.14.3, + skylighting-format-ansi ==0.1, + skylighting-format-blaze-html ==0.1.1.2, + skylighting-format-context ==0.1.0.2, + skylighting-format-latex ==0.1, + slave-thread ==1.1.0.3, + slick ==1.3.1.0, + slist ==0.2.1.0, + slynx ==0.7.2.2, + smallcheck ==1.2.1.1, + smtp-mail ==0.5.0.0, + snap ==1.1.3.3, + snap-blaze ==0.2.1.5, + snap-core ==1.0.5.1, + snap-server ==1.1.2.1, + snowflake ==0.1.1.1, + socks ==0.6.1, + solana-staking-csvs ==0.1.3.0, + some ==1.0.6, + some-dict-of ==0.1.0.2, + sop-core ==0.5.0.2, + sort ==1.0.0.0, + sorted-list ==0.2.2.0, + sound-collage ==0.2.1, + sourcemap ==0.1.7, + sox ==0.2.3.2, + soxlib ==0.0.3.2, + speculate ==0.4.20, + specup ==0.2.0.1, + speedy-slice ==0.3.2, + sphinx ==0.6.1, + Spintax ==0.3.6.1, + splice ==0.6.1.1, + split ==0.2.5, + splitmix ==0.1.0.5, + splitmix-distributions ==1.0.0, + split-record ==0.1.1.4, + Spock-api ==0.14.0.0, + spoon ==0.3.1, + spreadsheet ==0.1.3.10, + sqids ==0.2.2.0, + sqlite-simple ==0.4.19.0, + sql-words ==0.1.6.5, + squeather ==0.8.0.0, + srcloc ==0.6.0.1, + srtree ==1.0.0.5, + stache ==2.3.4, + stack-all ==0.6.3, + stack-clean-old ==0.5.1, + stack-templatizer ==0.1.1.0, + stamina ==0.1.0.3, + state-codes ==0.1.3, + stateref ==0.3, + statestack ==0.3.1.1, + StateVar ==1.2.2, + stateWriter ==0.4.0, + static-bytes ==0.1.0, + static-text ==0.2.0.7, + statistics ==0.16.2.1, + statistics-linreg ==0.3, + status-notifier-item ==0.3.1.0, + step-function ==0.2.0.1, + stitch ==0.6.0.0, + stm installed, + stm-chans ==3.0.0.9, + stm-conduit ==4.0.1, + stm-containers ==1.2.1, + stm-delay ==0.1.1.1, + stm-extras ==0.1.0.3, + stm-hamt ==1.2.1, + STMonadTrans ==0.4.8, + stm-split ==0.0.2.1, + stm-supply ==0.2.0.0, + storable-complex ==0.2.3.0, + storable-endian ==0.2.6.1, + storable-record ==0.0.7, + storable-tuple ==0.1, + storablevector ==0.2.13.2, + store ==0.7.18, + store-core ==0.4.4.7, + store-streaming ==0.2.0.5, + stratosphere ==0.60.0, + Stream ==0.4.7.2, + streaming ==0.2.4.0, + streaming-attoparsec ==1.0.0.1, + streaming-bytestring ==0.3.2, + streaming-commons ==0.2.2.6, + streaming-wai ==0.1.1, + streamly ==0.10.1, + streamly-core ==0.2.2, + streamly-process ==0.3.1, + streams ==3.3.2, + strict ==0.5.1, + strict-base-types ==0.8.1, + strict-concurrency ==0.2.4.3, + strict-lens ==0.4.1, + strict-list ==0.1.7.5, + strict-tuple ==0.1.5.4, + strict-wrapper ==0.0.1.0, + stringable ==0.1.3, + stringbuilder ==0.5.1, + string-class ==0.1.7.2, + string-combinators ==0.6.0.5, + string-conv ==0.2.0, + string-conversions ==0.4.0.1, + string-interpolate ==0.3.4.0, + stringprep ==1.0.0, + string-qq ==0.0.6, + stringsearch ==0.3.6.6, + string-transform ==1.1.1, + string-variants ==0.3.1.0, + strive ==6.0.0.12, + strongweak ==0.8.0, + structs ==0.1.9, + structured ==0.1.1, + stylish-haskell ==0.14.6.0, + subcategories ==0.2.1.1, + sundown ==0.6, + svg-builder ==0.1.1, + SVGFonts ==1.8.0.1, + svg-tree ==0.6.2.4, + swagger2 ==2.8.9, + swish ==0.10.9.0, + syb ==0.7.2.4, + sydtest ==0.17.0.2, + sydtest-aeson ==0.2.0.0, + sydtest-amqp ==0.1.0.0, + sydtest-autodocodec ==0.0.0.0, + sydtest-discover ==0.0.0.4, + sydtest-hedgehog ==0.4.0.0, + sydtest-hedis ==0.0.0.0, + sydtest-hspec ==0.4.0.2, + sydtest-mongo ==0.1.0.0, + sydtest-persistent ==0.1.0.0, + sydtest-persistent-sqlite ==0.2.0.3, + sydtest-process ==0.0.0.0, + sydtest-rabbitmq ==0.1.0.0, + sydtest-servant ==0.2.0.2, + sydtest-typed-process ==0.0.0.0, + sydtest-wai ==0.2.0.2, + sydtest-webdriver ==0.0.0.1, + sydtest-webdriver-screenshot ==0.1.0.0, + sydtest-webdriver-yesod ==0.0.0.1, + sydtest-yesod ==0.3.0.2, + symbol ==0.2.4.1, + symengine ==0.1.2.0, + symmetry-operations-symbols ==0.0.2.1, + symparsec ==1.1.1, + synthesizer-alsa ==0.5.0.6, + synthesizer-core ==0.8.4, + synthesizer-dimensional ==0.8.1.1, + synthesizer-midi ==0.6.1.2, + sysinfo ==0.1.1, + system-argv0 ==0.1.1, + systemd ==2.4.0, + system-fileio ==0.3.16.4, + system-filepath ==0.4.14, + system-info ==0.5.2, + system-linux-proc ==0.1.1.1, + tabular ==0.2.2.8, + tagchup ==0.4.1.2, + tagged ==0.8.8, + tagged-binary ==0.2.0.1, + tagged-identity ==0.1.4, + tagged-transformer ==0.8.2, + tagsoup ==0.14.8, + tagstream-conduit ==0.5.6, + tao ==1.0.0, + tao-example ==1.0.0, + tar ==0.6.3.0, + tar-conduit ==0.4.1, + tardis ==0.5.0, + tasty ==1.5, + tasty-ant-xml ==1.1.9, + tasty-autocollect ==0.4.3, + tasty-bench ==0.4, + tasty-bench-fit ==0.1.1, + tasty-checklist ==1.0.6.0, + tasty-dejafu ==2.1.0.1, + tasty-discover ==5.0.0, + tasty-expected-failure ==0.12.3, + tasty-fail-fast ==0.0.3, + tasty-focus ==1.0.1, + tasty-golden ==2.3.5, + tasty-hedgehog ==1.4.0.2, + tasty-hslua ==1.1.1, + tasty-hspec ==1.2.0.4, + tasty-html ==0.4.2.2, + tasty-hunit ==0.10.2, + tasty-inspection-testing ==0.2.1, + tasty-kat ==0.0.3, + tasty-leancheck ==0.0.2, + tasty-lua ==1.1.1, + tasty-papi ==0.1.2.0, + tasty-program ==1.1.0, + tasty-quickcheck ==0.11, + tasty-rerun ==1.1.19, + tasty-silver ==3.3.2, + tasty-smallcheck ==0.8.2, + tasty-sugar ==2.2.2.0, + tasty-tap ==0.1.0, + tasty-th ==0.1.7, + tasty-wai ==0.1.2.0, + TCache ==0.13.3, + tce-conf ==1.3, + tdigest ==0.3.1, + teardown ==0.5.0.1, + telegram-bot-api ==7.4, + telegram-bot-simple ==0.14.2, + tempgres-client ==1.0.0, + template ==0.2.0.10, + template-haskell installed, + template-haskell-compat-v0208 ==0.1.9.4, + temporary ==1.3, + temporary-rc ==1.2.0.3, + temporary-resourcet ==0.1.0.1, + tensorflow-test ==0.1.0.0, + tensort ==1.0.1.3, + termbox ==2.0.0.1, + termbox-banana ==2.0.0, + termbox-bindings-c ==0.1.0.1, + termbox-bindings-hs ==1.0.0, + termbox-tea ==1.0.0, + terminal ==0.2.0.0, + terminal-progress-bar ==0.4.2, + terminal-size ==0.3.4, + terminfo installed, + termonad ==4.6.0.0, + test-certs ==0.1.1.1, + test-framework ==0.8.2.0, + test-framework-hunit ==0.3.0.2, + test-framework-leancheck ==0.0.4, + test-framework-quickcheck2 ==0.3.0.5, + test-framework-smallcheck ==0.2, + test-fun ==0.1.0.0, + testing-feat ==1.1.1.1, + testing-type-modifiers ==0.1.0.1, + texmath ==0.12.8.10, + text installed, + text-ansi ==0.3.0.1, + text-binary ==0.2.1.1, + text-builder ==0.6.7.2, + text-builder-dev ==0.3.5, + text-builder-linear ==0.1.3, + text-conversions ==0.3.1.1, + text-icu ==0.8.0.5, + text-iso8601 ==0.1.1, + text-latin1 ==0.3.1, + text-ldap ==0.1.1.14, + textlocal ==0.1.0.5, + text-manipulate ==0.3.1.0, + text-metrics ==0.3.3, + text-postgresql ==0.0.3.1, + text-printer ==0.5.0.2, + text-regex-replace ==0.1.1.5, + text-rope ==0.2, + text-short ==0.1.6, + text-show ==3.10.5, + text-show-instances ==3.9.8, + text-zipper ==0.13, + tfp ==1.0.2, + tf-random ==0.5, + th-abstraction ==0.7.0.0, + th-bang-compat ==0.0.1.0, + th-compat ==0.1.5, + th-constraint-compat ==0.0.1.0, + th-data-compat ==0.1.3.1, + th-deepstrict ==0.1.1.0, + th-desugar ==1.16, + th-env ==0.1.1, + these ==1.2.1, + these-lens ==1.0.2, + these-optics ==1.0.2, + these-skinny ==0.7.6, + th-expand-syns ==0.4.11.0, + th-extras ==0.0.0.8, + th-lego ==0.3.0.3, + th-lift ==0.8.4, + th-lift-instances ==0.1.20, + th-nowq ==0.1.0.5, + th-orphans ==0.13.14, + th-printf ==0.8, + thread-hierarchy ==0.3.0.2, + thread-local-storage ==0.2, + threads ==0.5.1.8, + threads-extras ==0.1.0.3, + thread-supervisor ==0.2.0.0, + threepenny-gui ==0.9.4.1, + th-reify-compat ==0.0.1.5, + th-reify-many ==0.1.10, + th-strict-compat ==0.1.0.1, + th-test-utils ==1.2.1, + th-utilities ==0.2.5.0, + tidal ==1.9.5, + tidal-link ==1.0.3, + tile ==0.3.0.0, + time installed, + time-compat ==1.9.7, + time-domain ==0.1.0.5, + timeit ==2.0, + time-lens ==0.4.0.2, + timelens ==0.2.0.2, + time-locale-compat ==0.1.1.5, + time-locale-vietnamese ==1.0.0.0, + time-manager ==0.1.0, + timerep ==2.1.0.0, + timers-tick ==0.5.0.4, + timer-wheel ==1.0.0.1, + timespan ==0.4.0.0, + time-units ==1.0.0, + time-units-types ==0.2.0.1, + timezone-olson ==0.2.1, + timezone-olson-th ==0.1.0.11, + timezone-series ==0.1.13, + titlecase ==1.0.1, + tldr ==0.9.2, + tls ==2.0.6, + tls-session-manager ==0.0.6, + tlynx ==0.7.2.2, + tmapchan ==0.0.3, + tmapmvar ==0.0.4, + tmp-proc ==0.7.1.0, + tmp-proc-postgres ==0.7.0.0, + tmp-proc-rabbitmq ==0.7.0.1, + tmp-proc-redis ==0.7.0.0, + token-bucket ==0.1.0.1, + tokenize ==0.3.0.1, + tomland ==1.3.3.3, + toml-parser ==2.0.1.0, + toml-reader ==0.2.1.0, + toml-reader-parse ==0.1.1.1, + tophat ==1.0.8.0, + topograph ==1.0.1, + torrent ==10000.1.3, + torsor ==0.1.0.1, + tracing ==0.0.7.4, + transaction ==0.1.1.4, + transformers installed, + transformers-base ==0.4.6, + transformers-compat ==0.7.2, + transformers-either ==0.1.4, + traverse-with-class ==1.0.1.1, + tree-diff ==0.3.1, + tree-fun ==0.8.1.0, + tree-view ==0.5.1, + trie-simple ==0.4.2, + trifecta ==2.1.4, + trimdent ==0.1.0.0, + trivial-constraint ==0.7.0.0, + true-name ==0.2.0.0, + tsv2csv ==0.1.0.2, + ttc ==1.4.0.0, + ttrie ==0.1.2.2, + tuple ==0.3.0.2, + tuples ==0.1.0.0, + tuples-homogenous-h98 ==0.1.1.0, + tuple-sop ==0.3.1.0, + tuple-th ==0.2.5, + turtle ==1.6.2, + twitter-types ==0.11.0, + twitter-types-lens ==0.11.0, + typecheck-plugin-nat-simple ==0.1.0.9, + typed-process ==0.2.12.0, + typed-uuid ==0.2.0.0, + type-equality ==1.0.1, + type-errors ==0.2.0.2, + type-flip ==0.1.0.0, + type-fun ==0.1.3, + type-hint ==0.1, + type-level-bytestrings ==0.2.0, + type-level-integers ==0.0.1, + type-level-kv-list ==2.0.2.0, + type-level-natural-number ==2.0, + type-level-numbers ==0.1.1.2, + type-level-show ==0.3.0, + typelits-witnesses ==0.4.1.0, + type-map ==0.1.7.0, + type-natural ==1.3.0.1, + typenums ==0.1.4, + type-of-html ==1.6.2.0, + type-of-html-static ==0.1.0.2, + type-rig ==0.1, + type-set ==0.1.0.0, + type-spec ==0.4.0.0, + typography-geometry ==1.0.1.0, + typst ==0.6, + typst-symbols ==0.1.6, + tz ==0.1.3.6, + tzdata ==0.2.20240201.0, + tztime ==0.1.1.0, + ua-parser ==0.7.7.0, + uglymemo ==0.1.0.1, + ulid ==0.3.2.0, + unagi-chan ==0.4.1.4, + unbounded-delays ==0.1.1.1, + unbound-generics ==0.4.4, + unboxed-ref ==0.4.0.0, + unboxing-vector ==0.2.0.0, + uncaught-exception ==0.1.0, + uncertain ==0.4.0.1, + unconstrained ==0.1.0.2, + unexceptionalio ==0.5.1, + unexceptionalio-trans ==0.5.2, + unicode ==0.0.1.1, + unicode-collation ==0.1.3.6, + unicode-data ==0.6.0, + unicode-show ==0.1.1.1, + unicode-transforms ==0.4.0.1, + unidecode ==0.1.0.4, + unification-fd ==0.11.2.2, + union ==0.1.2, + union-angle ==0.1.0.1, + union-color ==0.1.2.1, + union-find-array ==0.1.0.4, + unipatterns ==0.0.0.0, + uniplate ==1.6.13, + uniq-deep ==1.2.1, + unique ==0.0.1, + unique-logic ==0.4.0.1, + unique-logic-tf ==0.5.1, + unit-constraint ==0.0.0, + units ==2.4.1.5, + units-defs ==2.2.1, + units-parser ==0.1.1.5, + universe ==1.2.3, + universe-base ==1.1.4, + universe-dependent-sum ==1.3.1, + universe-instances-extended ==1.1.4, + universe-reverse-instances ==1.1.2, + universe-some ==1.2.2, + universum ==1.8.2.1, + unix installed, + unix-bytestring ==0.4.0.2, + unix-compat ==0.7.2, + unix-time ==0.4.15, + unjson ==0.15.4, + unlifted ==0.2.2.0, + unliftio ==0.2.25.0, + unliftio-core ==0.2.1.0, + unliftio-path ==0.0.2.0, + unliftio-pool ==0.4.3.0, + unliftio-streams ==0.2.0.0, + unlit ==0.4.0.0, + unordered-containers ==0.2.20, + unsafe ==0.0, + uri-bytestring ==0.3.3.1, + uri-bytestring-aeson ==0.1.0.8, + uri-encode ==1.5.0.7, + url ==2.1.3, + urlpath ==11.0.2, + userid ==0.1.3.8, + users ==0.5.0.0, + users-test ==0.5.0.1, + utf8-light ==0.4.4.0, + utf8-string ==1.0.2, + utility-ht ==0.0.17.2, + uuid ==1.3.16, + uuid-types ==1.0.6, + valida ==1.1.0, + valida-base ==0.2.0, + validate-input ==0.5.0.0, + validation ==1.1.3, + validation-selective ==0.2.0.0, + validity ==0.12.1.0, + validity-aeson ==0.2.0.5, + validity-bytestring ==0.4.1.1, + validity-case-insensitive ==0.0.0.0, + validity-containers ==0.5.0.5, + validity-network-uri ==0.0.0.1, + validity-path ==0.4.0.1, + validity-persistent ==0.0.0.0, + validity-primitive ==0.0.0.1, + validity-scientific ==0.2.0.3, + validity-text ==0.3.1.3, + validity-time ==0.5.0.0, + validity-unordered-containers ==0.2.0.3, + validity-uuid ==0.1.0.3, + validity-vector ==0.2.0.3, + valor ==1.0.0.0, + varying ==0.8.1.0, + vault ==0.3.1.5, + vcs-ignore ==0.0.2.0, + vec ==0.5.1, + vector ==0.13.1.0, + vector-algorithms ==0.9.0.2, + vector-binary-instances ==0.2.5.2, + vector-buffer ==0.4.1, + vector-builder ==0.3.8.5, + vector-bytes-instances ==0.1.1, + vector-extras ==0.2.8.2, + vector-hashtables ==0.1.2.0, + vector-instances ==3.4.2, + vector-mmap ==0.0.3, + vector-rotcev ==0.1.0.2, + vector-sized ==1.6.1, + vector-space ==0.16, + vector-split ==1.0.0.3, + vector-stream ==0.1.0.1, + vector-th-unbox ==0.2.2, + verset ==0.0.1.9, + versions ==6.0.7, + vformat ==0.14.1.0, + vformat-time ==0.1.0.0, + ViennaRNAParser ==1.3.3, + vinyl ==0.14.3, + vinyl-loeb ==0.0.1.0, + Vis ==1.0.0, + vivid-osc ==0.5.0.0, + vivid-supercollider ==0.4.1.2, + void ==0.7.3, + vty ==6.2, + vty-crossplatform ==0.4.0.0, + vty-unix ==0.2.0.0, + vty-windows ==0.2.0.3, + wai ==3.2.4, + wai-app-static ==3.1.9, + wai-cli ==0.2.3, + wai-conduit ==3.0.0.4, + wai-cors ==0.2.7, + wai-enforce-https ==1.0.0.0, + wai-eventsource ==3.0.0, + wai-extra ==3.1.15, + wai-feature-flags ==0.1.0.8, + wai-handler-launch ==3.0.3.1, + wai-logger ==2.4.1, + wai-middleware-bearer ==1.0.3, + wai-middleware-caching ==0.1.0.2, + wai-middleware-caching-lru ==0.1.0.0, + wai-middleware-caching-redis ==0.2.0.0, + wai-middleware-clacks ==0.1.0.1, + wai-middleware-delegate ==0.1.4.1, + wai-middleware-metrics ==0.2.4, + wai-middleware-prometheus ==1.0.1.0, + wai-middleware-static ==0.9.2, + wai-rate-limit ==0.3.0.0, + wai-rate-limit-redis ==0.2.0.1, + wai-saml2 ==0.6, + wai-session ==0.3.3, + wai-session-postgresql ==0.2.1.3, + wai-slack-middleware ==0.2.0, + wai-transformers ==0.1.0, + wai-websockets ==3.0.1.2, + wakame ==0.1.0.0, + warp ==3.4.2, + warp-tls ==3.4.7, + wave ==0.2.1, + wcwidth ==0.0.2, + webdriver ==0.12.0.0, + webdriver-wrapper ==0.2.0.0, + webex-teams-api ==0.2.0.1, + webex-teams-conduit ==0.2.0.1, + webgear-core ==1.3.0, + webgear-openapi ==1.3.0, + webgear-server ==1.3.0, + webgear-swagger ==1.3.0, + webgear-swagger-ui ==1.3.0, + webpage ==0.0.5.1, + web-routes ==0.27.16, + web-routes-boomerang ==0.28.4.5, + web-routes-th ==0.22.8.2, + webrtc-vad ==0.1.0.3, + websockets ==0.13.0.0, + websockets-simple ==0.2.0, + websockets-snap ==0.10.3.1, + weigh ==0.0.17, + welford-online-mean-variance ==0.2.0.0, + what4 ==1.6.2, + wherefrom-compat ==0.1.1.1, + wide-word ==0.1.6.0, + Win32 installed, + Win32-notify ==0.3.0.3, + windns ==0.1.0.1, + witch ==1.2.1.1, + withdependencies ==0.3.0, + witherable ==0.5, + within ==0.2.0.1, + with-location ==0.1.0, + with-utf8 ==1.1.0.0, + witness ==0.6.2, + wizards ==1.0.3, + wkt-types ==0.1.0.0, + wl-pprint ==1.2.1, + wl-pprint-annotated ==0.1.0.1, + wl-pprint-text ==1.2.0.2, + word8 ==0.1.3, + word-compat ==0.0.6, + word-trie ==0.3.0, + word-wrap ==0.5, + world-peace ==1.0.2.0, + wrap ==0.0.0, + wraxml ==0.5, + wreq ==0.5.4.3, + wreq-stringless ==0.5.9.1, + writer-cps-transformers ==0.5.6.1, + ws ==0.0.6, + wuss ==2.0.2.0, + X11 ==1.10.3, + X11-xft ==0.3.4, + x11-xim ==0.0.9.0, + Xauth ==0.1, + xdg-basedir ==0.2.2, + xdg-desktop-entry ==0.1.1.2, + xdg-userdirs ==0.1.0.2, + xeno ==0.6, + xhtml installed, + xlsx ==1.1.2.2, + xml ==1.3.14, + xml-basic ==0.1.3.2, + xmlbf ==0.7, + xmlbf-xeno ==0.2.2, + xmlbf-xmlhtml ==0.2.2, + xml-conduit ==1.9.1.3, + xml-conduit-writer ==0.1.1.5, + xmlgen ==0.6.2.2, + xml-hamlet ==0.5.0.2, + xml-helpers ==1.0.0, + xmlhtml ==0.2.5.4, + xml-html-qq ==0.1.0.1, + xml-indexed-cursor ==0.1.1.0, + xml-picklers ==0.3.6, + xml-to-json-fast ==2.0.0, + xml-types ==0.3.8, + xmonad ==0.18.0, + xmonad-contrib ==0.18.1, + xor ==0.0.1.3, + xss-sanitize ==0.3.7.2, + xxhash-ffi ==0.3, + yaml ==0.11.11.2, + yaml-unscrambler ==0.1.0.19, + Yampa ==0.14.10, + yarn-lock ==0.6.5, + yeshql-core ==4.2.0.0, + yesod ==1.6.2.1, + yesod-auth ==1.6.11.3, + yesod-auth-basic ==0.1.0.3, + yesod-auth-hashdb ==1.7.1.7, + yesod-auth-oauth2 ==0.7.3.0, + yesod-bin ==1.6.2.3, + yesod-core ==1.6.26.0, + yesod-csp ==0.2.6.0, + yesod-eventsource ==1.6.0.1, + yesod-form ==1.7.6, + yesod-form-bootstrap4 ==3.0.1.1, + yesod-gitrepo ==0.3.0, + yesod-gitrev ==0.2.2, + yesod-markdown ==0.12.6.14, + yesod-newsfeed ==1.7.0.0, + yesod-page-cursor ==2.0.1.0, + yesod-paginator ==1.1.2.2, + yesod-persistent ==1.6.0.8, + yesod-recaptcha2 ==1.0.2.1, + yesod-routes-flow ==3.0.0.2, + yesod-sitemap ==1.6.0, + yesod-static ==1.6.1.0, + yesod-test ==1.6.16, + yesod-websockets ==0.3.0.3, + yes-precure5-command ==5.5.3, + yggdrasil-schema ==1.0.0.5, + yi-rope ==0.11, + yjsvg ==0.2.0.1, + yjtools ==0.9.18, + yoga ==0.0.0.8, + youtube ==0.2.1.1, + zenc ==0.1.2, + zeromq4-haskell ==0.8.0, + zeromq4-patterns ==0.3.1.0, + zigzag ==0.1.0.0, + zim-parser ==0.2.1.0, + zip ==2.1.0, + zip-archive ==0.4.3.2, + zippers ==0.3.2, + zip-stream ==0.2.2.0, + zlib ==0.7.1.0, + zlib-bindings ==0.1.1.5, + zlib-clib ==1.3.1, + zot ==0.0.3, + zstd ==0.1.3.0 diff --git a/ci/scripts/cabal-check-packages.sh b/ci/scripts/cabal-check-packages.sh new file mode 100644 index 0000000..a6ffa3c --- /dev/null +++ b/ci/scripts/cabal-check-packages.sh @@ -0,0 +1,63 @@ +#!/usr/bin/env bash + +COUNT=0 +FAILS=0 +declare GITHUB_STEP_SUMMARY +declare -a invalid=() + +set -eux + +LOG_FILE=$(readlink -f ./cabal-check-log.log) +touch "${LOG_FILE}" + +trap 'rm -f "${LOG_FILE}"' EXIT + +while read -r CABAL; do + echo "Checking ${CABAL}" + COUNT=$((COUNT + 1)) + pushd "$(dirname "${CABAL}")" + echo "" >> "${LOG_FILE}" + PKG=$(basename "${CABAL}") + PKG="${PKG%.cabal}" + { + echo "### ${PKG}" + echo "" + echo '```' + } >> "${LOG_FILE}" + + if ! (cabal check >>"${LOG_FILE}" 2>&1) ; then + invalid+=("${PKG}") + FAILS=$((FAILS + 1)) + fi + + { + echo '```' + echo "" + } >> "${LOG_FILE}" + popd +done < <(find . -name '*.cabal' -not -path './dist-newstyle/**') + +if [ "${FAILS}" -gt 0 ]; then + { + echo ":no_entry_sign: Cabal check failed for the following packages:" + echo "" + for PKG in "${invalid[@]}"; do + echo "- ${PKG}" + done + + echo "" + echo "## Messages" + echo "" + cat "${LOG_FILE}" + } >> "${GITHUB_STEP_SUMMARY}" + exit 1 +else + { + echo ":white_check_mark: All Cabal green!" + echo "" + + echo "## Messages" + echo "" + cat "${LOG_FILE}" + } >> "${GITHUB_STEP_SUMMARY}" +fi diff --git a/ci/scripts/calc-cache-keys.js b/ci/scripts/calc-cache-keys.js new file mode 100644 index 0000000..6df783e --- /dev/null +++ b/ci/scripts/calc-cache-keys.js @@ -0,0 +1,40 @@ +module.exports = async ({ os, plan, path, core, glob }) => { + function build_keys(comps) { + const fallbacks = comps + .reduce((accum, cur) => [accum[0].concat([cur])].concat(accum), [[]]) + .slice(1, -1) + .map((e) => e.concat("").join("-")); + + return { key: comps.join("-"), restore: fallbacks.join("\n") }; + } + const project_hash = await glob.hashFiles("cabal.project", path); + core.setOutput("project", project_hash); + + const package_hash = await glob.hashFiles("**/package.yaml", "**/*.cabal"); + core.setOutput("package", package_hash); + + const source_hash = await glob.hashFiles( + "**/*.hs", + "**/*.lhs", + "**/*.hsig", + "**/*.hs-boot", + "**/*.c", + "**/*.h", + "**/*.chs", + "**/*.hsc" + ); + core.setOutput("source", source_hash); + + const store_prefix = `store-${os}-${plan}`; + core.setOutput("store-prefix", store_prefix); + const store_keys = build_keys([store_prefix, project_hash, package_hash]); + core.setOutput("store", store_keys.key); + core.setOutput("store-restore", store_keys.restore); + + const dist_prefix = `dist-${os}-${plan}`; + core.setOutput("dist-prefix", dist_prefix); + const dist_key_comps = [dist_prefix, project_hash, package_hash, source_hash]; + const dist_keys = build_keys(dist_key_comps); + core.setOutput("dist", dist_keys.key); + core.setOutput("dist-restore", dist_keys.restore); +}; diff --git a/ci/scripts/collect-bins.sh b/ci/scripts/collect-bins.sh new file mode 100644 index 0000000..5b13da3 --- /dev/null +++ b/ci/scripts/collect-bins.sh @@ -0,0 +1,86 @@ +#!/usr/bin/env bash +set -euo pipefail +DEST="$(pwd)/${1}" + +echo "[*] Create directory tree" +TESTS="${DEST}"/tests +TESTS_LIST="${DEST}"/tests.list +EXES="${DEST}"/exes +EXES_LIST="${DEST}"/exes.list +BENCHS="${DEST}"/benchs +BENCHS_LIST="${DEST}"/benchs.list +set -x +mkdir -p "${TESTS}" +mkdir -p "${EXES}" +mkdir -p "${BENCHS}" +touch "${TESTS_LIST}" +touch "${EXES_LIST}" +touch "${BENCHS_LIST}" +set +x + +echo "[*] Setting-up cabal-plan" +if command -v cabal-plan; then + echo "cabal-plan found." + CABAL_PLAN="$(command -v cabal-plan)" +else + echo "No cabal-plan found." + set -x + case "$(uname)" in + Darwin) + CABAL_PLAN_URL=https://github.com/konn/cabal-plan/releases/download/v0.7.2.3/cabal-plan-0.7.2.3-macOS-x86_64.xz + ;; + *) + CABAL_PLAN_URL=https://github.com/haskell-hvr/cabal-plan/releases/download/v0.6.2.0/cabal-plan-0.6.2.0-x86_64-linux.xz + ;; + esac + + wget "${CABAL_PLAN_URL}" -O cabal-plan.xz + + xz -d <./cabal-plan.xz >cabal-plan + chmod +x cabal-plan + set +x + CABAL_PLAN="$(pwd)/cabal-plan" +fi + +echo "[*] Places artifacts into the correct place" + +local_pkgs=() +while read -r TARG; do + local_pkgs+=("-e" "$(basename "${TARG%*.cabal}")"); +done < <(find . -type f -not -path '*/dist-newstyle/*' -name '*.cabal') + +${CABAL_PLAN} list-bins | grep "${local_pkgs[@]}" | while read -r TARG; do + COMPONENT=$(echo "${TARG}" | awk '{ print $1 }') + BIN=$(echo "${TARG}" | awk '{ print $2 }') + TYPE=$(echo "${COMPONENT}" | cut -d':' -f2) + echo "---" + echo "- Comp: ${COMPONENT}" + echo "- Path: ${BIN}" + echo "- Type: ${TYPE}" + case "${TYPE}" in + exe) + COPY_DEST=${EXES} + LIST=${EXES_LIST} + ;; + test) + COPY_DEST=${TESTS} + LIST=${TESTS_LIST} + ;; + *) + COPY_DEST=${BENCHS} + LIST=${BENCHS_LIST} + ;; + esac + if [ -f "${BIN}" ]; then + echo "Copying to ${COPY_DEST}" + cp "${BIN}" "${COPY_DEST}/" + basename "${BIN}" >> "${LIST}" + else + echo "Binary not found. Skipped." + fi +done +echo "[*] Collected. Compressing..." + +TARBALL="${DEST}.tar.zst" +tar --use-compress-program="zstdmt -8" -caf "${TARBALL}" "./${1}" +echo "[*] Compressed as: ${TARBALL}" diff --git a/ci/scripts/enumerate-ci.js b/ci/scripts/enumerate-ci.js new file mode 100644 index 0000000..f067694 --- /dev/null +++ b/ci/scripts/enumerate-ci.js @@ -0,0 +1,21 @@ +module.exports = async ({ github, context, core, glob, io, require }) => { + const fs = require("fs"); + const globber = await glob.create("ci/configs/*.project"); + const files = await globber.glob(); + + function generate_obj(fullpath) { + const is_head = /-head\.project$/.test(fullpath); + const path = fullpath.replace(/^.+\//, "ci/configs/"); + const name = fullpath.replaceAll(/.+\/|\.project$/g, ""); + const match = fs + .readFileSync(fullpath, "utf-8") + .match(/with-compiler:\s*ghc-([\d\.]+)/); + const ghc = match[1]; + + return { path, name, ghc, is_head }; + } + + const plans = files.map(generate_obj); + core.info(`plan: ${JSON.stringify(plans)}`); + core.setOutput("plan", JSON.stringify(plans)); +}; diff --git a/elgenerics-containers/.gitignore b/elgenerics-containers/.gitignore new file mode 100644 index 0000000..c368d45 --- /dev/null +++ b/elgenerics-containers/.gitignore @@ -0,0 +1,2 @@ +.stack-work/ +*~ \ No newline at end of file diff --git a/elgenerics-containers/ChangeLog.md b/elgenerics-containers/ChangeLog.md new file mode 100644 index 0000000..db77a35 --- /dev/null +++ b/elgenerics-containers/ChangeLog.md @@ -0,0 +1,3 @@ +# Changelog for elgenerics-containers + +## Unreleased changes diff --git a/elgenerics-containers/LICENSE b/elgenerics-containers/LICENSE new file mode 100644 index 0000000..de78212 --- /dev/null +++ b/elgenerics-containers/LICENSE @@ -0,0 +1,30 @@ +Copyright DeepFlow, Inc. (c) 2019 + +All rights reserved. + +Redistribution and use in source and binary forms, with or without +modification, are permitted provided that the following conditions are met: + + * Redistributions of source code must retain the above copyright + notice, this list of conditions and the following disclaimer. + + * Redistributions in binary form must reproduce the above + copyright notice, this list of conditions and the following + disclaimer in the documentation and/or other materials provided + with the distribution. + + * Neither the name of DeepFlow, Inc. nor the names of other + contributors may be used to endorse or promote products derived + from this software without specific prior written permission. + +THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS +"AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT +LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR +A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT +OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, +SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT +LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, +DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY +THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT +(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE +OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. diff --git a/elgenerics-containers/README.md b/elgenerics-containers/README.md new file mode 100644 index 0000000..924a4da --- /dev/null +++ b/elgenerics-containers/README.md @@ -0,0 +1,16 @@ +# `elgenerics-containers` + +A battle-tested higher-kinded extensible records, heterogeneous lists, and unions, with dedicated type-checker plugin. +See [monorepo's README](https://github.com/deepflowinc/elgenerics/README.md) for more details. + +## Contributing + +Please feel free to open an issue, but also please search for existing issues to check if there already is a similar one. + +See [CONTRIBUTING.md][CONTRIBUTING] for more details. + +[CONTRIBUTING]: https://github.com/deepflowinc/elgenerics/blob/master/CONTRIBUTING.md + +## Copyright + +(c) 2019-present, DeepFlow Inc. diff --git a/elgenerics-containers/Setup.hs b/elgenerics-containers/Setup.hs new file mode 100644 index 0000000..e8ef27d --- /dev/null +++ b/elgenerics-containers/Setup.hs @@ -0,0 +1,3 @@ +import Distribution.Simple + +main = defaultMain diff --git a/elgenerics-containers/app/record-test.hs b/elgenerics-containers/app/record-test.hs new file mode 100644 index 0000000..028dee5 --- /dev/null +++ b/elgenerics-containers/app/record-test.hs @@ -0,0 +1,47 @@ +{-# LANGUAGE DataKinds #-} +{-# LANGUAGE DeriveAnyClass #-} +{-# LANGUAGE DerivingStrategies #-} +{-# LANGUAGE DisambiguateRecordFields #-} +{-# LANGUAGE DuplicateRecordFields #-} +{-# LANGUAGE GADTs #-} +{-# LANGUAGE OverloadedLabels #-} +{-# LANGUAGE RecordWildCards #-} +{-# LANGUAGE TemplateHaskell #-} +{-# LANGUAGE TypeFamilies #-} +{-# LANGUAGE UndecidableInstances #-} +{-# OPTIONS_GHC -dcore-lint #-} +{-# OPTIONS_GHC -fplugin Data.Record.Plugin #-} +{-# OPTIONS_GHC -fplugin Data.TypeLevel.List.Overloaded #-} +{-# OPTIONS_GHC -fplugin-opt Data.Record.Plugin:MyRecord #-} + +module Main where + +import Data.Record.HigherKinded (IsHRecord (..)) +import Data.Record.HigherKinded qualified as HK +import GHC.Generics (Generic) + +-- 以下のデータ型自体はテストでは用いられていない。 +-- しかし、コンパイルが現実的な時間で通ること自体がテストの意図になっている。 + +data ManyFields = ManyFields + { mf2 :: String + , mf5 :: Int + , mf6 :: String + , mf7 :: Int + , mf1 :: Int + , mf8 :: String + , mf10 :: String + , mf11 :: Int + , mf3 :: Int + , mf12 :: String + , mf13 :: String + , mf4 :: String + , mf14 :: String + , mf9 :: Int + , mf15 :: String + } + deriving (Generic) + deriving anyclass (IsHRecord HK.STagged) + +main :: IO () +main = putStrLn "Finished!" diff --git a/elgenerics-containers/app/record-tylist-test.hs b/elgenerics-containers/app/record-tylist-test.hs new file mode 100644 index 0000000..cfbaf2a --- /dev/null +++ b/elgenerics-containers/app/record-tylist-test.hs @@ -0,0 +1,106 @@ +{-# LANGUAGE AllowAmbiguousTypes #-} +{-# LANGUAGE DataKinds #-} +{-# LANGUAGE GADTs #-} +{-# LANGUAGE QuantifiedConstraints #-} +{-# LANGUAGE TemplateHaskell #-} +{-# LANGUAGE TypeFamilies #-} +{-# LANGUAGE UndecidableInstances #-} +{-# OPTIONS_GHC -Wno-orphans -dcore-lint #-} +{-# OPTIONS_GHC -Wno-unused-foralls -Wno-missing-methods #-} +{-# OPTIONS_GHC -fplugin Data.TypeLevel.List.Solver #-} + +module Main where + +import Data.Constraint.Operators (All) +import Data.Functor.Compose (Compose (Compose)) +import Data.Functor.Identity (Identity (Identity)) +import Data.HList.HigherKinded (HList, hfoldMap, hmap) +import Data.Proxy (Proxy (..)) +import Data.TypeLevel.List (ElemAt, KnownTyList, Map) +import Data.Vector.Generic qualified as G +import Data.Vector.Generic.Mutable qualified as GM +import Data.Vector.Unboxed qualified as U + +data Dict c where + Dict :: (c) => Dict c + +class Printable a where + doPrint :: a -> IO () + anotherPrint :: a -> IO () + +newtype MyHList h xs = MyHList {runMyHList :: HList h xs} + +instance + (KnownTyList xs, All U.Unbox (Map h xs)) => + Printable (MyHList h xs) + where + doPrint (MyHList hl) = + hfoldMap + ( \(Proxy :: (G.Vector U.Vector (h (ElemAt k xs))) => Proxy k) + (Proxy :: Proxy x) + (_ :: h x) -> + return () + ) + hl + anotherPrint (MyHList hl) = + hfoldMap + ( \(Proxy :: Proxy k) + (Proxy :: Proxy x) + (_ :: h x) -> + return () + ) + hl + +main :: IO () +main = putStrLn "Everytihng is ok; just to check whether it compiles suffices." + +class ToTuple a where + toTuple :: a -> () + +toTupling :: + forall h as. + (All ToTuple (Map h as), KnownTyList as) => + HList h as -> + () +toTupling = + hfoldMap $ const $ const toTuple + +newtype HL h as = HL {runHL :: HList h as} + +data instance U.Vector (HL h as) + = V_HL !Int !(HList Identity (Map (Compose U.Vector h) as)) + +data instance U.MVector s (HL h as) + = MV_HL !Int !(HList Identity (Map (U.MVector s) (Map h as))) + +instance + (KnownTyList as, All U.Unbox (Map h as)) => + U.Unbox (HL h as) + +instance + (KnownTyList as, All U.Unbox (Map h as)) => + G.Vector U.Vector (HL h as) + where + basicUnsafeSlice i n (V_HL _ vs) = + V_HL n $ + hmap @Identity @Identity + @(Map (Compose U.Vector h) as) + @(Map (Compose U.Vector h) as) + ( \(Proxy :: Proxy k) (Identity (Compose uv)) -> + Identity $ Compose $ G.basicUnsafeSlice i n uv + ) + vs + +instance + (KnownTyList as, All U.Unbox (Map h as)) => + GM.MVector U.MVector (HL h as) + where + basicUnsafeSlice i n (MV_HL _ vs :: U.MVector s (HL h as)) = + MV_HL n $ + hmap @Identity @Identity + @(Map (U.MVector s) (Map h as)) + @(Map (U.MVector s) (Map h as)) + ( \(Proxy :: Proxy k) (Identity uv) -> + Identity $ GM.basicUnsafeSlice i n uv + ) + vs diff --git a/elgenerics-containers/elgenerics-containers.cabal b/elgenerics-containers/elgenerics-containers.cabal new file mode 100644 index 0000000..e754a03 --- /dev/null +++ b/elgenerics-containers/elgenerics-containers.cabal @@ -0,0 +1,150 @@ +cabal-version: 3.4 +name: elgenerics-containers +version: 0.1.0.0 +category: Data, Generic Programming +synopsis: A battle-tested heterogeneous list, extensible records, unions with type-checker plugins. +description: Please see the README on GitHub at +author: DeepFlow, Inc. +maintainer: DeepFlow, Inc. +copyright: (c) 2020-present, DeepFlow, Inc. +license: BSD-3-Clause +license-file: LICENSE +build-type: Simple +extra-doc-files: + ChangeLog.md + README.md + +data-dir: data + +common defaults + build-depends: base >=4.7 && <5 + ghc-options: + -Wall + -Wcompat + -Widentities + -Wincomplete-record-updates + -Wincomplete-uni-patterns + -Wmissing-export-lists + -Wmissing-home-modules + -Wpartial-fields + -Wno-redundant-constraints + -Wunused-packages + + default-language: GHC2021 + other-modules: Paths_elgenerics_containers + autogen-modules: Paths_elgenerics_containers + +library + import: defaults + -- cabal-gild: discover src + exposed-modules: + Data.HList + Data.HList.HigherKinded + Data.HList.HigherKinded.Builder + Data.HList.Internal + Data.Product.Class + Data.Record + Data.Record.Builder.HigherKinded + Data.Record.Builder.HigherKinded.BottomUp + Data.Record.HigherKinded + Data.Record.HigherKinded.Internal + Data.Record.HigherKinded.OnEntry + Data.Record.HigherKinded.Unsafe + Data.Record.Plugin + Data.Sum.Class + Data.TypeLevel.BinTree + Data.TypeLevel.Path + Data.Union + Data.Union.HigherKinded + Data.Union.Internal + + hs-source-dirs: src + build-depends: + aeson, + base >=4.7 && <5, + bifunctors, + constraints, + containers, + deepseq, + distributive, + dlist, + elgenerics-known, + foldl, + ghc, + ghc-typelits-knownnat, + lens, + primitive, + semialign, + syb, + tagged, + these, + vector, + vector-builder, + vector-th-unbox, + +test-suite elgenerics-containers-test + import: defaults + type: exitcode-stdio-1.0 + main-is: Spec.hs + -- cabal-gild: discover test --exclude=test/Spec.hs + other-modules: + Data.Record.Builder.HigherKinded.BottomUpSpec + Data.Record.Builder.HigherKindedSpec + Data.Record.Cases + Data.Record.Failures + Data.Record.HigherKindedSpec + Data.Record.PluginSpec + Data.RecordSpec + + hs-source-dirs: test + ghc-options: + -threaded + -rtsopts + -with-rtsopts=-N + + build-tool-depends: tasty-discover:tasty-discover + build-depends: + QuickCheck, + base >=4.7 && <5, + deepseq, + dlist, + elgenerics-containers, + elgenerics-known, + ghc-typelits-knownnat, + ghc-typelits-presburger, + lens, + tagged, + tasty, + tasty-hunit, + tasty-quickcheck, + text, + vector, + +test-suite record-test + import: defaults + type: exitcode-stdio-1.0 + main-is: record-test.hs + hs-source-dirs: app + ghc-options: + -fplugin + Data.Record.Plugin + + build-depends: + base, + elgenerics-containers, + elgenerics-known, + +test-suite record-tylist-test + import: defaults + type: exitcode-stdio-1.0 + main-is: record-tylist-test.hs + hs-source-dirs: app + ghc-options: + -fplugin + Data.TypeLevel.List.Solver + + build-depends: + base >=4.7 && <5, + elgenerics-containers, + elgenerics-known, + vector, diff --git a/elgenerics-containers/src/Data/HList.hs b/elgenerics-containers/src/Data/HList.hs new file mode 100644 index 0000000..743cf1a --- /dev/null +++ b/elgenerics-containers/src/Data/HList.hs @@ -0,0 +1,302 @@ +{-# LANGUAGE AllowAmbiguousTypes #-} +{-# LANGUAGE DataKinds #-} +{-# LANGUAGE DefaultSignatures #-} +{-# LANGUAGE DerivingStrategies #-} +{-# LANGUAGE GADTs #-} +{-# LANGUAGE PatternSynonyms #-} +{-# LANGUAGE TypeFamilies #-} +{-# LANGUAGE UndecidableInstances #-} +{-# LANGUAGE UndecidableSuperClasses #-} +{-# OPTIONS_GHC -Wno-orphans #-} +{-# OPTIONS_GHC -fplugin Data.TypeLevel.List.Solver #-} + +module Data.HList ( + pattern (:-), + pattern HNil, + HList, + (:<-) (..), + HasFactor', + hsingleton, + happend, + hsplitAt, + generate, + generateM, + hindex, + hconcat, + htoList, + hzipWithM_, + hmapM, + hmapM_, + hmap, + hany, + hfoldMap, + hslice, + HasFactors (..), + HListLike (..), + CoercedHList (..), +) where + +import Data.Constraint +import Data.Constraint.Operators +import Data.Functor.Identity +import Data.HList.HigherKinded qualified as HK +import Data.Kind (Type) +import Data.Membership +import Data.Product.Class +import Data.Proxy +import Data.TypeLevel.List +import Data.TypeLevel.Path +import GHC.Exts +import Unsafe.Coerce + +type HList = HK.HList Identity + +-- | O(1) +hindex :: forall k as. (KnownNat k) => Proxy k -> HList as -> ElemAt k as +hindex = coerce $ HK.hindex @k @Identity @as + +infixr 9 :- + +pattern (:-) :: () => (Member a as', as' ~ (a ': as)) => a -> HList as -> HList as' +pattern a :- v = Identity a HK.:- v + +pattern HNil :: () => (qs ~ '[]) => HList qs +pattern HNil = HK.HNil + +{-# COMPLETE HNil, (:-) #-} + +happend :: HList as -> HList bs -> HList (as ++ bs) +happend = HK.happend + +generate :: + forall as. + (KnownTyList as) => + (forall k. (KnownNat k) => Proxy k -> ElemAt k as) -> + HList as +{-# INLINE generate #-} +generate = \f -> HK.generate (Identity . f) + +generateM :: + forall m as. + (KnownTyList as, Monad m) => + (forall k. (KnownNat k) => Proxy k -> m (ElemAt k as)) -> + m (HList as) +{-# INLINE generateM #-} +generateM = \f -> + HK.generateM (fmap Identity . f) + +hconcat :: HK.HList HList as -> HList (Concat as) +hconcat = HK.hconcat + +htoList :: + forall as a. + (forall x. (Member x as) => x -> a) -> + HList as -> + [a] +htoList f = HK.htoList @Identity @as @a (f . runIdentity) + +hsingleton :: a -> HList '[a] +{-# INLINE hsingleton #-} +hsingleton = HK.hsingleton . Identity + +hzipWithM_ :: + forall m as as'. + (Monad m) => + ( forall k. + ( KnownNat k + , Member (ElemAt k as) as + , Member (ElemAt k as') as' + ) => + Proxy k -> + ElemAt k as -> + ElemAt k as' -> + m () + ) -> + HList as -> + HList as' -> + m () +{-# INLINE hzipWithM_ #-} +hzipWithM_ = + \f -> HK.hzipWithM_ @_ @_ @m @as @as' (\p (Identity x) (Identity y) -> f p x y) + +hmapM :: + forall m as as'. + (Monad m) => + ( forall k. + ( KnownNat k + , Member (ElemAt k as) as + , Member (ElemAt k as') as' + ) => + Proxy k -> + ElemAt k as -> + m (ElemAt k as') + ) -> + HList as -> + m (HList as') +{-# INLINE hmapM #-} +hmapM f = + HK.hmapM @_ @_ @_ @as @as' + (\p (Identity x) -> Identity <$> f p x) + +hmapM_ :: + forall m as. + (Monad m) => + ( forall k. + ( KnownNat k + , Member (ElemAt k as) as + ) => + Proxy k -> + ElemAt k as -> + m () + ) -> + HList as -> + m () +hmapM_ = \f -> HK.hmapM_ @_ @Identity @as (\p -> f p . runIdentity) + +hfoldMap :: + forall as w. + (Monoid w) => + ( forall k x. + (KnownNat k, Member x as, ElemAt k as ~ x) => + Proxy k -> + Proxy x -> + x -> + w + ) -> + HList as -> + w +hfoldMap = \f -> HK.hfoldMap @Identity @as @w $ + \p l -> f p l . runIdentity + +hmap :: + forall as as'. + ( forall k. + ( KnownNat k + , Member (ElemAt k as) as + , Member (ElemAt k as') as' + ) => + Proxy k -> + ElemAt k as -> + ElemAt k as' + ) -> + HList as -> + HList as' +hmap = \f -> HK.hmap (\p -> Identity . f p . runIdentity) + +hany :: + forall as. + ( forall k. + ( KnownNat k + , Member (ElemAt k as) as + ) => + Proxy k -> + ElemAt k as -> + Bool + ) -> + HList as -> + Bool +{-# INLINE hany #-} +hany = \f -> HK.hany (\p -> f p . runIdentity) + +instance {-# OVERLAPPING #-} (KnownTyList as, All Show as) => Show (HList as) where + showsPrec _ HNil = showString "[]" + showsPrec _ vs = + showString "[" + . foldr1 + (\a b -> a . showString ", " . b) + ( htoList + ( \(x :: (Member x as) => x) -> + showsPrec 11 x \\ subDict @Show @x @as + ) + vs + ) + . showString "]" + +hslice :: + (KnownNatList ns) => + pxy ns -> + HList as -> + HK.HList HList (Sliced ns as) +hslice = HK.hslice + +hsplitAt :: + (KnownNat n) => + pxy n -> + HList as -> + (HList (Take n as), HList (Drop n as)) +hsplitAt = HK.hsplitAt + +class (HasFactor c a) => HasFactor' a c + +instance (HasFactor c a) => HasFactor' a c + +newtype a :<- b = Flip {runFlipArrow :: b -> a} + +class (All (HasFactor' a) (Factors a)) => HasFactors a where + type Factors a :: [Type] + type Factors a = GFacts (Rep a) + +class (HasFactors a) => HListLike a where + toHList :: a -> HList (Factors a) + fromHList :: HList (Factors a) -> a + default toHList :: + (Generic a, GHListLike (Rep a), GFacts (Rep a) ~ Factors a) => + a -> + HList (Factors a) + toHList = gtoHList . from + default fromHList :: + (Generic a, GHListLike (Rep a), GFacts (Rep a) ~ Factors a) => + HList (Factors a) -> + a + fromHList = to . gfromHList + +class GHListLike f where + type GFacts f :: [Type] + gtoHList :: f () -> HList (GFacts f) + gfromHList :: HList (GFacts f) -> f () + +instance GHListLike (K1 i c) where + type GFacts (K1 i c) = '[c] + gtoHList (K1 a) = hsingleton a + gfromHList (a :- HNil) = K1 a + +instance (GHListLike f) => GHListLike (M1 i c f) where + type GFacts (M1 i c f) = GFacts f + gtoHList (M1 f) = gtoHList f + gfromHList = M1 . gfromHList + +instance (KnownTyList (GFacts f), GHListLike f, GHListLike g) => GHListLike (f :*: g) where + type GFacts (f :*: g) = GFacts f ++ GFacts g + gtoHList (f :*: g) = happend (gtoHList f) (gtoHList g) + gfromHList v = + let (lh, rh) = hsplitAt (Proxy @(Length (GFacts f))) v + in (gfromHList (unsafeCoerce lh) :*: gfromHList (unsafeCoerce rh)) + +instance GHListLike U1 where + type GFacts U1 = '[] + gtoHList _ = HNil + gfromHList _ = U1 + +newtype CoercedHList bs a = CoercedHList {runCoercedHList :: a} + deriving (Read, Show, Eq, Ord) + +instance + ( Generic a + , GHListLike (Rep a) + , Coercible (GFacts (Rep a)) bs + , All (HasFactor' (CoercedHList bs a)) bs + ) => + HasFactors (CoercedHList bs a) + where + type Factors (CoercedHList bs a) = bs + +instance + ( Generic a + , GHListLike (Rep a) + , Coercible (GFacts (Rep a)) bs + , All (HasFactor' (CoercedHList bs a)) bs + ) => + HListLike (CoercedHList bs a) + where + toHList = unsafeCoerce . gtoHList . from . runCoercedHList + fromHList = CoercedHList . to . gfromHList . unsafeCoerce diff --git a/elgenerics-containers/src/Data/HList/HigherKinded.hs b/elgenerics-containers/src/Data/HList/HigherKinded.hs new file mode 100644 index 0000000..8cbefe8 --- /dev/null +++ b/elgenerics-containers/src/Data/HList/HigherKinded.hs @@ -0,0 +1,986 @@ +{-# LANGUAGE AllowAmbiguousTypes #-} +{-# LANGUAGE DataKinds #-} +{-# LANGUAGE GADTs #-} +{-# LANGUAGE PatternSynonyms #-} +{-# LANGUAGE TypeFamilies #-} +{-# LANGUAGE UndecidableInstances #-} +{-# LANGUAGE ViewPatterns #-} +{-# OPTIONS_GHC -Wno-orphans -dcore-lint #-} +{-# OPTIONS_GHC -fplugin Data.TypeLevel.List.Solver #-} + +module Data.HList.HigherKinded ( + HList ((:-), HNil), + HListView (..), + viewHList, + hsingleton, + castAppliedCon, + happend, + hsplitAt, + factorIdentity, + hfoldMap, + hfoldr, + hfoldl', + purify, + purifyApply, + innerComp, + factor, + generateM, + generateA, + generate, + hix, + hindex, + hconcat, + htoList, + hzip, + hzipWithM, + hzipWith, + hzipWithM_, + hzipWith3, + hzipWithM3, + hunzip, + hunzip', + hunzipWith, + hunzipWithM, + hmapM, + hmapM_, + htraverse_, + hmap, + htraverse, + hany, + hall, + liftHList, + hslice, + hset, + hset', + hmodify, + hmodify', +) where + +import Control.Arrow +import Control.DeepSeq +import Control.Lens (Lens', lens) +import Control.Monad.Primitive +import Data.Constraint hiding ((***)) +import Data.Constraint.Operators +import Data.Foldable qualified as F +import Data.Functor.Compose +import Data.Functor.Identity +import Data.Functor.Product +import Data.HList.Internal +import Data.Membership +import Data.Monoid (Endo (..)) +import Data.Monoid qualified as Mon +import Data.Proxy +import Data.Type.Equality +import Data.TypeLevel.Function +import Data.TypeLevel.List +import Data.TypeLevel.Ord () +import Data.TypeLevel.OrdMap () +import Data.Vector qualified as V +import Data.Vector.Fusion.Bundle.Monadic qualified as FV +import Data.Vector.Generic qualified as G +import Data.Vector.Generic.Mutable qualified as M +import Data.Vector.Mutable qualified as MV +import Data.Vector.Unboxed qualified as U +import GHC.Exts +import Unsafe.Coerce + +-- | O(1) +hindex :: (KnownNat k) => Proxy k -> HList h as -> h (ElemAt k as) +hindex k = unsafeCoerce $ flip V.unsafeIndex $ fromIntegral $ natVal k + +unconsV :: V.Vector a -> Maybe (a, V.Vector a) +unconsV v = + if V.null v + then Nothing + else Just (V.unsafeHead v, V.unsafeTail v) + +data HListView h as where + HNilV :: HListView h '[] + HConsV :: h a -> HList h as -> HListView h (a ': as) + +viewHList :: forall h as. HList h as -> HListView h as +{-# NOINLINE viewHList #-} -- NOTE: See https://gitlab.haskell.org/ghc/ghc/issues/16893 +viewHList (HL v) = + case unconsV v of + Nothing -> unsafeCoerce HNilV + Just (a, vs) -> unsafeCoerce $ HConsV (unsafeCoerce a) $ HL vs + +liftHList :: (forall a. f a -> g a) -> HList f as -> HList g as +liftHList f = hmap (const f) + +infixr 9 :- + +pattern (:-) :: () => (Member a as', as' ~ (a ': as)) => h a -> HList h as -> HList h as' +pattern a :- v <- + (viewHList -> HConsV a v) + where + a :- (HL v) = HL (V.cons (unsafeCoerce a) v) + +pattern HNil :: () => (qs ~ '[]) => HList h qs +pattern HNil <- + (viewHList -> HNilV) + where + HNil = HL V.empty + +{-# COMPLETE HNil, (:-) #-} + +generate :: + forall h as. + (KnownTyList as) => + ( forall n. + ( KnownNat n + , Member (h (ElemAt n as)) (Map h as) + , Member (ElemAt n as) as + ) => + Proxy n -> + h (ElemAt n as) + ) -> + HList h as +generate f = + HL $ + V.generate (fromIntegral $ tyListLength @(Map h as)) $ \i -> + withKnownNat (fromIntegral i) $ \(p :: Proxy n) -> + unsafeCoerce $ f p + +generateA :: + forall f h as. + (Applicative f, KnownTyList as) => + ( forall n. + ( KnownNat n + , Member (h (ElemAt n as)) (Map h as) + , Member (ElemAt n as) as + ) => + Proxy n -> + f (h (ElemAt n as)) + ) -> + f (HList h as) +generateA f = + fmap HL $ + sequenceA $ + V.generate (fromIntegral $ tyListLength @(Map h as)) $ \i -> + withKnownNat (fromIntegral i) $ + fmap (unsafeCoerce @_ @Any) . f + +generateM :: + forall m h as. + (Monad m, KnownTyList as) => + ( forall k. + (KnownNat k, Member (ElemAt k as) as) => + Proxy k -> + m (h (ElemAt k as)) + ) -> + m (HList h as) +generateM f = + fmap HL $ + V.generateM (fromIntegral $ tyListLength @(Map h as)) $ \i -> + withKnownNat (fromIntegral i) $ fmap unsafeCoerce . f + +hconcat :: HList (HList h) as -> HList h (Concat as) +hconcat = HL . F.fold . unsafeCoerce @_ @(V.Vector (V.Vector Any)) + +happend :: HList h as -> HList h bs -> HList h (as ++ bs) +happend (HL v) (HL u) = HL $ v V.++ u + +purify :: HList f as -> HList Identity (Map f as) +purify = unsafeCoerce + +purifyApply :: HList (Applied f) as -> HList Identity (MapApply f as) +purifyApply = unsafeCoerce + +innerComp :: + HList (Applied (f .: g)) as -> + HList (Applied f) (MapApply g as) +innerComp = unsafeCoerce + +castAppliedCon :: + HList (Applied (Con h)) as -> + HList h as +castAppliedCon = unsafeCoerce + +factor :: forall g as f. HList f (Map g as) -> HList (Applied (Con f .: Con g)) as +factor = unsafeCoerce + +factorIdentity :: + HList Identity (MapApply f as) -> + HList (Applied f) as +factorIdentity = unsafeCoerce + +htoList :: + forall h as a. + (forall x. (Member x as, Member (h x) (Map h as)) => h x -> a) -> + HList h as -> + [a] +htoList f (HL v) = + V.toList $ + V.imap + ( \i x -> + withKnownNat (fromIntegral i) $ \(Proxy :: Proxy i) -> + f (unsafeCoerce x :: h (ElemAt i as)) + ) + v + +hsingleton :: h a -> HList h '[a] +hsingleton = HL . V.singleton . unsafeCoerce + +data instance U.Vector (HList h as) + = V_HList !Int !(HList (Compose U.Vector h) as) + +data instance U.MVector s (HList h as) + = MV_HList !Int !(HList (Compose (U.MVector s) h) as) + +instance + (All NFData (Map h as), KnownTyList as) => + NFData (HList h as) + where + rnf = + hfoldr + (\(_ :: Proxy k) _ a b -> rnf a `seq` b) + () + +instance + (All U.Unbox (Map h as), KnownTyList as) => + U.Unbox (HList h as) + +instance + (All U.Unbox (Map h as), KnownTyList as) => + G.Vector U.Vector (HList h as) + where + basicUnsafeFreeze (MV_HList n vs) = + V_HList n + <$> hmapM + ( \(Proxy :: Proxy k) (Compose v) -> do + unsafeCoerce <$> G.basicUnsafeFreeze v + ) + vs + basicUnsafeThaw (V_HList n vs) = + MV_HList n + <$> hmapM + ( \(Proxy :: Proxy k) (Compose e) -> do + Compose <$> G.basicUnsafeThaw e + ) + vs + basicLength (V_HList l _) = l + basicUnsafeIndexM (V_HList _ vs) i = + hmapM @_ @_ @_ @as @as + ( \(Proxy :: Proxy k) (Compose uv) -> + G.basicUnsafeIndexM + (uv :: U.Vector (h (ElemAt k as))) + i + ) + vs + + basicUnsafeSlice i n (V_HList _ vs) = + V_HList n $ + hmap + ( \(Proxy :: Proxy k) (Compose uv) -> + Compose $ G.basicUnsafeSlice i n uv + ) + vs + +instance + (All U.Unbox (Map h as), KnownTyList as) => + M.MVector U.MVector (HList h as) + where + basicLength (MV_HList n _) = n + + basicUnsafeNew :: + forall m. + (PrimMonad m) => + Int -> + m (U.MVector (PrimState m) (HList h as)) + basicUnsafeNew n = + fmap (MV_HList n) $ + generateM $ \(Proxy :: Proxy k) -> + Compose <$> M.basicUnsafeNew @U.MVector @(h (ElemAt k as)) n + + basicUnsafeRead :: + forall m. + (PrimMonad m) => + U.MVector (PrimState m) (HList h as) -> + Int -> + m (HList h as) + basicUnsafeRead (MV_HList _ v) i = + hmapM + ( \(Proxy :: Proxy k) (Compose u) -> + M.basicUnsafeRead u i + ) + v + + basicUnsafeWrite :: + forall m. + (PrimMonad m) => + U.MVector (PrimState m) (HList h as) -> + Int -> + HList h as -> + m () + basicUnsafeWrite (MV_HList _ vs) i xs = + hzipWithM_ + ( \(Proxy :: Proxy i) (Compose v) x -> + M.basicUnsafeWrite @U.MVector v i x + ) + vs + xs + + basicInitialize :: + forall m. + (PrimMonad m) => + U.MVector (PrimState m) (HList h as) -> + m () + basicInitialize (MV_HList _ vs) = + hmapM_ + ( \(Proxy :: Proxy k) -> + M.basicInitialize . getCompose + ) + vs + basicUnsafeSlice :: + forall s. + Int -> + Int -> + U.MVector s (HList h as) -> + U.MVector s (HList h as) + basicUnsafeSlice i n (MV_HList _ vs) = + MV_HList n $ + hmap + ( \(Proxy :: Proxy k) (Compose uv) -> Compose $ M.basicUnsafeSlice i n uv + ) + vs + + basicOverlaps :: + forall s. + U.MVector s (HList h as) -> + U.MVector s (HList h as) -> + Bool + basicOverlaps + (MV_HList _ vs) + (MV_HList _ us) = + hany + ( \(Proxy :: Proxy k) (Pair (Compose fx) (Compose gx)) -> + (M.basicOverlaps @U.MVector @(h (ElemAt k as)) @s fx gx) + ) + $ hzip vs us + +hzip :: + HList f as -> HList g as -> HList (Product f g) as +{-# INLINE [1] hzip #-} +hzip = \(HL as) (HL bs) -> + HL $ + V.zipWith + (\fa gb -> unsafeCoerce $ Pair (fa, gb)) + as + bs + +hzipWith :: + forall f bs h g as as'. + ( forall k. + ( KnownNat k + , Member (ElemAt k as) as + , Member (h (ElemAt k as)) (Map h as) + , Member (ElemAt k as') as' + , Member (g (ElemAt k as')) (Map g as') + , Member (ElemAt k bs) bs + , Member (f (ElemAt k bs)) (Map f bs) + ) => + Proxy k -> + h (ElemAt k as) -> + g (ElemAt k as') -> + f (ElemAt k bs) + ) -> + HList h as -> + HList g as' -> + HList f bs +{-# INLINE hzipWith #-} +hzipWith f = \(HL as) (HL bs) -> + HL $ + V.izipWith + ( \(fromIntegral -> i) a b -> + withKnownNat i $ \p@(Proxy :: Proxy i) -> + unsafeCoerce @_ @Any $ + f p (unsafeCoerce a) (unsafeCoerce b) + ) + as + bs + +hzipWithM :: + forall f bs h g as as' m. + (Monad m) => + ( forall k. + ( KnownNat k + , Member (ElemAt k as) as + , Member (h (ElemAt k as)) (Map h as) + , Member (ElemAt k as') as' + , Member (g (ElemAt k as')) (Map g as') + , Member (ElemAt k bs) bs + , Member (f (ElemAt k bs)) (Map f bs) + ) => + Proxy k -> + h (ElemAt k as) -> + g (ElemAt k as') -> + m (f (ElemAt k bs)) + ) -> + HList h as -> + HList g as' -> + m (HList f bs) +{-# INLINE hzipWithM #-} +hzipWithM f (HL v) (HL u) = + fmap HL $ + V.izipWithM + ( \(fromIntegral -> k) a b -> + withKnownNat k $ \p@(Proxy :: Proxy k) -> + let ek = unsafeCoerce a :: h (ElemAt k as) + el = unsafeCoerce b :: g (ElemAt k as') + in unsafeCoerce <$> f p ek el + ) + v + u + +hzipWithM3 :: + forall f bs h g l as as' as'' m. + (Monad m) => + ( forall k. + ( KnownNat k + , Member (ElemAt k as) as + , Member (h (ElemAt k as)) (Map h as) + , Member (ElemAt k as') as' + , Member (g (ElemAt k as')) (Map g as') + , Member (ElemAt k as'') as'' + , Member (l (ElemAt k as'')) (Map l as'') + , Member (ElemAt k bs) bs + , Member (f (ElemAt k bs)) (Map f bs) + ) => + Proxy k -> + h (ElemAt k as) -> + g (ElemAt k as') -> + l (ElemAt k as'') -> + m (f (ElemAt k bs)) + ) -> + HList h as -> + HList g as' -> + HList l as'' -> + m (HList f bs) +{-# INLINE hzipWithM3 #-} +hzipWithM3 f (HL v) (HL u) (HL w) = + fmap HL $ + G.unstreamM $ + FV.zipWith3M + ( \(fromIntegral -> k, a) b c -> + withKnownNat k $ \p@(Proxy :: Proxy k) -> + let ek = unsafeCoerce a :: h (ElemAt k as) + el = unsafeCoerce b :: g (ElemAt k as') + eo = unsafeCoerce c :: l (ElemAt k as'') + in unsafeCoerce <$> f p ek el eo + ) + (FV.indexed $ FV.fromVector v) + (FV.fromVector u) + (FV.fromVector w) + +hzipWith3 :: + forall f bs h g l as as' as''. + ( forall k. + ( KnownNat k + , Member (ElemAt k as) as + , Member (h (ElemAt k as)) (Map h as) + , Member (ElemAt k as') as' + , Member (g (ElemAt k as')) (Map g as') + , Member (ElemAt k as'') as'' + , Member (l (ElemAt k as'')) (Map l as'') + , Member (ElemAt k bs) bs + , Member (f (ElemAt k bs)) (Map f bs) + ) => + Proxy k -> + h (ElemAt k as) -> + g (ElemAt k as') -> + l (ElemAt k as'') -> + f (ElemAt k bs) + ) -> + HList h as -> + HList g as' -> + HList l as'' -> + HList f bs +{-# INLINE hzipWith3 #-} +hzipWith3 f (HL v) (HL u) (HL w) = + HL $ + V.izipWith3 + ( \(fromIntegral -> k) a b c -> + withKnownNat k $ \p@(Proxy :: Proxy k) -> + let ek = unsafeCoerce a :: h (ElemAt k as) + el = unsafeCoerce b :: g (ElemAt k as') + eo = unsafeCoerce c :: l (ElemAt k as'') + in unsafeCoerce $ f p ek el eo + ) + v + u + w + +hzipWithM_ :: + forall h g m as as'. + (Monad m) => + ( forall k. + ( KnownNat k + , Member (ElemAt k as) as + , Member (h (ElemAt k as)) (Map h as) + , Member (ElemAt k as') as' + , Member (g (ElemAt k as')) (Map g as') + ) => + Proxy k -> + h (ElemAt k as) -> + g (ElemAt k as') -> + m () + ) -> + HList h as -> + HList g as' -> + m () +{-# INLINE hzipWithM_ #-} +hzipWithM_ f = \(HL as) (HL bs) -> + V.izipWithM_ + ( \(fromIntegral -> i) a b -> + withKnownNat i $ \p@(Proxy :: Proxy i) -> + f p (unsafeCoerce a) (unsafeCoerce b) + ) + as + bs + +hsplitAt :: + forall n h as pxy. + (KnownNat n) => + pxy n -> + HList h as -> + (HList h (Take n as), HList h (Drop n as)) +hsplitAt p (HL v) = + let (lh, rh) = V.splitAt (fromIntegral $ natVal p) v + in (HL lh, HL rh) + +hmapM :: + forall m h g as as'. + (Monad m) => + ( forall k. + ( KnownNat k + , Member (ElemAt k as) as + , Member (h (ElemAt k as)) (Map h as) + , Member (ElemAt k as') as' + , Member (g (ElemAt k as')) (Map g as') + ) => + Proxy k -> + h (ElemAt k as) -> + m (g (ElemAt k as')) + ) -> + HList h as -> + m (HList g as') +hmapM f (HL v) = + fmap HL $ + flip V.imapM v $ \(fromIntegral -> k) a -> + withKnownNat k $ \p@(Proxy :: Proxy k) -> do + let ek = unsafeCoerce a :: h (ElemAt k as) + unsafeCoerce <$> f p ek + +hmapM_ :: + forall m h as. + (Monad m) => + ( forall k. + ( KnownNat k + , Member (ElemAt k as) as + , Member (h (ElemAt k as)) (Map h as) + ) => + Proxy k -> + h (ElemAt k as) -> + m () + ) -> + HList h as -> + m () +hmapM_ f (HL v) = + flip V.imapM_ v $ \(fromIntegral -> k) a -> + withKnownNat k $ \p@(Proxy :: Proxy k) -> + f p (unsafeCoerce a :: h (ElemAt k as)) + +hmap :: + forall h g as as'. + ( forall k. + ( KnownNat k + , Member (ElemAt k as) as + , Member (h (ElemAt k as)) (Map h as) + , Member (ElemAt k as') as' + , Member (g (ElemAt k as')) (Map g as') + ) => + Proxy k -> + h (ElemAt k as) -> + g (ElemAt k as') + ) -> + HList h as -> + HList g as' +hmap f (HL v) = + HL $ + flip V.imap v $ \(fromIntegral -> k) a -> + withKnownNat k $ \p@(Proxy :: Proxy k) -> + let ek = unsafeCoerce a :: h (ElemAt k as) + in unsafeCoerce $ f p ek + +hany :: + forall h as. + ( forall k. + ( KnownNat k + , Member (ElemAt k as) as + , Member (h (ElemAt k as)) (Map h as) + ) => + Proxy k -> + h (ElemAt k as) -> + Bool + ) -> + HList h as -> + Bool +hany f (HL v) = + V.any + ( \(fromIntegral -> k, a) -> + withKnownNat k $ \p@(Proxy :: Proxy k) -> + f p (unsafeCoerce a :: h (ElemAt k as)) + ) + $ V.indexed v + +hall :: + forall h as. + ( forall k. + ( KnownNat k + , Member (ElemAt k as) as + , Member (h (ElemAt k as)) (Map h as) + ) => + Proxy k -> + h (ElemAt k as) -> + Bool + ) -> + HList h as -> + Bool +hall f (HL v) = + V.all + ( \(fromIntegral -> k, a) -> + withKnownNat k $ \p@(Proxy :: Proxy k) -> + f p (unsafeCoerce a :: h (ElemAt k as)) + ) + $ V.indexed v + +instance + (KnownTyList as, All Show (Map h as)) => + Show (HList h as) + where + showsPrec _ HNil = showString "[]" + showsPrec _ vs = + showString "[" + . foldr1 + (\a b -> a . showString ", " . b) + ( htoList + ( \(x :: h x) -> + showsPrec 11 x \\ subDict @Show @(h x) @(Map h as) + ) + vs + ) + . showString "]" + +instance + ( KnownTyList as + , All Eq (Map h as) + , All Ord (Map h as) + ) => + Ord (HList h as) + where + compare = + fmap + ( hfoldMap $ + \(Proxy :: Proxy k) (Proxy :: Proxy x) -> + castWith (elemAtReplicate @(Length as) @k @Ordering) . runIdentity + ) + . hzipWith @Identity @(Replicate (Length as) Ordering) + ( \(Proxy :: (KnownNat k) => Proxy k) -> + fmap + (Identity . castWith (sym $ elemAtReplicate @(Length as) @k @Ordering)) + . compare + ) + +instance + (KnownTyList as, All Eq (Map h as)) => + Eq (HList h as) + where + hs == ls = + Mon.getAll + $ hfoldMap + ( \(Proxy :: Proxy k) (Proxy :: Proxy x) -> + Mon.All + . castWith (elemAtReplicate @(Length as) @k @Bool) + . runIdentity + ) + $ hzipWith @Identity @(Replicate (Length as) Bool) + ( \(Proxy :: Proxy k) + a + b -> + Identity $ + castWith (sym $ elemAtReplicate @(Length as) @k @Bool) $ + a == b + ) + hs + ls + + hs /= ls = + Mon.getAny + $ hfoldMap + (\(Proxy :: Proxy k) _ -> Mon.Any . castWith (elemAtReplicate @(Length as) @k @Bool) . runIdentity) + $ hzipWith @Identity @(Replicate (Length as) Bool) + ( \(Proxy :: Proxy k) + a + b -> + Identity $ + castWith (sym $ elemAtReplicate @(Length as) @k @Bool) $ + a /= b + ) + hs + ls + +hslice :: + forall ns f as pxy. + (KnownNatList ns) => + pxy ns -> + HList f as -> + HList (HList f) (Sliced ns as) +hslice _ (HL vec) = HL $ V.fromList $ go (natListVal $ Proxy @ns) vec + where + go [] _ = [] + go (n : ns) v = + let (ls, rs) = V.splitAt (fromIntegral n) v + in (unsafeCoerce (HL ls) :: Any) : go ns rs + +hix :: forall x xs h. (Member x xs) => Lens' (HList h xs) (h x) +hix = lens (hindex (Proxy @(Index x xs))) (flip $ hset (Proxy @(Index x xs))) + +hset :: + (KnownNat k) => + Proxy k -> + h (ElemAt k xs) -> + HList h xs -> + HList h xs +hset k x (HL vec) = + HL $ + V.modify + ( \mv -> + MV.unsafeWrite mv (fromIntegral $ natVal k) $ unsafeCoerce x + ) + vec + +hset' :: + (KnownNat k) => + Proxy k -> + h a -> + HList h xs -> + HList h (Take k xs ++ (a ': Drop (k + 1) xs)) +hset' k x (HL vec) = + HL $ + V.modify + ( \mv -> + MV.unsafeWrite mv (fromIntegral $ natVal k) $ unsafeCoerce x + ) + vec + +hmodify :: + (KnownNat k) => + Proxy k -> + (h (ElemAt k xs) -> h (ElemAt k xs)) -> + HList h xs -> + HList h xs +hmodify k f (HL vec) = + HL $ + V.modify + ( \mv -> + MV.unsafeModify mv (unsafeCoerce . f . unsafeCoerce) (fromIntegral $ natVal k) + ) + vec + +hmodify' :: + (KnownNat k) => + Proxy k -> + (h (ElemAt k xs) -> h a) -> + HList h xs -> + HList h (Take k xs ++ (a ': Drop (k + 1) xs)) +hmodify' k f (HL vec) = + HL $ + V.modify + ( \mv -> + MV.unsafeModify mv (unsafeCoerce . f . unsafeCoerce) (fromIntegral $ natVal k) + ) + vec + +hfoldr :: + forall h as b. + ( forall k x. + ( KnownNat k + , Member (h x) (Map h as) + , Member x as + , ElemAt k as ~ x + ) => + Proxy k -> + Proxy x -> + h x -> + b -> + b + ) -> + b -> + HList h as -> + b +{-# INLINE hfoldr #-} +hfoldr f = \z0 hl -> + appEndo (hfoldMap (\p px x -> Endo (f p px x)) hl) z0 + +hfoldl' :: + forall h as b. + ( forall k x. + ( KnownNat k + , Member (h x) (Map h as) + , Member x as + , ElemAt k as ~ x + ) => + Proxy k -> + Proxy x -> + b -> + h x -> + b + ) -> + b -> + HList h as -> + b +{-# INLINE hfoldl' #-} +hfoldl' f = flip $ hfoldr (\l n x k z -> k $! f l n z x) id + +hfoldMap :: + forall h as w. + (Monoid w) => + ( forall k x. + ( KnownNat k + , ElemAt k as ~ x + , Member (h x) (Map h as) + , Member x as + ) => + Proxy k -> + Proxy x -> + h x -> + w + ) -> + HList h as -> + w +hfoldMap f (HL v) = + flip foldMap (V.indexed v) $ \(fromIntegral -> k, a) -> + withKnownNat k $ \p@(Proxy :: Proxy k) -> + f p (Proxy :: Proxy (ElemAt k as)) (unsafeCoerce a) + +htraverse :: + forall g bs f h as. + (Applicative f) => + ( forall k. + ( KnownNat k + , Member (ElemAt k as) as + , Member (h (ElemAt k as)) (Map h as) + ) => + Proxy k -> + h (ElemAt k as) -> + f (g (ElemAt k bs)) + ) -> + HList h as -> + f (HList g bs) +htraverse f (HL v) = + HL + <$> flip + traverse + (V.indexed v) + ( \(fromIntegral -> k, a) -> + withKnownNat k $ \p@(Proxy :: Proxy k) -> + unsafeCoerce @_ @Any <$> f p (unsafeCoerce a) + ) + +htraverse_ :: + forall f h as. + (Applicative f) => + ( forall k. + ( KnownNat k + , Member (ElemAt k as) as + , Member (h (ElemAt k as)) (Map h as) + ) => + Proxy k -> + h (ElemAt k as) -> + f () + ) -> + HList h as -> + f () +htraverse_ f (HL v) = + flip + F.traverse_ + (V.indexed v) + ( \(fromIntegral -> k, a) -> + withKnownNat k $ \p@(Proxy :: Proxy k) -> + f p (unsafeCoerce a :: h (ElemAt k as)) + ) + +hunzip :: + forall h as bs. + HList h (ZipSame as bs) -> + (HList h as, HList h bs) +hunzip (HL v) = + let (l, r) = + V.unzip $ + V.imap + ( \k -> + withKnownNat (fromIntegral k) $ \(Proxy :: Proxy k) -> + (unsafeCoerce *** unsafeCoerce) + . unsafeCoerce @Any @(ElemAt k as, ElemAt k bs) + ) + v + in (HL l, HL r) + +hunzip' :: + forall h g as. + HList (Product h g) as -> + (HList h as, HList g as) +hunzip' (HL v) = + let (l, r) = + V.unzip $ + V.imap + ( \k -> + withKnownNat (fromIntegral k) $ \(Proxy :: Proxy k) -> + (\(Pair x y) -> (unsafeCoerce x, unsafeCoerce y)) + . unsafeCoerce @Any @(Product h g (ElemAt k as)) + ) + v + in (HL l, HL r) + +hunzipWith :: + forall h as g k. + (forall x. (Member x as, Member (h x) (Map h as)) => h x -> (g x, k x)) -> + HList h as -> + (HList g as, HList k as) +hunzipWith f (HL v) = + (HL *** HL) $ + V.unzip $ + V.imap + ( \(fromIntegral -> k) hx -> withKnownNat k $ \(Proxy :: Proxy n) -> + (unsafeCoerce *** unsafeCoerce) $ + f (unsafeCoerce @_ @(h (ElemAt n as)) hx) + ) + v + +hunzipWithM :: + forall h as g k m. + (Monad m) => + ( forall n. + ( KnownNat n + , Member (ElemAt n as) as + , Member (ElemAt n as) as + , Member (h (ElemAt n as)) (Map h as) + , Member (g (ElemAt n as)) (Map g as) + , Member (k (ElemAt n as)) (Map k as) + ) => + Proxy n -> + h (ElemAt n as) -> + m (g (ElemAt n as), k (ElemAt n as)) + ) -> + HList h as -> + m (HList g as, HList k as) +hunzipWithM f (HL v) = + (HL *** HL) . V.unzip + <$> V.imapM + ( \(fromIntegral -> k) hx -> withKnownNat k $ \p@(Proxy :: Proxy n) -> + (unsafeCoerce *** unsafeCoerce) + <$> f p (unsafeCoerce @_ @(h (ElemAt n as)) hx) + ) + v diff --git a/elgenerics-containers/src/Data/HList/HigherKinded/Builder.hs b/elgenerics-containers/src/Data/HList/HigherKinded/Builder.hs new file mode 100644 index 0000000..47b15b5 --- /dev/null +++ b/elgenerics-containers/src/Data/HList/HigherKinded/Builder.hs @@ -0,0 +1,43 @@ +{-# LANGUAGE DataKinds #-} +{-# LANGUAGE ExplicitNamespaces #-} +{-# LANGUAGE GADTs #-} + +module Data.HList.HigherKinded.Builder ( + Builder (), + empty, + (%:-), + (-:%), + (%++), + build, +) where + +import Data.Coerce (coerce) +import Data.HList.Internal (HList (..)) +import Data.Kind (Type) +import Data.TypeLevel.List (type (++)) +import GHC.Exts (Any) +import Unsafe.Coerce (unsafeCoerce) +import VectorBuilder.Builder qualified as VB +import VectorBuilder.Vector qualified as VB + +type Builder :: forall {k}. (k -> Type) -> [k] -> Type +newtype Builder h xs = Builder {runBuilder :: VB.Builder Any} + +infixr 5 %:-, %++ + +(%:-) :: h x -> Builder h xs -> Builder h (x ': xs) +hl %:- Builder anys = Builder $ VB.singleton (unsafeCoerce hl) <> anys + +infixl 5 -:% + +(-:%) :: Builder h xs -> h x -> Builder h (xs ++ '[x]) +Builder anys -:% hl = Builder $ anys <> VB.singleton (unsafeCoerce hl) + +(%++) :: Builder h xs -> Builder h ys -> Builder h (xs ++ ys) +(%++) = coerce $ (<>) @(VB.Builder Any) + +build :: Builder h xs -> HList h xs +build = HL . VB.build . runBuilder + +empty :: Builder h xs +empty = Builder mempty diff --git a/elgenerics-containers/src/Data/HList/Internal.hs b/elgenerics-containers/src/Data/HList/Internal.hs new file mode 100644 index 0000000..003c8e4 --- /dev/null +++ b/elgenerics-containers/src/Data/HList/Internal.hs @@ -0,0 +1,9 @@ +{-# LANGUAGE DataKinds #-} + +module Data.HList.Internal (HList (..)) where + +import Data.Kind +import Data.Vector (Vector) +import GHC.Exts + +newtype HList (h :: k -> Type) (as :: [k]) = HL (Vector Any) diff --git a/elgenerics-containers/src/Data/Product/Class.hs b/elgenerics-containers/src/Data/Product/Class.hs new file mode 100644 index 0000000..7d3ee3d --- /dev/null +++ b/elgenerics-containers/src/Data/Product/Class.hs @@ -0,0 +1,103 @@ +{-# LANGUAGE AllowAmbiguousTypes #-} +{-# LANGUAGE DataKinds #-} +{-# LANGUAGE DefaultSignatures #-} +{-# LANGUAGE GADTs #-} +{-# LANGUAGE LiberalTypeSynonyms #-} +{-# LANGUAGE RecordWildCards #-} +{-# LANGUAGE TypeFamilies #-} +{-# LANGUAGE UndecidableInstances #-} +{-# LANGUAGE UndecidableSuperClasses #-} + +module Data.Product.Class ( + HasFactor (..), + getFactor, + setFactor, + GHasFactor, + withHasFactor, + withIdFactor, + withHasFactorL, + factorLWith, + getFactorWith, + setFactorWith, +) where + +import Control.Lens (Lens', ReifiedLens (..), coerced, lens, set, view) +import Data.Proxy +import Data.TypeLevel.Maybe +import Data.TypeLevel.Path +import GHC.TypeLits +import Unsafe.Coerce + +getFactor' :: ProdPath c f -> f () -> c +getFactor' K (K1 a) = a +getFactor' (M p) (M1 a) = getFactor' p a +getFactor' (GoL p) (l :*: _) = getFactor' p l +getFactor' (GoR p) (_ :*: r) = getFactor' p r + +setFactor' :: ProdPath c f -> c -> f () -> f () +setFactor' K c (K1 _) = K1 c +setFactor' (M p) c (M1 f) = M1 $ setFactor' p c f +setFactor' (GoL p) c (l :*: r) = setFactor' p c l :*: r +setFactor' (GoR p) c (l :*: r) = l :*: setFactor' p c r + +getFactorWith :: (Generic a) => ProdPath c (Rep a) -> a -> c +getFactorWith p = getFactor' p . from + +setFactorWith :: (Generic a) => ProdPath c (Rep a) -> c -> a -> a +{-# INLINE setFactorWith #-} +setFactorWith p = \c -> to . setFactor' p c . from + +factorLWith :: forall c a. (Generic a) => ProdPath c (Rep a) -> Lens' a c +factorLWith path = + coerced . lens (getFactorWith path) (flip $ setFactorWith @a @c path) + +type FactorPath :: + forall c -> forall a -> ProdPath c (Rep a) +type family FactorPath c a :: ProdPath c (Rep a) where + FactorPath c a = + FromJust + ( 'Text "A type `" + ':<>: 'ShowType a + ':<>: 'Text "' doesn't have a field of type `" + ':<>: 'ShowType c + ':<>: 'Text "'" + ) + (PositionOf ProdOnly c a) + +class HasFactor c a where + factorL :: Lens' a c + default factorL :: (GHasFactor c a) => Lens' a c + factorL = factorLWith (pathVal $ Proxy @(FactorPath c a)) + +type GHasFactor c a = + (Generic a, KnownPath ProdOnly c (Rep a) (FactorPath c a)) + +-- instance {-# OVERLAPPABLE #-} +-- (Generic a, KnownPath ProdOnly c (Rep a) (FactorPath c a)) +-- => HasFactor c a + +getFactor :: forall c a. (HasFactor c a) => a -> c +getFactor = view factorL + +setFactor :: forall c a. (HasFactor c a) => c -> a -> a +setFactor = set factorL + +newtype WrapHF a b r = WrapHF ((HasFactor a b) => r) + +withHasFactor :: + forall a b r. + (a -> b) -> + (b -> a -> a) -> + ((HasFactor b a) => r) -> + r +withHasFactor f g = withHasFactorL (lens f $ flip g) +{-# INLINE withHasFactor #-} + +withHasFactorL :: forall b a r. Lens' a b -> ((HasFactor b a) => r) -> r +withHasFactorL l act = + unsafeCoerce (WrapHF @b @a @r act) (Lens l) +{-# INLINE withHasFactorL #-} + +withIdFactor :: forall a r. ((HasFactor a a) => r) -> r +withIdFactor act = unsafeCoerce (WrapHF @a @a @r act) (Lens @a @a @a @a id) +{-# INLINE withIdFactor #-} diff --git a/elgenerics-containers/src/Data/Record.hs b/elgenerics-containers/src/Data/Record.hs new file mode 100644 index 0000000..d2a8f65 --- /dev/null +++ b/elgenerics-containers/src/Data/Record.hs @@ -0,0 +1,185 @@ +{-# LANGUAGE AllowAmbiguousTypes #-} +{-# LANGUAGE DataKinds #-} +{-# LANGUAGE DefaultSignatures #-} +{-# LANGUAGE DerivingStrategies #-} +{-# LANGUAGE ExplicitNamespaces #-} +{-# LANGUAGE GADTs #-} +{-# LANGUAGE PatternSynonyms #-} +{-# LANGUAGE RecordWildCards #-} +{-# LANGUAGE TemplateHaskell #-} +{-# LANGUAGE TypeFamilies #-} +{-# LANGUAGE UndecidableInstances #-} +{-# OPTIONS_GHC -Wno-orphans #-} + +-- | Non-HKD like record, dependent only on the second field +module Data.Record ( + Record, + type (:::), + type (<:), + HasLabel, + EntryAt, + FieldAt, + Entries, + Extendible, + Field (..), + FieldLabel (..), + ShowableRecord, + Shown (..), + Labels, + (:=) (..), + extends, + EntryC, + LabelC, + emptyRec, + recField, + (&.), + (&+), + (&%~), + (&|~), + (&-), + traverseRec, + viewField, + viewField', + field, + IsRecord (..), + SortFields, + ToLabel, +) where + +import Control.Lens (Lens', coerced) +import Data.Coerce +import Data.Proxy +import Data.Record.HigherKinded ( + Entries, + EntryAt, + EntryC, + Extendible, + Field (..), + FieldAt, + FieldLabel (..), + HasLabel, + IsRecord (..), + LabelC, + Labels, + ShowableRecord, + Shown, + SortFields, + ToLabel, + field, + (:::), + (:=) (..), + type (<:), + ) +import Data.Record.HigherKinded qualified as HK +import Data.Tagged +import Data.TypeLevel.OrdMap (Delete, Lookup') +import Data.TypeLevel.OrdMap qualified as OM +import GHC.Records +import GHC.TypeLits + +type Record recs = HK.Record HK.STagged recs + +extends :: + forall l x xs. + (Extendible (l ::: x) xs) => + l := x -> + Record xs -> + Record ((l ::: x) <: xs) +extends = coerce $ HK.extends @l @HK.STagged @x @xs + +(&+) :: + (Extendible (l ::: x) xs) => + Record xs -> + l := x -> + Record ((l ::: x) <: xs) +(&+) = flip extends + +infixl 1 &+ + +emptyRec :: Record OM.Empty +emptyRec = HK.emptyRec + +(&.) :: + forall l xs. + (HasLabel l xs) => + Record xs -> + l := Lookup' l xs -> + Record xs +(&.) = coerce $ (HK.&.) @l @xs @HK.STagged + +infixl 1 &. + +viewField :: + forall l recs. + (HasLabel l recs) => + FieldLabel l -> + Record recs -> + OM.Lookup' l recs +viewField = const $ viewField' @l + +viewField' :: + forall l recs. + (HasLabel l recs) => + Record recs -> + OM.Lookup' l recs +viewField' = unTagged . HK.viewField' @l + +instance + {-# OVERLAPPING #-} + ( HasLabel (l :: Symbol) recs + , 'Just x ~ OM.Lookup l recs + ) => + HasField l (Record recs) x + where + getField = viewField (FieldLabel @_ @l) + +recField :: + forall xs l. + (HasLabel l xs) => + FieldLabel l -> + Lens' + (Record xs) + (Lookup' l xs) +recField l = + HK.recField l + . coerced + @(Tagged l (Lookup' l xs)) + @(Tagged l (Lookup' l xs)) +{-# INLINE recField #-} + +(&%~) :: + forall l xs a. + (HasLabel l xs) => + Record xs -> + l HK.:= (Lookup' l xs -> a) -> + Record ((l ::: a) <: xs) +(&%~) = coerce $ (HK.&%~) @l @xs @HK.STagged @a + +(&|~) :: + forall l xs a. + (HasLabel l xs) => + Record xs -> + l := a -> + Record ((l ::: a) <: xs) +(&|~) = coerce $ (HK.&|~) @l @xs @a @HK.STagged + +(&-) :: + forall l xs. + (HasLabel l xs) => + Record xs -> + FieldLabel l -> + Record (Delete l xs) +(&-) = coerce $ (HK.&-) @l @xs @HK.STagged + +traverseRec :: + forall f as. + (Applicative f) => + ( forall l. + (HasLabel l as) => + Proxy l -> + Lookup' l as -> + f (Lookup' l as) + ) -> + Record as -> + f (Record as) +traverseRec = \f -> HK.traverseRec (\p _ _ -> fmap Tagged . f p . unTagged) diff --git a/elgenerics-containers/src/Data/Record/Builder/HigherKinded.hs b/elgenerics-containers/src/Data/Record/Builder/HigherKinded.hs new file mode 100644 index 0000000..c5dda25 --- /dev/null +++ b/elgenerics-containers/src/Data/Record/Builder/HigherKinded.hs @@ -0,0 +1,132 @@ +{-# LANGUAGE DataKinds #-} +{-# LANGUAGE GADTs #-} +{-# LANGUAGE MagicHash #-} +{-# LANGUAGE RoleAnnotations #-} + +{- | Top-down style extensible record builder. + + The construction is top-down in a sense that + the resulting record fields are determined before the + actual construction (i.e. when the user calls 'empty'). + If the resulting fields are not determined a priori, use the bottom-up + builder provided in module "Data.Record.Builder.Highedrinded.BottomUp". +-} +module Data.Record.Builder.HigherKinded ( + RecordBuilder, + Building, + Building' (), + (&+), + (&+:), + singleton, + singleton', + build, + empty, +) where + +import Control.Monad.ST.Strict +import Data.HList.Internal qualified as HL +import Data.Record.HigherKinded qualified as Rec +import Data.Record.HigherKinded.Internal qualified as Rec +import Data.TypeLevel.OrdMap qualified as OM +import Data.Vector qualified as V +import Data.Vector.Mutable qualified as MV +import GHC.Exts (Any, proxy#) +import GHC.TypeNats +import Unsafe.Coerce + +{- | A Record builder that is ready for building. + + c.f. 'Building' and 'Building''. +-} +type RecordBuilder = Building' OM.Empty + +{- | A record buidler with all the fields uninitialised. + + c.f. 'empty'. +-} +type Building h xs = Building' xs h xs + +type role Building' nominal representational nominal + +-- | A generic record-builder type. + +-- @'Building'' remains h allFields@ is a builder for a record with type +-- @'Record' h allFields@ with uninitialised fields @remains@. +-- +-- Fields can be added with @('&+')@ and @('&+:')@, +-- and you can build a concrete record with 'build' if @remains@ is 'OM.Empty'. +-- +-- __N.B.__ If the resuliting fields are NOT determined a priori, +-- it is much faster and safer to use the bottom-up builder +-- provided in "Data.Record.Builder.HigherKinded.BottomUp". +newtype Building' (remains :: OM.OrdMap k v) h (allFields :: OM.OrdMap k v) + = RecordBuilder (forall s. MV.MVector s Any -> ST s ()) + +infixl 1 &+, &+: + +{- | /O(1)/ Adds field to a record builder. + + See also: @('&+:')@. +-} +(&+) :: + forall h fields l remain a. + (Rec.HasLabel l fields, Rec.HasLabel l remain, OM.Lookup' l fields ~ a) => + Building' remain h fields -> + l Rec.:= h l a -> + Building' (OM.Delete l remain) h fields +{-# INLINE (&+) #-} +(&+) = \b (_ Rec.:= hla) -> b &+: hla + +{- | /O(1)/ Adds field to a record builder. + + See also: @('&+')@. +-} +(&+:) :: + forall h fields l remain a. + (Rec.HasLabel l fields, Rec.HasLabel l remain, OM.Lookup' l fields ~ a) => + Building' remain h fields -> + h l a -> + Building' (OM.Delete l remain) h fields +{-# INLINE (&+:) #-} +(&+:) = \(RecordBuilder cur) (hla :: h l a) -> + let n = fromIntegral $ natVal' @(OM.Index l fields) proxy# + in RecordBuilder $ + \mv -> cur mv >> MV.unsafeWrite mv n (unsafeCoerce hla :: Any) + +-- | /O(1)/ Record-builder with all fields uninitialised. +empty :: forall h fields. Building h fields +empty = RecordBuilder $ const $ pure () + +-- | /O(1)/ Record-builder with a single field initialised. +singleton :: + forall l a h fields. + (Rec.HasLabel l fields, OM.Lookup' l fields ~ a) => + l Rec.:= h l a -> + Building' (OM.Delete l fields) h fields +{-# INLINE singleton #-} +singleton = \(_ Rec.:= hla) -> singleton' hla + +-- | /O(1)/ Record-builder with a single field initialised. +singleton' :: + forall l a h fields. + (Rec.HasLabel l fields, OM.Lookup' l fields ~ a) => + h l a -> + Building' (OM.Delete l fields) h fields +{-# INLINE singleton' #-} +singleton' = + let n = fromIntegral $ natVal' @(OM.Index l fields) proxy# + in \hla -> RecordBuilder $ \mv -> + MV.unsafeWrite mv n $ unsafeCoerce hla + +-- | /O(n)/ Turns fully-initialised builder into a concrete record. +build :: + forall h fields. + (KnownNat (OM.Size fields)) => + RecordBuilder h fields -> + Rec.Record h fields +build (RecordBuilder cmd) = Rec.Record $ + HL.HL $ + V.create $ do + mv <- MV.new $ fromIntegral $ natVal' @(OM.Size fields) proxy# + cmd mv + pure mv diff --git a/elgenerics-containers/src/Data/Record/Builder/HigherKinded/BottomUp.hs b/elgenerics-containers/src/Data/Record/Builder/HigherKinded/BottomUp.hs new file mode 100644 index 0000000..e51d322 --- /dev/null +++ b/elgenerics-containers/src/Data/Record/Builder/HigherKinded/BottomUp.hs @@ -0,0 +1,117 @@ +{-# LANGUAGE DataKinds #-} +{-# LANGUAGE ExplicitNamespaces #-} +{-# LANGUAGE GADTs #-} +{-# LANGUAGE MagicHash #-} +{-# LANGUAGE RoleAnnotations #-} + +{- | Bottom-up style extensible record builder. + + The construction is bottom-up in a sense that + the resulting record fields are determined when the + 'build' function is called; if the resulting fields + are determined before the construction, use a top-down + builder provided in module "Data.Record.Builder.Highedrinded". +-} +module Data.Record.Builder.HigherKinded.BottomUp ( + RecordBuilder, + build, + buildNoDupe, + empty, + (&+), + (&+:), + (&<>), +) where + +import Data.HList.Internal qualified as HL +import Data.Kind +import Data.Record.HigherKinded qualified as Rec +import Data.Record.HigherKinded.Internal qualified as Rec +import Data.TypeLevel.List (Length, type (++)) +import Data.TypeLevel.OrdMap qualified as OM +import Data.Vector qualified as V +import GHC.Exts (Any) +import Unsafe.Coerce +import VectorBuilder.Builder qualified as VB +import VectorBuilder.Vector qualified as VB + +-- | A generic bottom-up record-builder type. + +-- @'Building'' h allFields@ is a builder for a record with type +-- @'Record' h ('OM.FromList' allFields)@. +-- +-- Fields can be added with @('&+')@ and @('&+:')@, +-- and a concrete record can be built by 'build'. +-- +-- __N.B.__ If the resuliting fields are determined a priori, +-- it is much faster and safer to use the top-down builder +-- provided in "Data.Record.Builder.HigherKinded". +data RecordBuilder (h :: k -> v -> Type) (fields :: [OM.Field k v]) + = RecordBuilder (VB.Builder Any) + +{- | /O(n)/ Build a concrete record. + + See also: 'buildNoDupe'. +-} +build :: + forall h fields. + (OM.SortableLabels fields) => + RecordBuilder h fields -> + Rec.Record h (OM.FromList fields) +build (RecordBuilder vb) = + let vec0 = VB.build vb + perms = V.convert $ OM.sortPermutation @fields + in Rec.Record $ + HL.HL $ + V.unsafeBackpermute vec0 perms + +{- | /O(n)/ Build a concrete record, but checks there is no duplicated labels. + + See also: 'build'. +-} +buildNoDupe :: + forall h fields. + ( OM.SortableLabels fields + , OM.Size (OM.FromList fields) ~ Length fields + ) => + RecordBuilder h fields -> + Rec.Record h (OM.FromList fields) +buildNoDupe = build + +-- | /O(1)/ Record-builder with no fields. +empty :: RecordBuilder h '[] +empty = RecordBuilder VB.empty + +{- | /O(1)/ Adds field to a record builder. + + See also: @('&+:')@. +-} +(&+) :: + forall h fields l a. + RecordBuilder h fields -> + l Rec.:= h l a -> + RecordBuilder h ((l OM.::: a) ': fields) +{-# INLINE (&+) #-} +(&+) = \b (_ Rec.:= hla) -> b &+: hla + +{- | /O(1)/ Adds field to a record builder. + + See also: @('&+')@. +-} +(&+:) :: + forall h fields l a. + RecordBuilder h fields -> + h l a -> + RecordBuilder h ((l OM.::: a) ': fields) +{-# INLINE (&+:) #-} +(&+:) = \(RecordBuilder cur) (hla :: h l a) -> + RecordBuilder $ VB.singleton (unsafeCoerce hla :: Any) <> cur + +infixl 1 &+, &+: + +(&<>) :: + forall h fields fields'. + RecordBuilder h fields -> + RecordBuilder h fields' -> + RecordBuilder h (fields ++ fields') +(&<>) = \(RecordBuilder cur) (RecordBuilder rest) -> + RecordBuilder $ cur <> rest diff --git a/elgenerics-containers/src/Data/Record/HigherKinded.hs b/elgenerics-containers/src/Data/Record/HigherKinded.hs new file mode 100644 index 0000000..62ab9af --- /dev/null +++ b/elgenerics-containers/src/Data/Record/HigherKinded.hs @@ -0,0 +1,2006 @@ +{-# LANGUAGE AllowAmbiguousTypes #-} +{-# LANGUAGE CPP #-} +{-# LANGUAGE DataKinds #-} +{-# LANGUAGE DefaultSignatures #-} +{-# LANGUAGE DerivingStrategies #-} +{-# LANGUAGE DerivingVia #-} +{-# LANGUAGE GADTs #-} +{-# LANGUAGE LambdaCase #-} +{-# LANGUAGE MagicHash #-} +{-# LANGUAGE OverloadedLabels #-} +{-# LANGUAGE PatternSynonyms #-} +{-# LANGUAGE QuantifiedConstraints #-} +{-# LANGUAGE TemplateHaskell #-} +{-# LANGUAGE TypeFamilies #-} +{-# LANGUAGE UndecidableInstances #-} +{-# LANGUAGE UndecidableSuperClasses #-} +{-# OPTIONS_GHC -Wno-orphans -Wno-unused-top-binds -dcore-lint #-} +{-# OPTIONS_GHC -fplugin Data.TypeLevel.List.Solver #-} + +module Data.Record.HigherKinded + ( Record (MkRecord), + type (:::), + WithMembership(..), + Uncurried (..), + OnLabel (..), + OnLabel', + OnEntry (..), + OnEntry', + STagged, + SConst, + getSConst, + IsSubRecordOf, + HasRecField, + deferHasRecField, + type (⊑), + LabelName, + Entries, + Extendible, + Modifiable, + Field (..), + FieldLabel (..), + EntryAt, + FieldAt, + HasLabel, + Labels, + Singleton, + type (<:), + (:=) (..), + extends, + Recordable, + HRecordable, + hfieldL', + RecordRep, + AllOM, + FieldC, + EntryC, + LabelC, + OverC, + castRecord, + singletonRec, + singletonRec', + emptyRec, + recField, + (&.), + (&+), + (&%~), + (&|~), + (&-), + traverseRec, + traverseRecC, + traverseRec_, + traverseRecC_, + sequenceRec, + foldMapRec, + foldMapRecC, + foldrRec, + foldrMRec, + foldlRec', + viewField, + viewField', + recFieldTraversal, + projField, + CouldHaveField, + CmpLabel, + Entry, + Label, + Entry', + Label', + SortFields, + ToLabel, + sToLabel, + Shown (..), + unzipWithM, + unzipWith, + mapRecSame, + mapMRecSame, + mergeRec, + Mergeable, + alignRec, + alignRecWith, + alignRecWithM, + unalignRec, + collectRec, + These(..), + TheseF(..), + TheseC, + zipWithM, + zipWith, + zipWithM3, + zipWith3, + unzip, -- Merge, + ShowableRecord, + EqRecord, + OrdRecord, + GenericRecord, + fieldToLabelMembership, + entrySortIdentFields, + labelSortIdentFields, + field, + IsRecord (..), + GIsHRecord (), + IsHRecord (..), + fromHRecord', + -- SerialRec, + -- SerialiseWith, + -- resolveGenericRecord, + projToRecord, + withLabelsMember, + withKnownLabels, + generateRec, + generateRecM, + generateRecA, + elimFieldCons, + fields, + + -- * フィールドがダミーの場合 + ConstField, + ConstFields, + ConstField1, + ConstFields1, + elimConstField, + + -- * 要素とフィールドが一致している場合 + IdentField, + IdentFields, + memberIdent, + elimMemberIdent, + identFieldRefl, + + -- * Re-exports + FromList, + FromAscList, + ) +where + +import Control.Arrow +import Control.Category.Monoid +import Control.DeepSeq +import qualified Control.Foldl as L +import Control.Lens + ( Iso', + Lens', + Traversal', + coerced, + iso, + ix, + (%~), + (&), + (.~), + (<&>), + ) +import Data.Bifunctor.Product +import Data.Constraint (Dict (..)) +import Data.Constraint.Deferrable +import Data.Constraint.Operators +import Data.DList (DList) +import qualified Data.DList as DL +import Data.Functor.Const +import Data.Functor.Identity +import qualified Data.Functor.Product as F +import Data.HList.HigherKinded hiding (generate, generateM) +import qualified Data.HList.HigherKinded as HL +import Data.HList.Internal +import Data.Kind +import Data.Maybe +import Data.Membership hiding (natVal) +import Data.Monoid (Endo (..)) +import qualified Data.Monoid as Mon +import Data.Proxy +import Data.Record.HigherKinded.Internal +import Data.Tagged +import Data.Type.Equality +import Data.TypeLevel.BinTree (BinTree, MkBin, Stop, Val) +import qualified Data.TypeLevel.BinTree as BinTree +import Data.TypeLevel.Function +import Data.TypeLevel.Known +import Data.TypeLevel.List hiding (natVal) +import qualified Data.TypeLevel.List as L +import Data.TypeLevel.Ord hiding (Merge) +import Data.TypeLevel.OrdMap hiding (Member) +import qualified Data.TypeLevel.OrdMap as OrdMap +import Data.TypeLevel.OrdMap.Internal +import Data.TypeLevel.Typeable +import qualified Data.Vector as V +import qualified Data.Vector.Unboxed as U +import Data.Vector.Unboxed.Deriving +import GHC.Exts +import GHC.Generics +import GHC.OverloadedLabels +import GHC.Records +import GHC.TypeLits as TL +import Type.Reflection +import Unsafe.Coerce ( unsafeCoerce ) +import qualified VectorBuilder.Builder as VB +import qualified VectorBuilder.Vector as VB +import Prelude hiding (zipWith3, unzip, zipWith) +import qualified Prelude as P hiding (zipWith3) +import Data.These ( These(..) ) +import qualified Data.Map.Strict as M +import Data.Align (align,Unalign (unalign)) +import Data.Distributive ( Distributive(collect) ) + +class c (h k v) => OverC h c k v + +instance c (h k v) => OverC h c k v + +instance Deferrable (c (h k v)) => Deferrable (OverC h c k v) where + deferEither _ = \act -> deferEither_ @(c (h k v)) act + {-# INLINE deferEither #-} + +infix 4 := + +data IdentField :: k ~> Field k k + +type instance Apply IdentField ty = ty ::: ty + +type IdentFields xs = MapApply IdentField xs + +-- | 曖昧性除去のため、依存しない値部分のカインドを引数に取る 'OnLabel' のシノニム。 +type OnLabel' v = (OnLabel :: (k -> Type) -> k -> v -> Type) + +-- | 曖昧性除去のため、依存しないラベル部分のカインドを引数に取る 'OnEntry' のシノニム。 +type OnEntry' k = (OnEntry :: (v -> Type) -> k -> v -> Type) + +instance Deferrable (c k v) => Deferrable (FieldC c (k ::: v)) where + deferEither _ = \act -> deferEither_ @(c k v) act + +class + ( LookupWithIndex l ys ~ 'Just '(x, OrdMap.Index l ys) + , HasLabel l ys + ) => + HasRecField (ys :: OrdMap k v) l x + +instance + ( LookupWithIndex l ys ~ 'Just '(x, OrdMap.Index l ys) + , HasLabel l ys + ) => + HasRecField (ys :: OrdMap k v) l x + +instance + ( Known dic + , Known (l :: key) + , Known (x :: val) + , ShowSing key + , ShowSing val + , SOrd key + , STestEquality val + ) => + Deferrable (HasRecField dic l x) + where + deferEither _ = + deferHasRecField (sKnownVal' @dic) (sKnownVal' @l) (sKnownVal' @x) + {-# INLINE deferEither #-} + +deferHasRecField :: + forall r key val dic l x. + ( Known dic + , Known (l :: key) + , Known (x :: val) + , ShowSing key + , ShowSing val + , SOrd key + , STestEquality val + ) => + SOrdMap dic -> + Sing l -> + Sing x -> + (HasRecField dic l x => r) -> + Either String r +{-# INLINE deferHasRecField #-} +deferHasRecField (dic :: SOrdMap dic) (l :: Sing l) (x :: Sing x) r = + case sLookupWithIndex l dic of + SNothing -> + Left $ + "The key `" ++ show (sKnownVal' @l) + ++ "' is absent in the given dictionary: " + ++ show (sKnownVal' @dic) + SJust (SPair sx idx) + | Equal <- sTestEquality sx x -> + withKnownNat' idx $ Right r + | otherwise -> + Left $ + "The key `" ++ show (sKnownVal' @l) + ++ "' is present, but associated with different value; in dictionary: " + ++ show (sKnownVal' @dic) + +class + ( AllOM (HasRecField ys) xs + ) => + IsSubRecordOf xs ys + +instance + ( AllOM (HasRecField ys) xs + ) => + IsSubRecordOf xs ys + +instance + ( Known (xs :: OrdMap k v) + , ShowSing k + , ShowSing v + , Known ys + , SOrd k + , ShowSing k + , ShowSing v + , STestEquality v + ) => + Deferrable (IsSubRecordOf xs ys) + where + deferEither _ f = go (sKnownVal' @xs) <&> \Dict -> f + where + ys = sKnownVal' @ys + go :: + SOrdMap (zs :: OrdMap k v) -> + Either String (Dict (IsSubRecordOf zs ys)) + go SLeaf = Right Dict + go (SBranch c n rk l (k :: Sing l) (v :: Sing x) r) = + withKnown' c $ + withKnownNat' n $ + withKnown' rk $ + withKnown' k $ + withKnown' v $ do + Dict <- deferHasRecField @(Dict (HasRecField ys l x)) ys k v Dict + Dict <- go l + Dict <- go r + pure Dict + +type xs ⊑ ys = IsSubRecordOf xs ys + +memberIdent :: + forall p ps. + Member p ps => + Membership (p ::: p) (MapApply IdentField ps) +memberIdent = unsafeCoerce $ membership @p @ps + +elimMemberIdent :: + forall p ps. + Member (p ::: p) (MapApply IdentField ps) => + Membership p ps +elimMemberIdent = unsafeCoerce $ membership @(p ::: p) @(MapApply IdentField ps) + +elemAtIdent :: + ElemAt k (MapApply IdentField ps) + :~: (ElemAt k ps ::: ElemAt k ps) +elemAtIdent = unsafeCoerce $ Refl @() + +identFieldRefl :: + Member (l ::: x) (MapApply IdentField ps) => + l :~: x +identFieldRefl = unsafeCoerce $ Refl @() + +unRecord :: Record h recs -> HList (Uncurried h) (ToList recs) +unRecord (Record l) = l + +type LabelName :: + forall (k :: Type). k -> Symbol +type family LabelName (l :: k) :: Symbol where + LabelName (l :: Symbol) = l + LabelName l = ShowTypeRep (TypeRepOf l) + +type family TyConName (f :: k -> Type) :: Symbol where + TyConName (D1 ( 'MetaData l _ _ 'False) _) = l + +type ToSel (h :: label -> key -> Type) (l :: label) (k :: key) = + S1 + ( 'MetaSel + ( 'Just (LabelName l)) + 'NoSourceUnpackedness + 'NoSourceStrictness + 'DecidedLazy + ) + (Rec0 (h l k)) + +type RecordRep h xs = + D1 + ( 'MetaData "Record" "Data.Record.HigherKinded" "elgenerics" 'False) + ( C1 + ( 'MetaCons "Record" 'PrefixI 'True) + (ToProds h xs) + ) + +newtype Shown (f :: k -> v -> Type) a b = Shown {_runShown :: f a b} + +deriving newtype instance + {-# OVERLAPPABLE #-} + Show (f a b) => + Show (Shown f a b) + +instance {-# OVERLAPPING #-} Show a => Show (Shown Const a b) where + showsPrec d = coerce $ showsPrec @a d + +instance {-# OVERLAPPING #-} Show b => Show (Shown Tagged a b) where + showsPrec d = coerce $ showsPrec @b d + +class Typeable a => ToLabel a where + typeLabel :: TypeRep a -> ShowS + +sToLabel :: forall l. ToLabel l => String +sToLabel = typeLabel (typeRep @l) "" + +instance {-# OVERLAPPABLE #-} Typeable a => ToLabel a where + typeLabel = shows + +instance {-# OVERLAPPING #-} KnownSymbol s => ToLabel s where + typeLabel = showString . symbolVal + +tyLabels :: + forall as pxy. + (AllOM (LabelC ToLabel) as) => + pxy as -> + [ShowS] +tyLabels _ = + DL.toList $ + foldMapOrdMapC @(LabelC ToLabel) @as $ + \(Proxy :: Proxy l) _ _ -> + DL.singleton $ + typeLabel (typeRep @l) + +type ShowableRecord h (xs :: OrdMap k v) = + ( AllOM (LabelC ToLabel) xs + , AllOM (OverC (Shown h) Show) xs + ) + +instance + ( AllOM (OverC h NFData) xs + ) => + NFData (Record h xs) + where + rnf = + foldlRec' + (\_ _ _ () b -> rnf b `seq` ()) + () + {-# INLINE rnf #-} + +instance + (ShowableRecord h (xs :: OrdMap key val)) => + Show (Record h xs) + where + showsPrec _ (Record HNil) = showString "Record {}" + showsPrec d r = + showParen (d > 10) $ + let labs = tyLabels $ Proxy @xs + vals = + DL.toList $ + foldMapRecC @(OverC (Shown h) Show) + ( \_ _ _ hkv -> + DL.singleton $ shows $ Shown hkv + ) + r + in showString "Record {" + . foldr1 + (\a b -> a . showString ", " . b) + ( P.zipWith + (\l v -> l . showString " = " . v) + labs + vals + ) + . showChar '}' + +type GenericRecord h xs = GRec (RecordRep h xs) + +instance + (GenericRecord h xs) => + Generic (Record h xs) + where + type Rep (Record h xs) = RecordRep h xs + to = Record . HL . V.fromList . toList . gTo + from (Record (HL vec)) = gFrom vec + +class GRec f where + gTo :: f x -> DList Any + gFrom' :: V.Vector Any -> (f x, V.Vector Any) + +gFrom :: GRec f => V.Vector Any -> f x +{-# INLINE gFrom #-} +gFrom = fst . gFrom' + +instance + {-# OVERLAPPING #-} + (Generic (UnwrapNewtype f), GRec (Rep (UnwrapNewtype f))) => + GRec (D1 ( 'MetaData a b c 'True) f) + where + gTo = + gTo . from . unsafeCoerce @_ @(UnwrapNewtype f) + gFrom' = + first (unsafeCoerce @(UnwrapNewtype f) . to) . gFrom' @(Rep (UnwrapNewtype f)) + +instance GRec U1 where + gTo = const $ DL.empty + gFrom' = (U1,) + +instance {-# OVERLAPPABLE #-} GRec f => GRec (M1 i c f) where + gTo = gTo . unM1 + gFrom' = first M1 . gFrom' + +instance (GRec f, GRec g) => GRec (f :*: g) where + gTo (l :*: g) = gTo l <> gTo g + gFrom' vec = + let (lh, leftover) = gFrom' vec + (rh, lf') = gFrom' leftover + in (lh :*: rh, lf') + +instance {-# OVERLAPPING #-} GRec (K1 i c) where + gTo (K1 i) = DL.singleton $ unsafeCoerce i + gFrom' = + (K1 . unsafeCoerce . V.unsafeHead) + &&& V.unsafeTail + +type family ToProds h xs :: Type -> Type where + ToProds _ 'Leaf = U1 + ToProds h (Branch _ _ _ Leaf k v Leaf) = ToSel h k v + ToProds h (Branch _ _ _ Leaf k v r) = ToSel h k v :*: ToProds h r + ToProds h (Branch _ _ _ l k v Leaf) = ToProds h l :*: ToSel h k v + ToProds h (Branch _ _ _ l k v r) = + ToProds h l + :*: ToSel h k v + :*: ToProds h r + +data (:=) l b = FieldLabel l := b + deriving (Functor) + +deriving instance (KnownSymbol l, Show b) => Show (l := b) + +deriving instance (KnownSymbol l, Eq b) => Eq (l := b) + +data FieldLabel (l :: label) = FieldLabel + deriving (Eq, Ord) + +instance KnownSymbol l => Show (FieldLabel l) where + showsPrec d = showsPrec d . symbolVal + +-- N.B. 以下の ~~ は heterogeneous equality である。 +-- つまり、a priori には カインドが異なるかもしれない @l@ と @l'@ が与えられた +-- 時に、それらが同種のカインドに属し、なおかつ値として等しいことを要求している。 +-- これを通常の等値性 @l ~ l'@ で置き換えてしまうと、@l@ が @'Symbol'@ の +-- 場合のインスタンスしか生成されず、たとえば @empRec &+ #foo := 12@ とやっても、 +-- @:=@ 左辺の @#foo :: FieldLabel l'@ における @l'@ のカインドが一意に決まらず、 +-- インスタンス解決に失敗する。ここでは @~~@ を用いることで、@l'@ が Symbol のとき、 +-- その時に限り @FieldLabel l'@ が @IsLabel@ のインスタンスになるように制限している。 +instance (KnownSymbol l, l ~~ l') => IsLabel l (FieldLabel l') where + fromLabel = FieldLabel + +emptyRec :: + Record + (h :: k -> v -> Type) + (OrdMap.Empty :: OrdMap k v) +emptyRec = Record HNil + +singletonRec :: + forall h l a. h l a -> Record h (Singleton l a) +singletonRec = Record . HL . V.singleton . unsafeCoerce @(h l a) @Any + +singletonRec' :: + l := h l a -> + Record h (Singleton l a) +singletonRec' ((:=) _ r) = singletonRec r + +infixr 9 <: + +type (<:) x xs = Insert (Label x) (Entry x) xs + +type InsertedIndex x xs = OrdMap.Index (Label x) (x <: xs) + +type Extendible l xs = + ( Mergeable xs (Singleton (Label l) (Entry l)) + , KnownNat (InsertedIndex l xs) + ) + +extends :: + forall l h x xs. + (Extendible (l ::: x) xs) => + l := h l x -> + Record h xs -> + Record h ((l ::: x) <: xs) +extends (_ := x) (Record hl) = + let (HL lh, HL rh) = hsplitAt (Proxy @(InsertedIndex (l ::: x) xs)) hl + in Record $ HL $ lh <> (unsafeCoerce (Uncurried @_ @_ @h @(l ::: x) x) `V.cons` rh) + +(&+) :: + Extendible (l ::: x) xs => + Record h xs -> + l := h l x -> + Record h ((l ::: x) <: xs) +(&+) = flip extends + +infixl 1 &+ + +(&.) :: + forall l xs h. + (HasLabel l xs) => + Record h xs -> + l := h l (Lookup' l xs) -> + Record h xs +Record hl &. (_ := hx) = + Record $ + hset + (Proxy @(OrdMap.Index l xs)) + (unsafeCoerce $ Uncurried @_ @_ @h @(l ::: Lookup' l xs) hx) + hl + +infixl 1 &. + +type Modifiable l x recs = + (HasLabel l recs) + +(&%~) :: + forall l xs h a. + (Modifiable l a xs) => + Record h xs -> + l := (h l (Lookup' l xs) -> h l a) -> + Record h ((l ::: a) <: xs) +Record (HL hl) &%~ (_ := f) = + Record $ + HL $ + hl & ix (fromIntegral $ natVal $ Proxy @(OrdMap.Index l xs)) + %~ unsafeCoerce @_ @Any + . Uncurried @_ @_ @h @(l ::: a) + . f + . curried + . unsafeCoerce @Any @(Uncurried h (l ::: Lookup' l xs)) + +infixl 1 &%~ + +(&|~) :: + forall l xs a h. + (HasLabel l xs) => + Record h xs -> + l := h l a -> + Record h ((l ::: a) <: xs) +Record (HL hl) &|~ (_ := ha) = + Record $ + HL $ + hl & ix (fromIntegral $ natVal $ Proxy @(OrdMap.Index l xs)) + .~ unsafeCoerce @_ @Any (Uncurried @_ @_ @h @(l ::: a) ha) + +infixl 1 &|~ + +(&-) :: + forall l xs h. + HasLabel l xs => + Record h xs -> + FieldLabel l -> + Record h (Delete l xs) +Record (HL vec) &- _ = + let n = (fromIntegral $ TL.natVal $ Proxy @(OrdMap.Index l xs)) + (lh, rh) = V.splitAt n vec + in Record $ HL $ lh <> V.unsafeTail rh + +infixl 1 &- + +type EqRecord h as = (AllOM (OverC h Eq) as) + +instance (EqRecord h as) => Eq (Record h as) where + (==) = + fmap + ( Mon.getAll + . foldMapRec (const $ const $ const $ Mon.All . getConst . runOnEntry) + ) + . zipWith @h @h @as @(OnEntry (Const Bool)) + (const $ const $ const $ fmap (OnEntry . Const) . (==)) + {-# INLINE (==) #-} + + (/=) = + fmap + ( Mon.getAny + . foldMapRec (const $ const $ const $ Mon.Any . getConst . runOnEntry) + ) + . zipWith @h @h @as @(OnEntry (Const Bool)) + (const $ const $ const $ fmap (OnEntry . Const) . (/=)) + {-# INLINE (/=) #-} + +type OrdRecord h as = (AllOM (OverC h Ord) as, AllOM (OverC h Eq) as) + +instance (OrdRecord h as) => Ord (Record h as) where + compare = + fmap + ( foldMapRec (const $ const $ const $ getConst . runOnEntry) + ) + . zipWith @h @h @as @(OnEntry (Const Ordering)) + (const $ const $ const $ fmap (OnEntry . Const) . compare) + {-# INLINE compare #-} + +type CmpLabel = Comparing2 Compare2 Label' + +type SortFields (xs :: [Field k v]) = SortBy Compare2 xs + +instance + {-# INCOHERENT #-} + (HasLabel l recs, 'Just x ~ Lookup l recs) => + HasField + l + (Record h (recs :: OrdMap Symbol k)) + (h l x) + where + getField = viewField (field @l) + +viewField :: + forall l recs h. + (HasLabel l recs) => + FieldLabel l -> + Record h recs -> + h l (Lookup' l recs) +viewField = const $ viewField' @l + +elimLabelToList :: + forall l recs. + ElemAt (OrdMap.Index l recs) (ToList recs) + :~: (l ::: Lookup' l recs) +elimLabelToList = unsafeCoerce $ Refl @() + +viewField' :: + forall l recs h. + (HasLabel l recs) => + Record h recs -> + h l (Lookup' l recs) +viewField' (Record hl) = + gcastWith (elimLabelToList @l @recs) $ + curried $ hindex (Proxy @(OrdMap.Index l recs)) hl + +recField :: + forall h xs l. + (HasLabel l xs) => + FieldLabel l -> + Lens' + (Record h xs) + (h l (Lookup' l xs)) +{-# INLINE recField #-} +recField _ = + let n = fromIntegral $ TL.natVal' @(OrdMap.Index l xs) proxy# + in coerced @(Record h xs) @(Record h xs) @(V.Vector Any) @(V.Vector Any) + . ix' n + . iso unsafeCoerce unsafeCoerce + +ix' :: Int -> Lens' (V.Vector a) a +{-# INLINE ix' #-} +ix' n = \f v -> f (V.unsafeIndex v n) <&> \a -> V.unsafeUpd v [(n, a)] + +{- RULES: GHC 8.8 になったら次のように書けるのにね…… +"recField/mono" forall k h xs l. forall. + recField @h @xs @l @(EntryAt h xs) = recField' + # -} + +field :: forall l. FieldLabel l +field = FieldLabel + +memberInsert :: + forall l xs. + (HasLabel l xs) => + xs :~: ((l ::: Lookup' l xs) <: xs) +memberInsert = unsafeCoerce $ Refl @() + +type family UnwrapNewtype f where + UnwrapNewtype (M1 i c f) = UnwrapNewtype f + UnwrapNewtype (Rec0 a) = a + +type Recordable a = + ( Generic a + , GRec (Rep a) + , KnownTyList (GFields (Rep a)) + ) + +type HRecordable h a = + ( Generic a + , GRec (Rep a) + , SortableLabels (GHFields h (Rep a)) + , KnownTyList (GHFields h (Rep a)) + ) + +type GFields f = GHFields (Tagged :: Symbol -> Type -> Type) f + +type family GHFields (h :: l -> k -> Type) f :: [Field l k] where + GHFields (h :: l -> k -> Type) f = BinTree.ToList (GHFieldsAux k l h f) + +#if __GLASGOW_HASKELL__ >= 810 +type GHFieldsAux :: + forall k -> forall l -> + (l -> k -> Type) -> + (Type -> Type) -> + BinTree (Field l k) +#endif +type family GHFieldsAux k l h f :: BinTree (Field l k) where + GHFieldsAux Type Symbol (Tagged :: Symbol -> Type -> Type) (S1 ( 'MetaSel ( 'Just l) _ _ _) (Rec0 a)) = + Val (l ::: a) + GHFieldsAux () Symbol (OnLabel h) (S1 ( 'MetaSel ( 'Just l) _ _ _) (Rec0 (h l))) = + Val (l ::: '()) + GHFieldsAux k Symbol (OnLabel f) (S1 ( 'MetaSel ( 'Just l) _ _ _) (Rec0 (g l))) = + ValIfEqual f g l (Any :: k) + GHFieldsAux k Symbol (OnEntry g) (S1 ( 'MetaSel ( 'Just l) _ _ _) (Rec0 (f a))) = + ValIfEqual f g l a + GHFieldsAux _ Symbol h (S1 ( 'MetaSel ( 'Just l) _ _ _) (Rec0 (h l a))) = + Val (l ::: a) + GHFieldsAux _ Symbol h (S1 ( 'MetaSel ( 'Just l) _ _ _) (Rec0 b)) = + TypeError ( 'Text "Field " ':<>: 'ShowType l ':<>: 'Text " doesn't match the prefix functor " ':<>: 'ShowType h) + GHFieldsAux Type Type h (K1 i (h a a)) = Val (a ::: a) + GHFieldsAux k l h (D1 ( 'MetaData _ _ _ 'True) f) = + BinTree.FromList (ToList (HFields h (UnwrapNewtype f))) + GHFieldsAux k l h (D1 ( 'MetaData _ _ _ 'False) f) = + BinTree.FromList (GHFields h f) + GHFieldsAux k l h (M1 i c f) = GHFieldsAux k l h f + GHFieldsAux k l h (f :*: g) = + MkBin (GHFieldsAux k l h f) (GHFieldsAux k l h g) + GHFieldsAux k l h U1 = Stop + +type family ValIfEqual f g l a where + ValIfEqual f f l a = Val (l ::: a) + ValIfEqual f g l a = + TypeError ( 'Text "Field " ':<>: 'ShowType l ':<>: 'Text " doesn't match the prefix functor " ':<>: 'ShowType f) + +type family LabelOf a :: Type + +type family TrySort f as where + TrySort (D1 ( 'MetaData _ _ _ 'True) _) as = as + TrySort (D1 ( 'MetaData _ _ _ 'False) _) as = SortFields as + TrySort (M1 i c f) as = TrySort f as + +castRecord :: + (Equivalent recs recs') => + Record h recs -> + Record h recs' +castRecord = coerce + +class + ( Generic a + , GRec (Rep a) + , KnownTyList (GHFields h (Rep a)) + , SortableLabels (GHFields h (Rep a)) + ) => + GIsHRecord (h :: l -> k -> Type) a + where + unsafePerms :: Proxy# a -> V.Vector Int + unsafePerms _ = + V.convert $ sortPermutation @(GHFields h (Rep a)) + +instance + ( Generic a + , GRec (Rep a) + , KnownTyList (GHFields h (Rep a)) + , SortableLabels (GHFields h (Rep a)) + ) => + GIsHRecord h a + +-- | A variant of 'fromHRecord' with record representation fixed. +fromHRecord' :: + forall h a. + IsHRecord h a => + Record h (HFields h a) -> + a +fromHRecord' = fromHRecord + + +class IsHRecord h a where + type HFields h a :: (OrdMap l k) + type HFields h a = FromList (GHFields h (Rep a)) + + toHRecord :: a -> Record h (HFields h a) + default toHRecord :: + (GIsHRecord h a) => + a -> + Record h (HFields h a) + toHRecord a = + let perms = unsafePerms @_ @_ @h (proxy# :: Proxy# a) + in Record $ HL $ V.unsafeBackpermute (L.fold L.vector $ gTo $ from a) perms + fromHRecord :: + Equivalent recs (HFields h a) => + Record h recs -> + a + default fromHRecord :: + ( GIsHRecord h a + , Equivalent recs (HFields h a) + ) => + Record h recs -> + a + fromHRecord (Record (HL vec)) = + let perms = unsafePerms @_ @_ @h (proxy# :: Proxy# a) + in to $ gFrom $ V.update_ vec perms vec + hrecordL :: + Iso' a (Record h (HFields h a)) + hrecordL = iso toHRecord fromHRecord + + hfieldL :: + forall lab. + (HasLabel lab (HFields h a)) => + FieldLabel lab -> + Lens' + a + (h lab (Lookup' lab (HFields h a))) + hfieldL l = + hrecordL @h + . gcastWith + (memberInsert @lab @(HFields h a)) + (recField l) + +hfieldL' :: + forall lab h a. + (IsHRecord h a, HasLabel lab (HFields h a)) => + Lens' + a + (h lab (Lookup' lab (HFields h a))) +hfieldL' = hfieldL (field @lab) + +type instance LabelOf (Record h (as :: (OrdMap l _))) = l + +instance IsHRecord (h :: l -> k -> Type) (Record h (as :: (OrdMap l k))) where + type HFields h (Record h as) = as + toHRecord = id + fromHRecord = castRecord + +type STagged = (Tagged :: Symbol -> Type -> Type) + +class IsRecord (a :: Type) where + type Fields a :: (OrdMap Symbol Type) + type Fields a = FromList (GFields (Rep a)) + toRecord :: + a -> Record STagged (Fields a) + default toRecord :: + ( GIsHRecord STagged a + ) => + a -> + Record STagged (Fields a) + toRecord a = + let perms = unsafePerms @_ @_ @STagged (proxy# :: Proxy# a) + in Record $ + HL $ + V.unsafeBackpermute + (L.fold L.vector $ gTo $ from a) + perms + + fromRecord :: + (Equivalent recs (Fields a)) => + Record STagged recs -> + a + default fromRecord :: + (Equivalent recs (Fields a), GIsHRecord STagged a) => + Record STagged recs -> + a + fromRecord (Record (HL vec)) = + let perms = unsafePerms @_ @_ @STagged (proxy# :: Proxy# a) + in to $ gFrom $ V.update_ vec perms vec + recordL :: + Iso' a (Record STagged (Fields a)) + recordL = iso toRecord fromRecord + fieldL :: + forall l. + (KnownSymbol l, HasLabel l (Fields a)) => + FieldLabel l -> + Lens' a (Lookup' l (Fields a)) + fieldL l = + recordL + . gcastWith + (memberInsert @l @(Fields a)) + ( recField + @(Tagged :: Symbol -> Type -> Type) + l + ) + . iso (unTagged @l) (Tagged @l) + +instance IsRecord (Record STagged (a :: (OrdMap Symbol Type))) where + type Fields (Record STagged a) = a + toRecord = id + fromRecord = castRecord + recordL = id + fieldL l@(FieldLabel :: FieldLabel l) = + gcastWith (memberInsert @l @a) (recField l) + . iso (unTagged @l) (Tagged @l) + +projToRecord :: + forall recs h a. + ( IsHRecord h a + , recs ⊑ HFields h a + ) => + a -> + Record h recs +projToRecord a = + let perms = VB.build $ + foldMapOrdMapC @(HasRecField (HFields h a)) @recs $ + \(_ :: Proxy k) (_ :: Proxy v) (_ :: Proxy n) -> + VB.singleton $ + fromIntegral $ + TL.natVal' @(OrdMap.Index k (HFields h a)) proxy# + in case toHRecord @h a of + Record (HL hl') -> Record $ HL $ V.unsafeBackpermute hl' perms + +traverseRec :: + forall f h g as. + Applicative f => + ( forall l p n. + (LookupWithIndex l as ~ 'Just '(p, n), KnownNat n) => + Proxy l -> + Proxy p -> + Proxy n -> + h l p -> + f (g l p) + ) -> + Record h as -> + f (Record g as) +traverseRec f (Record hl) = + Record + <$> htraverse @(Uncurried g) @(ToList as) + ( \(Proxy :: Proxy n) + (Uncurried hx) -> + gcastWith (fieldAtToList @n @as) $ + withToListMember @(FieldAt n as) @as $ + gcastWith (unsafeCoerce $ Refl @() :: (n + 1 <=? Size as) :~: 'True) $ + gcastWith (elimMemberToList @(FieldAt n as) @as) $ + gcastWith (indexFieldAt @n @as) $ + Uncurried +#if defined(__GLASGOW_HASKELL__) && __GLASGOW_HASKELL__ >= 810 + @_ @_ +#endif + @g @(FieldAt n as) + <$> f (Proxy @(LabelAt n as)) (Proxy @(EntryAt n as)) (Proxy @n) hx + ) + hl + +traverseRecC :: + forall c f h g as. + (Applicative f, AllOM c as) => + ( forall l p n. + (LookupWithIndex l as ~ 'Just '(p, n), KnownNat n, c l p) => + Proxy l -> + Proxy p -> + Proxy n -> + h l p -> + f (g l p) + ) -> + Record h as -> + f (Record g as) +{-# INLINE traverseRecC #-} +traverseRecC = \f -> traverseRec $ \(l :: Proxy l) p n hlp -> + f l p n hlp + +traverseRec_ :: + forall f h as. + Applicative f => + ( forall l p n. + (LookupWithIndex l as ~ 'Just '(p, n), KnownNat n) => + Proxy l -> + Proxy p -> + Proxy n -> + h l p -> + f () + ) -> + Record h as -> + f () +traverseRec_ f (Record hl) = + HL.htraverse_ + ( \(pn :: Proxy n) (Uncurried hx) -> + withToListMember @(ElemAt n (ToList as)) @as $ + gcastWith (fieldAtToList @n @as) $ + withToListMember @(FieldAt n as) @as $ + gcastWith (unsafeCoerce $ Refl @() :: (n + 1 <=? Size as) :~: 'True) $ + gcastWith (elimMemberToList @(FieldAt n as) @as) $ + gcastWith (indexFieldAt @n @as) $ + gcastWith (elimMemberToList @(ElemAt n (ToList as)) @as) $ + f (Proxy @(LabelAt n as)) (Proxy @(EntryAt n as)) pn hx + ) + hl + +traverseRecC_ :: + forall c f h as. + (Applicative f, AllOM c as) => + ( forall l p n. + (LookupWithIndex l as ~ 'Just '(p, n), KnownNat n, c l p) => + Proxy l -> + Proxy p -> + Proxy n -> + h l p -> + f () + ) -> + Record h as -> + f () +{-# INLINE traverseRecC_ #-} +traverseRecC_ = \f -> traverseRec_ $ \(l :: Proxy l) p n hlp -> + withOrdMapMember @l @as $ f l p n hlp + +foldrMRec :: + forall h fs m b. + Monad m => + ( forall l v n. + (LookupWithIndex l fs ~ 'Just '(v, n), KnownNat n) => + Proxy l -> + Proxy v -> + Proxy n -> + h l v -> + b -> + m b + ) -> + b -> + Record h fs -> + m b +foldrMRec f = \z r -> + appEndoM (foldMapRec (\p l n hx -> EndoM $ f p l n hx) r) z + +foldrRec :: + forall h fs b. + ( forall l v n. + (LookupWithIndex l fs ~ 'Just '(v, n), KnownNat n) => + Proxy l -> + Proxy v -> + Proxy n -> + h l v -> + b -> + b + ) -> + b -> + Record h fs -> + b +foldrRec f = flip $ \r -> + appEndo (foldMapRec (\p l n hx -> Endo $ f p l n hx) r) + +foldlRec' :: + forall h fs b. + ( forall l v n. + (LookupWithIndex l fs ~ 'Just '(v, n), KnownNat n) => + Proxy l -> + Proxy v -> + Proxy n -> + b -> + h l v -> + b + ) -> + b -> + Record h fs -> + b +foldlRec' f z0 xs = foldrRec (\l v n x k z -> k $! f l v n z x) id xs z0 + +foldMapRec :: + forall h fs w. + Monoid w => + ( forall l v n. + (LookupWithIndex l fs ~ 'Just '(v, n), KnownNat n) => + Proxy l -> + Proxy v -> + Proxy n -> + h l v -> + w + ) -> + Record h fs -> + w +foldMapRec f (Record v) = + hfoldMap + ( \(Proxy :: Proxy k) (Proxy :: Proxy x) -> + withToListMember @x @fs $ + gcastWith (elimMemberToList @x @fs) $ + gcastWith (unsafeCoerce $ Refl @() :: L.Index x (ToList fs) :~: k) $ + f (Proxy @(Label x)) (Proxy @(Entry x)) (Proxy @k) + . curried + ) + v + +foldMapRecC :: + forall c h fs w. + (Monoid w, AllOM c fs) => + ( forall l v n. + (LookupWithIndex l fs ~ 'Just '(v, n), KnownNat n, c l v) => + Proxy l -> + Proxy v -> + Proxy n -> + h l v -> + w + ) -> + Record h fs -> + w +{-# INLINE foldMapRecC #-} +foldMapRecC = \f -> foldMapRec f + +pattern MkRecord :: Record h OrdMap.Empty +pattern MkRecord = Record HNil + +elemAtLabelEntry :: + ElemAt n (Labels recs) ::: ElemAt n (Entries recs) + :~: ElemAt n (ToList recs) +elemAtLabelEntry = unsafeCoerce $ Refl @() + +entryToFieldMembership :: + forall n recs. + (KnownNat n, Member (ElemAt n (Entries recs)) (Entries recs)) => + Membership + (ElemAt n (Labels recs) ::: ElemAt n (Entries recs)) + (ToList recs) +entryToFieldMembership = + gcastWith (elemAtLabelEntry @n @recs) $ + elemAtMembership @n @(ToList recs) + +fieldToLabelMembership :: + forall l recs. + (HasLabel l recs) => + Membership l (Labels recs) +fieldToLabelMembership = + unsafeCoerce (fromIntegral $ TL.natVal' @(OrdMap.Index l recs) proxy# :: Word) + +zipWithM :: + forall m h g recs k. + Monad m => + ( forall l v n. + (LookupWithIndex l recs ~ 'Just '(v, n), KnownNat n) => + Proxy l -> + Proxy v -> + Proxy n -> + h l v -> + g l v -> + m (k l v) + ) -> + Record h recs -> + Record g recs -> + m (Record k recs) +zipWithM f (Record l) (Record r) = + Record + <$> hzipWithM + ( \(Proxy :: Proxy n) (Uncurried hx) (Uncurried gx) -> + withToListMember @(ElemAt n (ToList recs)) @recs $ + gcastWith (elimMemberToList @(ElemAt n (ToList recs)) @recs) $ + gcastWith + ( unsafeCoerce $ Refl @() :: + LookupWithIndex (Label (ElemAt n (ToList recs))) recs + :~: 'Just '(Entry (ElemAt n (ToList recs)), n) + ) + $ Uncurried + <$> f + (Proxy @(Label (ElemAt n (ToList recs)))) + (Proxy @(Entry (ElemAt n (ToList recs)))) + (Proxy @n) + hx + gx + ) + l + r + +zipWithM3 :: + forall m h g f recs k. + Monad m => + ( forall l v n. + (LookupWithIndex l recs ~ 'Just '(v, n), KnownNat n) => + Proxy l -> + Proxy v -> + Proxy n -> + h l v -> + g l v -> + f l v -> + m (k l v) + ) -> + Record h recs -> + Record g recs -> + Record f recs -> + m (Record k recs) +zipWithM3 f (Record l) (Record r) (Record s) = + Record + <$> hzipWithM3 + ( \(Proxy :: Proxy n) (Uncurried hx) (Uncurried gx) (Uncurried fx) -> + withToListMember @(ElemAt n (ToList recs)) @recs $ + gcastWith (elimMemberToList @(ElemAt n (ToList recs)) @recs) $ + gcastWith + ( unsafeCoerce $ Refl @() :: + LookupWithIndex (Label (ElemAt n (ToList recs))) recs + :~: 'Just '(Entry (ElemAt n (ToList recs)), n) + ) + $ Uncurried + <$> f + (Proxy @(Label (ElemAt n (ToList recs)))) + (Proxy @(Entry (ElemAt n (ToList recs)))) + (Proxy @n) + hx + gx + fx + ) + l + r + s +zipWith3 :: + forall h g f recs k. + ( forall l v n. + (LookupWithIndex l recs ~ 'Just '(v, n), KnownNat n) => + Proxy l -> + Proxy v -> + Proxy n -> + h l v -> + g l v -> + f l v -> + k l v + ) -> + Record h recs -> + Record g recs -> + Record f recs -> + Record k recs +zipWith3 f (Record l) (Record r) (Record s) = + Record + $ hzipWith3 + ( \(Proxy :: Proxy n) (Uncurried hx) (Uncurried gx) (Uncurried fx) -> + withToListMember @(ElemAt n (ToList recs)) @recs $ + gcastWith (elimMemberToList @(ElemAt n (ToList recs)) @recs) $ + gcastWith + ( unsafeCoerce $ Refl @() :: + LookupWithIndex (Label (ElemAt n (ToList recs))) recs + :~: 'Just '(Entry (ElemAt n (ToList recs)), n) + ) + $ Uncurried + $ f + (Proxy @(Label (ElemAt n (ToList recs)))) + (Proxy @(Entry (ElemAt n (ToList recs)))) + (Proxy @n) + hx + gx + fx + ) + l + r + s + +zipWith :: + forall h g recs k. + ( forall l v n. + (LookupWithIndex l recs ~ 'Just '(v, n), KnownNat n) => + Proxy l -> + Proxy v -> + Proxy n -> + h l v -> + g l v -> + k l v + ) -> + Record h recs -> + Record g recs -> + Record k recs +zipWith f (Record l) (Record r) = + Record $ + hzipWith + ( \(Proxy :: Proxy n) (Uncurried hx) (Uncurried gx) -> + withToListMember @(ElemAt n (ToList recs)) @recs $ + gcastWith (elimMemberToList @(ElemAt n (ToList recs)) @recs) $ + gcastWith + ( unsafeCoerce $ Refl @() :: + LookupWithIndex (Label (ElemAt n (ToList recs))) recs + :~: 'Just '(Entry (ElemAt n (ToList recs)), n) + ) + $ Uncurried $ + f + (Proxy @(Label (ElemAt n (ToList recs)))) + (Proxy @(Entry (ElemAt n (ToList recs)))) + (Proxy @n) + hx + gx + ) + l + r + +unzip :: + forall h g as. + Record (Product h g) as -> + (Record h as, Record g as) +unzip = (Record *** Record) . hunzip' . castProducts . unRecord + +castProducts :: + HList (Uncurried (Product h g)) xs -> + HList (F.Product (Uncurried h) (Uncurried g)) xs +castProducts = hmap $ + const $ \(Uncurried (Pair f g)) -> + F.Pair (Uncurried f) (Uncurried g) + +unzipWithM :: + forall m h recs g k. + Monad m => + ( forall l v n. + (LookupWithIndex l recs ~ 'Just '(v, n), KnownNat n) => + Proxy l -> + Proxy v -> + Proxy n -> + h l v -> + m (g l v, k l v) + ) -> + Record h recs -> + m (Record g recs, Record k recs) +unzipWithM f (Record hl) = + (Record *** Record) + <$> hunzipWithM + ( \pn@(Proxy :: Proxy n) (Uncurried hx) -> + withToListMember @(ElemAt n (ToList recs)) @recs $ + gcastWith (fieldAtToList @n @recs) $ + withToListMember @(FieldAt n recs) @recs $ + gcastWith (unsafeCoerce $ Refl @() :: (n + 1 <=? Size recs) :~: 'True) $ + gcastWith (elimMemberToList @(FieldAt n recs) @recs) $ + gcastWith (indexFieldAt @n @recs) $ + gcastWith (elimMemberToList @(ElemAt n (ToList recs)) @recs) $ + f (Proxy @(Label (ElemAt n (ToList recs)))) (Proxy @(EntryAt n recs)) pn hx <&> \(l, r) -> + (Uncurried l, Uncurried r) + ) + hl + +unzipWith :: + ( forall l v n. + (LookupWithIndex l recs ~ 'Just '(v, n), KnownNat n) => + Proxy l -> + Proxy v -> + Proxy n -> + h l v -> + (g l v, k l v) + ) -> + Record h recs -> + (Record g recs, Record k recs) +{-# INLINE unzipWith #-} +unzipWith f = runIdentity . unzipWithM (fmap (fmap $ fmap Identity) . f) + +generateRec :: + forall recs h. + (KnownNat (Size recs)) => + ( forall l v n. + (LookupWithIndex l recs ~ 'Just '(v, n), KnownNat n) => + Proxy l -> + Proxy v -> + Proxy n -> + h l v + ) -> + Record h recs +generateRec f = + Record $ + HL.generate + ( \(Proxy :: Proxy k) -> + gcastWith (elimFieldCons @(FieldAt k recs)) $ + gcastWith (fieldAtToList @k @recs) $ + gcastWith + ( unsafeCoerce $ Refl @() :: + L.Index (ElemAt k (ToList recs)) (ToList recs) :~: k + ) + $ withToListMember @(FieldAt k recs) @recs $ + Uncurried $ + f + (Proxy @(LabelAt k recs)) + (Proxy @(EntryAt k recs)) + (Proxy @k) + ) + +mapMRecSame :: + forall g h recs f. + (Applicative f) => + ( forall l p n. + (LookupWithIndex l recs ~ 'Just '(p, n), KnownNat n) => + Proxy l -> + Proxy p -> + Proxy n -> + h l p -> + f (g l p) + ) -> + Record h recs -> + f (Record g recs) +{-# INLINE mapMRecSame #-} +mapMRecSame = traverseRec + +mapRecSame :: + forall g h recs. + ( forall l p n. + (LookupWithIndex l recs ~ 'Just '(p, n), KnownNat n) => + Proxy l -> + Proxy p -> + Proxy n -> + h l p -> + g l p + ) -> + Record h recs -> + Record g recs +{-# INLINE mapRecSame #-} +mapRecSame f = + runIdentity + . mapMRecSame (\l p n hx -> Identity (f l p n hx)) + +generateRecM :: + forall recs h m. + ( KnownNat (Size recs) + , Monad m + ) => + ( forall l v n. + (LookupWithIndex l recs ~ 'Just '(v, n), KnownNat n) => + Proxy l -> + Proxy v -> + Proxy n -> + m (h l v) + ) -> + m (Record h recs) +generateRecM f = + fmap Record $ + HL.generateM + ( \(Proxy :: Proxy k) -> + gcastWith (elimFieldCons @(FieldAt k recs)) $ + gcastWith (fieldAtToList @k @recs) $ + gcastWith + ( unsafeCoerce $ Refl @() :: + L.Index (ElemAt k (ToList recs)) (ToList recs) :~: k + ) + $ withToListMember @(FieldAt k recs) @recs $ + Uncurried + <$> f + (Proxy @(LabelAt k recs)) + (Proxy @(EntryAt k recs)) + (Proxy @k) + ) + +generateRecA :: + forall recs h m. + ( KnownNat (Size recs) + , Applicative m + ) => + ( forall l v n. + (LookupWithIndex l recs ~ 'Just '(v, n), KnownNat n) => + Proxy l -> + Proxy v -> + Proxy n -> + m (h l v) + ) -> + m (Record h recs) +generateRecA f = + fmap Record $ + HL.generateA + ( \(Proxy :: Proxy k) -> + gcastWith (elimFieldCons @(FieldAt k recs)) $ + gcastWith (fieldAtToList @k @recs) $ + gcastWith + ( unsafeCoerce $ Refl @() :: + L.Index (ElemAt k (ToList recs)) (ToList recs) :~: k + ) + $ withToListMember @(FieldAt k recs) @recs $ + Uncurried + <$> f + (Proxy @(LabelAt k recs)) + (Proxy @(EntryAt k recs)) + (Proxy @k) + ) + +entrySortIdentFields :: + forall ls. + Entries (FromList (IdentFields ls)) + :~: SortBy Compare2 ls +entrySortIdentFields = unsafeCoerce $ Refl @() + +labelSortIdentFields :: + forall ls. + Labels (FromList (IdentFields ls)) + :~: SortBy Compare2 ls +labelSortIdentFields = unsafeCoerce $ Refl @() + +type Mergeable ls rs = + (MergeableAux ls rs (Merge ls rs)) + +type family MergeableAux ls rs merged :: Constraint where + MergeableAux ls rs merged = + ( KnownNat (Size merged) + , Disjoint ls rs + , Known (MergePerm ls rs) + ) + +-- | Merges two /disjoint/ records into one. +mergeRec :: + forall h recs recs'. + Mergeable recs recs' => + Record h recs -> + Record h recs' -> + Record h (Merge recs recs') +mergeRec (Record (HL l)) (Record (HL r)) = + Record $ + HL $ + V.map + ( \case + Left n -> l V.! fromIntegral n + Right n -> r V.! fromIntegral n + ) + $ V.fromList $ + knownVal' @(MergePerm recs recs') + +data Succ :: Nat ~> Nat + +type instance Apply Succ n = n + 1 + +data IndexWithValMResult key val + = NotFound + | Found Nat + | ValueMismatched key val val + +defineSingletons ''IndexWithValMResult +deriveKnown ''IndexWithValMResult +deriveShowSing ''IndexWithValMResult + +type IndexWithValM l a fs = IWVMAux l a (LookupWithIndex l fs) + +type family IWVMAux l (a :: val) (mb :: Maybe (val, Nat)) where + IWVMAux _ _ 'Nothing = 'NotFound + IWVMAux l a ( 'Just '(b, n)) = IWVMAux' (a == b) l a b n + +type family + IWVMAux' ab (l :: key) (a :: val) b n :: + IndexWithValMResult key val + where + IWVMAux' 'True _ _ _ n = 'Found n + IWVMAux' 'False l a b _ = 'ValueMismatched l a b + +type family ResolveCouldHaveField a where + ResolveCouldHaveField 'NotFound = 'Nothing + ResolveCouldHaveField ( 'Found n) = 'Just n + ResolveCouldHaveField ( 'ValueMismatched l a b) = + TypeError + ( 'Text "A label:" + ':$$: 'Text "\t" ':<>: 'ShowType l + ':$$: 'Text "must be associated with a type:" + ':$$: 'Text "\t" ':<>: 'ShowType a ':<>: 'Text "," + ':$$: 'Text "but got:" + ':$$: 'Text "\t" ':<>: 'ShowType b + ) + +class + (Known (ResolveCouldHaveField (IndexWithValM l a fs))) => + CouldHaveField l a fs + +instance + (Known (ResolveCouldHaveField (IndexWithValM l a fs))) => + CouldHaveField l a fs + +instance + ( Known (fs :: OrdMap key v) + , Known (l :: key) + , Known (a :: v) + , SOrd key + , STestEquality v + , ShowSing key, ShowSing v + ) => + Deferrable (CouldHaveField l a fs) + where + deferEither _ r = + case sIndexWithValM + (sKnownVal' @l) + (sKnownVal' @a) + (sKnownVal' @fs) of + SFound n -> withKnown' (SJust n) $ Right r + SNotFound -> Right r + SValueMismatched _ _ _ -> + Left $ "A value for label " <> show (sKnownVal' @l) <> " mismatched!" + +recFieldTraversal :: + forall l a h xs. + CouldHaveField l a xs => + Traversal' (Record h xs) (h l a) +recFieldTraversal = + case knownVal' @(ResolveCouldHaveField (IndexWithValM l a xs)) of + Nothing -> const pure + Just n -> + coerced + @(Record h xs) + @(Record h xs) + @(V.Vector Any) + @(V.Vector Any) + . ix' (fromIntegral n) + . iso unsafeCoerce unsafeCoerce + +sIndexWithValM :: + (SOrd key, STestEquality val) => + Sing (l :: key) -> + Sing (v :: val) -> + Sing (map :: OrdMap key val) -> + Sing (IndexWithValM l v map) +sIndexWithValM l a fs = + case sLookupWithIndex l fs of + SNothing -> SNotFound + SJust (SPair (sv :: Sing x) (sn :: SNat n)) -> + case sTestEquality a sv of + Equal -> SFound sn + NonEqual -> SValueMismatched l a sv + +projField :: + forall l a h fs. + (CouldHaveField l a fs) => + Record h fs -> + Maybe (h l a) +projField (Record (HL hs)) = do + i <- knownVal' @(ResolveCouldHaveField (IndexWithValM l a fs)) + return $ unsafeCoerce $ hs V.! fromIntegral i + +derivingUnbox + "Record" + [t| + forall h recs. + ( KnownTyList (ToList recs) + , All U.Unbox (Map (Uncurried h) (ToList recs)) + ) => + Record h recs -> + HList (Uncurried h) (ToList recs) + |] + [|\(Record hl) -> hl|] + [|Record|] + +instance POrd l => POrd (Field l v) where + type Compare p q = Apply (Apply CmpLabel p) q + +type family NotMemberB (xs :: [k]) (x :: k) :: Bool where + NotMemberB '[] x = 'True + NotMemberB (x ': xs) x = 'False + NotMemberB (_ ': xs) x = NotMemberB xs x + +class NotMemberB xs x ~ 'True => AbsentIn xs x + +instance NotMemberB xs x ~ 'True => AbsentIn xs x + +type SConst ty = OnEntry' Symbol (Const ty) + +fields :: + forall a. + ( IsRecord a + , KnownNat (Size (Fields a)) + , AllOM (LabelC KnownSymbol) (Fields a) + ) => + Record (SConst String) (Fields a) +fields = generateRec $ \(_ :: Proxy l) _ _ -> + OnEntry $ Const $ symbolVal @l Proxy + +getSConst :: SConst a tag b -> a +getSConst = getConst . runOnEntry + +sequenceRec :: + Applicative f => + Record (OnEntry f) rec -> + f (Record Tagged rec) +{-# INLINE sequenceRec #-} +sequenceRec = + traverseRec $ + const $ + const $ + const $ + fmap Tagged . runOnEntry + +data WithMembership h ks l v where + WithMembership + :: (KnownNat n, LookupWithIndex l ks ~ 'Just '(v, n)) + => Proxy l -> Proxy n -> h l v -> WithMembership h ks l v + +deriving instance + Show (h l v) => Show (WithMembership h ks l v) + +-- | Higher-kinded version of 'These'. +-- +-- /c.f./ 'alignRec', 'alignRecWith', 'alignRecWithM', and 'TheseC'. +data TheseF h g k (these :: These val val') where + ThisF :: forall h g k v. h k v -> TheseF h g k ('This v) + ThatF :: forall h g k v'. g k v' -> TheseF h g k ('That v') + TheseF :: forall h g k v v'. h k v -> g k v' -> TheseF h g k ('These v v') + +-- | Dependent constraint family for 'These'. +-- +-- /c.f./ 'alignRec', 'alignRecWith', 'alignRecWithM', and 'TheseC'. +type family TheseC c d (v :: These a b) :: Constraint where + TheseC c _ ('This x) = c x + TheseC _ d ('That y) = d y + TheseC c d ('These x y) = (c x, d y) + +deriving instance (TheseC (OverC h Show k) (OverC g Show k) v) + => Show (TheseF h g k v) + +newtype OrdSomeSing k = OrdSomeSing (SomeSing k) +instance SOrd k => Eq (OrdSomeSing k) where + {-# INLINE (==) #-} + OrdSomeSing (MkSomeSing a) == OrdSomeSing (MkSomeSing b) = + case sCompare a b of + SEQ -> True + _ -> False + {-# INLINE (/=) #-} + OrdSomeSing (MkSomeSing a) /= OrdSomeSing (MkSomeSing b) = + case sCompare a b of + SEQ -> False + _ -> True + +instance SOrd k => Ord (OrdSomeSing k) where + compare (OrdSomeSing (MkSomeSing a)) (OrdSomeSing (MkSomeSing b)) = + demote $ sCompare a b + {-# INLINE compare #-} + +type Alignable ks ks' = + ( Known ks, + Known ks' + ) + +data SomeEntry h ks where + MkSomeEntry + :: (LookupWithIndex k ks ~ 'Just '(v, n), KnownNat n) + => Proxy k -> Proxy n -> h k v -> SomeEntry h ks + +withKnownLabels + :: forall ks r. Known ks + => (AllOM (LabelC Known) ks => r) + -> r +withKnownLabels = allOMIntro @(LabelC Known) @ks $ \ _ _ _-> Dict + +-- | O(n) +toSomeEntryMap + :: (SOrd key, Known (ks :: OrdMap key val)) + => Record h ks + -> M.Map (OrdSomeSing key) (SomeEntry h ks) +{-# INLINE [1] toSomeEntryMap #-} +toSomeEntryMap (r :: Record h ks) = + withKnownLabels @ks $ + M.fromAscList $ DL.toList $ + foldMapRecC @(LabelC Known) + (\ pkeyl _ pnn hlv -> + DL.singleton + (OrdSomeSing $ MkSomeSing $ sKnownVal pkeyl, + MkSomeEntry pkeyl pnn hlv) + ) + r + +-- | O(n) +fromSomeEntryMap + :: (SOrd key, Known (ks :: OrdMap key val)) + => M.Map (OrdSomeSing key) (SomeEntry h ks) + -> Record h ks +{-# INLINE [1] fromSomeEntryMap #-} +fromSomeEntryMap = + Record . HL . L.fold + (L.premap (\(MkSomeEntry _ _ hkv) -> unsafeCoerce hkv :: Any) L.vector) + +{-# RULES +"fromSomeEntryMap/toSomeEntryMap" forall xs. + fromSomeEntryMap (toSomeEntryMap xs) = xs + #-} + +trustMeEqual :: forall a b. a :~: b +trustMeEqual = unsafeCoerce $ Refl @() + +{- | +Aligns two records into one. + +The higher-kinded analogue of 'Data.align.align' for 'M.Map' in @semialign@ package. + +c.f. 'alignRecWith', 'alignRecWithM', and 'TheseF'. + +>>> import Data.Functor.Const +>>> let rec1 = (emptyRec &+ field @"foo" := Tagged True &+ field @"buz" := Tagged "nux") +>>> let rec2 = (emptyRec &+ field @"foo" := Tagged (42 :: Int) &+ field @"bar" := Tagged 'd') +>>> alignRec rec1 rec2 +Record {bar = ThatF (WithMembership Proxy Proxy (Tagged 'd')), buz = ThisF (WithMembership Proxy Proxy (Tagged "nux")), foo = TheseF (WithMembership Proxy Proxy (Tagged True)) (WithMembership Proxy Proxy (Tagged 42))} +-} +alignRec + :: (Alignable ks ks') + => SOrd key + => Record h (ks :: OrdMap key val) + -> Record g (ks' :: OrdMap key val') + -> Record (TheseF (WithMembership h ks) (WithMembership g ks')) (AlignOM ks ks') +{-# NOINLINE [1] alignRec #-} +alignRec (l :: Record h ks) (r :: Record g ks') = + let l' = toSomeEntryMap l + r' = toSomeEntryMap r + lr = M.toList $ align l' r' + in Record $ HL $ V.fromList + [ case v of + This (MkSomeEntry (pkk :: Proxy k') pnn hkv) -> + unsafeCoerce $ + ThisF @(WithMembership h ks) @(WithMembership g ks') + (WithMembership pkk pnn hkv) + That (MkSomeEntry (pkk :: Proxy k') pnn gkv) -> + unsafeCoerce $ + ThatF @(WithMembership h ks) @(WithMembership g ks') + (WithMembership pkk pnn gkv) + These (MkSomeEntry (pkl :: Proxy k) pnn hkv) + (MkSomeEntry (pkr :: Proxy k') pnm gkv) -> + gcastWith (trustMeEqual @k @k') $ + unsafeCoerce $ + TheseF @(WithMembership h ks) @(WithMembership g ks') + (WithMembership pkl pnn hkv) + (WithMembership pkr pnm gkv) + | (OrdSomeSing (MkSomeSing _), v) + <- lr + ] + +{- | +Analogous to 'zipWith', combines two records by taking the union of their fields and combining the elements with the given function. + +The higher-kinded analogue of 'Data.align.alignWith' for 'M.Map' in @semialign@ package. + +c.f. 'alignRec', 'alignRecWithM', and 'TheseF'. +-} +alignRecWith + :: (Alignable ks ks') + => SOrd key + => (forall l n v. + ( LookupWithIndex l (AlignOM ks ks') ~ 'Just '(v, n) + , KnownNat n + ) => + Proxy l + -> Proxy n + -> TheseF (WithMembership h ks) (WithMembership g ks') l v + -> k l v) + -> Record h (ks :: OrdMap key val) + -> Record g (ks' :: OrdMap key val') + -> Record k (AlignOM ks ks') +alignRecWith f (l :: Record h ks) (r :: Record g ks') = + mapRecSame + (\ pl _pThese pnn theseF + -> f pl pnn theseF + ) + $ alignRec l r + + +{- | +Analogous to 'zipWithM', combines two records by taking the union of their fields and combining the elements with the given monadic function. + +The higher-kinded and monadic analogue of 'Data.align.alignWith' for 'M.Map' in @semialign@ package. + +c.f. 'alignRec', 'alignRecWith', and 'TheseF'. +-} +alignRecWithM + :: (Applicative f, Alignable ks ks') + => SOrd key + => (forall l n v. + ( LookupWithIndex l (AlignOM ks ks') ~ 'Just '(v, n) + , KnownNat n + ) => + Proxy l + -> Proxy n + -> TheseF (WithMembership h ks) (WithMembership g ks') l v + -> f (k l v)) + -> Record h (ks :: OrdMap key val) + -> Record g (ks' :: OrdMap key val') + -> f (Record k (AlignOM ks ks')) +alignRecWithM f (l :: Record h ks) (r :: Record g ks') = + traverseRec + (\ pl _pThese pnn theseF + -> f pl pnn theseF + ) + $ alignRec l r + +{- | +The inverse to 'alignRec'. +-} +unalignRec + :: (Alignable ks ks') + => SOrd key + => Record (TheseF (WithMembership h ks) (WithMembership g ks')) (AlignOM ks ks') + -> (Record h (ks :: OrdMap key v), Record g ks') +{-# NOINLINE [1] unalignRec #-} +unalignRec (r :: Record (TheseF (WithMembership h ks) (WithMembership g ks')) (AlignOM (ks :: OrdMap key val) ks')) = + let ksks' = (sAlignOM (sKnownVal' @ks) (sKnownVal' @ks')) + in withKnown' ksks' $ + withKnownLabels @(AlignOM ks ks') $ + let thsMap :: M.Map (OrdSomeSing key) (These (SomeEntry h ks) (SomeEntry g ks')) + thsMap = toSomeEntryMap r <&> \case + MkSomeEntry _ _ (ThisF (WithMembership pl pm hkv)) -> + This (MkSomeEntry pl pm hkv) + MkSomeEntry _ _ (ThatF (WithMembership pl pm gkv')) -> + That (MkSomeEntry pl pm gkv') + MkSomeEntry _ _ + (TheseF (WithMembership pl pm hkv) (WithMembership pl' pk gkv')) -> + These (MkSomeEntry pl pm hkv) (MkSomeEntry pl' pk gkv') + (ls, rs) = unalign thsMap + in (fromSomeEntryMap ls, fromSomeEntryMap rs) + +{-# RULES +"unalignRec/alignRec" forall ls rs. + unalignRec (alignRec ls rs) = (ls, rs) + #-} + +-- >>> collectRec @(Identity :*: Identity) @(SConst Int) @(SConst Int) (\_ _ _ (OnEntry (Const l)) -> Identity (OnEntry (Const (l `div` 2))) :*: Identity (OnEntry (Const $ l `mod` 2))) $ emptyRec &+ field @"foo" := OnEntry (Const (12 :: Int) :: Const Int '()) &+ #bar := OnEntry (Const 42 :: Const Int '()) &+ #duz := OnEntry (Const 59 :: Const Int '()) +-- Identity (Record {bar = OnEntry {runOnEntry = Const 21}, duz = OnEntry {runOnEntry = Const 29}, foo = OnEntry {runOnEntry = Const 6}}) :*: Identity (Record {bar = OnEntry {runOnEntry = Const 0}, duz = OnEntry {runOnEntry = Const 1}, foo = OnEntry {runOnEntry = Const 0}}) + +collectRec + :: forall g k h recs . + Distributive g + => ( forall l p n. + (LookupWithIndex l recs ~ 'Just '(p, n), KnownNat n) => + Proxy l -> + Proxy p -> + Proxy n -> + h l p -> + g (k l p) + ) + -> Record h recs + -> g (Record k recs) +collectRec f (Record (HL vec)) = + fmap (Record . HL) + $ collect + (\(i, v) -> + withKnownNat (fromIntegral i) $ \(p :: Proxy n) -> + gcastWith + (trustMeEqual :: + 'Just '(Entry (ElemAt n (ToList recs)), n) :~: + LookupWithIndex (Label (ElemAt n (ToList recs))) recs + ) $ + let hlv = f + (Proxy @(Label (ElemAt n (ToList recs)))) + (Proxy @(Entry (ElemAt n (ToList recs)))) + p + (unsafeCoerce v :: h (Label (ElemAt n (ToList recs))) (Entry (ElemAt n (ToList recs)))) + in fmap + (unsafeCoerce + :: k (Label (ElemAt n (ToList recs))) (Entry (ElemAt n (ToList recs))) -> Any + ) hlv + ) + $ V.indexed vec diff --git a/elgenerics-containers/src/Data/Record/HigherKinded/Internal.hs b/elgenerics-containers/src/Data/Record/HigherKinded/Internal.hs new file mode 100644 index 0000000..629d7a7 --- /dev/null +++ b/elgenerics-containers/src/Data/Record/HigherKinded/Internal.hs @@ -0,0 +1,73 @@ +{-# LANGUAGE CPP #-} +{-# LANGUAGE DataKinds #-} +{-# LANGUAGE DeriveAnyClass #-} +{-# LANGUAGE DerivingStrategies #-} +{-# LANGUAGE DerivingVia #-} +{-# LANGUAGE GADTs #-} +{-# LANGUAGE TemplateHaskell #-} +{-# LANGUAGE TypeFamilies #-} +{-# LANGUAGE UndecidableInstances #-} + +#if __GLASGOW_HASKELL__ >= 810 +#endif + +module Data.Record.HigherKinded.Internal (module Data.Record.HigherKinded.Internal) where + +import Control.DeepSeq +import Data.HList.HigherKinded +import Data.Kind +import Data.TypeLevel.OrdMap as OrdMap +import Data.Vector.Unboxed qualified as U +import Data.Vector.Unboxed.Deriving +import GHC.Generics +import Type.Reflection + +#if defined(__GLASGOW_HASKELL__) && __GLASGOW_HASKELL__ >= 810 +type Uncurried + :: forall k k'. (k -> k' -> Type) -> Field k k' -> Type +#endif + +newtype Uncurried (h :: k -> k' -> Type) fld = Uncurried {curried :: h (Label fld) (Entry fld)} + deriving (Generic, Typeable) + +deriving newtype instance + (NFData (h l a)) => NFData (Uncurried h (l ::: a)) + +deriving newtype instance + (Eq (h l a)) => Eq (Uncurried h (l ::: a)) + +deriving newtype instance + (Ord (h l a)) => Ord (Uncurried h (l ::: a)) + +deriving newtype instance + (Show (h l a)) => Show (Uncurried h (l ::: a)) + +derivingUnbox + "Uncurried" + [t|forall h l a. (U.Unbox (h l a)) => Uncurried h (l ::: a) -> h l a|] + [|curried|] + [|Uncurried|] + +newtype OnLabel (h :: k -> Type) (l :: k) (a :: k') = OnLabel {runOnLabel :: h l} + deriving (Read, Show, Eq, Ord, Generic, Typeable) + deriving newtype (NFData) + +derivingUnbox + "OnLabel" + [t|forall h l a. (U.Unbox (h l)) => OnLabel h l a -> h l|] + [|runOnLabel|] + [|OnLabel|] + +newtype OnEntry (h :: k' -> Type) (l :: k) (a :: k') = OnEntry {runOnEntry :: h a} + deriving (Read, Show, Eq, Ord, Generic, Typeable) + deriving newtype (NFData) + +derivingUnbox + "OnEntry" + [t|forall h l a. (U.Unbox (h a)) => OnEntry h l a -> h a|] + [|runOnEntry|] + [|OnEntry|] + +newtype Record h recs = Record (HList (Uncurried h) (ToList recs)) + +type HasLabel (l :: k) (xs :: OrdMap k v) = OrdMap.Member l xs diff --git a/elgenerics-containers/src/Data/Record/HigherKinded/OnEntry.hs b/elgenerics-containers/src/Data/Record/HigherKinded/OnEntry.hs new file mode 100644 index 0000000..5bf3169 --- /dev/null +++ b/elgenerics-containers/src/Data/Record/HigherKinded/OnEntry.hs @@ -0,0 +1,265 @@ +{-# LANGUAGE AllowAmbiguousTypes #-} +{-# LANGUAGE DataKinds #-} +{-# LANGUAGE ExplicitNamespaces #-} +{-# LANGUAGE GADTs #-} +{-# OPTIONS_GHC -fplugin Data.TypeLevel.List.Solver #-} + +-- | エントリーにだけ依存するレコードのインタフェース +module Data.Record.HigherKinded.OnEntry ( + Record, + HasLabel, + OnEntry (..), + IsRecord (..), + Labels, + Entries, + field, + type (<:), + (:=) (..), + FieldLabel (..), + traverseRec, + traverseRecC, + traverseRec_, + traverseRecC_, + foldMapRec, + foldMapRecC, + singletonRec, + singletonRec', + emptyRec, + (&.), + Extendible, + (&+), + Modifiable, + (&%~), + (&|~), + (&-), + generateRec, + generateRecM, + fields, +) where + +import Data.Coerce +import Data.Functor.Const +import Data.Proxy +import Data.Record.HigherKinded ( + Extendible, + FieldLabel (..), + HasLabel, + IsRecord (..), + Modifiable, + OnEntry (..), + field, + (:=) (..), + type (<:), + ) +import Data.Record.HigherKinded qualified as HK +import Data.TypeLevel.OrdMap +import GHC.TypeLits + +type Record h = HK.Record (HK.OnEntry h) + +emptyRec :: Record h Empty +emptyRec = HK.emptyRec + +singletonRec :: + h a -> Record h (Singleton l a) +singletonRec = HK.singletonRec . OnEntry + +singletonRec' :: + l := h a -> + Record h (Singleton l a) +singletonRec' = HK.singletonRec' . coerce + +fields :: + forall a. + ( IsRecord a + , AllOM (HK.LabelC KnownSymbol) (Fields a) + ) => + Record (Const String) (Fields a) +fields = HK.fields @a + +traverseRec :: + forall f h g as. + (Applicative f) => + ( forall l x n. + (LookupWithIndex l as ~ 'Just '(x, n), KnownNat n) => + Proxy l -> + Proxy x -> + Proxy n -> + h x -> + f (g x) + ) -> + Record h as -> + f (Record g as) +{-# INLINE traverseRec #-} +traverseRec = \f -> HK.traverseRec $ \l x n (OnEntry hx) -> + OnEntry <$> f l x n hx + +traverseRecC :: + forall c f h g as. + (Applicative f, AllOM (EntryC c) as) => + ( forall l x n. + (LookupWithIndex l as ~ 'Just '(x, n), KnownNat n, c x) => + Proxy l -> + Proxy x -> + Proxy n -> + h x -> + f (g x) + ) -> + Record h as -> + f (Record g as) +{-# INLINE traverseRecC #-} +traverseRecC f = + traverseRec $ + \(l :: Proxy l) + (x :: Proxy x) + (n :: Proxy n) + (hx :: h x) -> f l x n hx + +traverseRec_ :: + forall f h as. + (Applicative f) => + ( forall l x n. + (LookupWithIndex l as ~ 'Just '(x, n), KnownNat n) => + Proxy l -> + Proxy x -> + Proxy n -> + h x -> + f () + ) -> + Record h as -> + f () +{-# INLINE traverseRec_ #-} +traverseRec_ = \f -> HK.traverseRec_ $ \l x n -> + f l x n . runOnEntry + +traverseRecC_ :: + forall c f h as. + (Applicative f, AllOM (EntryC c) as) => + ( forall l x n. + (LookupWithIndex l as ~ 'Just '(x, n), KnownNat n, c x) => + Proxy l -> + Proxy x -> + Proxy n -> + h x -> + f () + ) -> + Record h as -> + f () +{-# INLINE traverseRecC_ #-} +traverseRecC_ = \f -> HK.traverseRecC_ @(EntryC c) @f @(OnEntry h) @as $ + \l x n (OnEntry hx) -> + f l x n hx + +foldMapRec :: + forall h fs w. + (Monoid w) => + ( forall l v n. + (LookupWithIndex l fs ~ 'Just '(v, n), KnownNat n) => + Proxy l -> + Proxy v -> + Proxy n -> + h v -> + w + ) -> + Record h fs -> + w +{-# INLINE foldMapRec #-} +foldMapRec = \f -> + HK.foldMapRec $ \(l :: Proxy l) v n -> + f l v n . runOnEntry + +foldMapRecC :: + forall c h fs w. + (Monoid w, AllOM (EntryC c) fs) => + ( forall l v n. + (LookupWithIndex l fs ~ 'Just '(v, n), KnownNat n) => + Proxy l -> + Proxy v -> + Proxy n -> + h v -> + w + ) -> + Record h fs -> + w +{-# INLINE foldMapRecC #-} +foldMapRecC = \f -> foldMapRec f + +(&.) :: + forall l xs h. + (HasLabel l xs) => + Record h xs -> + l := h (Lookup' l xs) -> + Record h xs +(&.) = \r -> (HK.&.) r . fmap OnEntry + +infixl 1 &. + +(&+) :: + forall l x xs h. + (Extendible (l ::: x) xs) => + Record h xs -> + l := h x -> + Record h ((l ::: x) <: xs) +(&+) = coerce $ (HK.&+) @l @x @xs @(OnEntry h) + +infixl 1 &+ + +(&%~) :: + forall l xs h a. + (Modifiable l a xs) => + Record h xs -> + l := (h (Lookup' l xs) -> h a) -> + Record h ((l ::: a) <: xs) +(&%~) = coerce $ (HK.&%~) @l @xs @(OnEntry h) @a + +infixl 1 &%~ + +(&|~) :: + forall l xs a h. + (HasLabel l xs) => + Record h xs -> + l := h a -> + Record h ((l ::: a) <: xs) +(&|~) = coerce $ (HK.&|~) @l @xs @a @(OnEntry h) + +infixl 1 &|~ + +(&-) :: + forall l xs h. + (HasLabel l xs) => + Record h xs -> + FieldLabel l -> + Record h (Delete l xs) +(&-) = (HK.&-) + +infixl 1 &- + +generateRec :: + forall recs h. + (KnownNat (Size recs)) => + ( forall l v n. + (LookupWithIndex l recs ~ 'Just '(v, n), KnownNat n) => + Proxy l -> + Proxy v -> + Proxy n -> + h v + ) -> + Record h recs +{-# INLINE generateRec #-} +generateRec = \f -> HK.generateRec $ \a b -> OnEntry . f a b + +generateRecM :: + forall recs h m. + ( KnownNat (Size recs) + , Monad m + ) => + ( forall l v n. + (LookupWithIndex l recs ~ 'Just '(v, n), KnownNat n) => + Proxy l -> + Proxy v -> + Proxy n -> + m (h v) + ) -> + m (Record h recs) +{-# INLINE generateRecM #-} +generateRecM = \f -> HK.generateRecM $ \a b -> fmap OnEntry . f a b diff --git a/elgenerics-containers/src/Data/Record/HigherKinded/Unsafe.hs b/elgenerics-containers/src/Data/Record/HigherKinded/Unsafe.hs new file mode 100644 index 0000000..aa64230 --- /dev/null +++ b/elgenerics-containers/src/Data/Record/HigherKinded/Unsafe.hs @@ -0,0 +1,29 @@ +{-# LANGUAGE DataKinds #-} + +module Data.Record.HigherKinded.Unsafe ( + unsafeMkRecord, + unsafeDeconsRecord, +) where + +import Data.HList.Internal +import Data.Proxy +import Data.Record.HigherKinded +import Data.Record.HigherKinded.Internal +import Data.TypeLevel.List +import Data.TypeLevel.Ord +import Data.Vector qualified as V +import GHC.Exts + +unsafeMkRecord :: + forall h xs pxy. + (Sortable Compare2 xs) => + pxy xs -> + V.Vector Any -> + Record h (FromList (SortFields xs)) +unsafeMkRecord _ v = + let idxs = natListVal @(MapApply Fst1 (SortByWithIndex Compare2 xs)) Proxy + in Record $ HL $ V.unsafeBackpermute v $ V.fromList $ map fromIntegral idxs + +unsafeDeconsRecord :: + Record h xs -> V.Vector Any +unsafeDeconsRecord (Record (HL hl)) = hl diff --git a/elgenerics-containers/src/Data/Record/Plugin.hs b/elgenerics-containers/src/Data/Record/Plugin.hs new file mode 100644 index 0000000..015a903 --- /dev/null +++ b/elgenerics-containers/src/Data/Record/Plugin.hs @@ -0,0 +1,108 @@ +{-# LANGUAGE CPP #-} +{-# LANGUAGE GADTs #-} +{-# LANGUAGE LambdaCase #-} +{-# LANGUAGE RecordWildCards #-} +{-# OPTIONS_GHC -Wno-orphans #-} + +module Data.Record.Plugin (plugin) where + +import Control.Monad +import Data.Generics +import Data.Maybe +import GHC +import GHC.TcPluginM.Orphans () +#if MIN_VERSION_ghc(9,0,1) +import GHC.Plugins +import GHC.Types.SourceText (SourceText(..)) +#else +import GhcPlugins +#endif + +plugin :: Plugin +plugin = + defaultPlugin + { parsedResultAction = recordExp + , pluginRecompile = const $ return NoForceRecompile + } + +recordExp :: + [CommandLineOption] -> + ModSummary -> + HsParsedModule -> + Hsc HsParsedModule +recordExp opts _ pmods = do + let cons = mkDataOcc $ head $ opts ++ ["MkRecord"] + m <- everywhereM (mkM $ procRecCon cons) $ hpm_module pmods + return $ pmods {hpm_module = m} + +procRecCon :: + OccName -> + LHsExpr GhcPs -> + Hsc (LHsExpr GhcPs) +procRecCon + cons + (L gLoc RecordCon {rcon_con = L _ (Unqual c), rcon_flds = HsRecFields {..}}) + | c == cons = do + when (isJust rec_dotdot) $ + error "Wildcard in Extensible Record construction not allowed" + toRecordCons gLoc rec_flds +procRecCon _ rc = return rc + +toRecordCons :: SrcSpanAnnA -> [LHsRecField GhcPs (LHsExpr GhcPs)] -> Hsc (LHsExpr GhcPs) +toRecordCons gLoc fs = do + recHKM <- lookupModule (mkModuleName "Data.Record.HigherKinded") Nothing + recM <- lookupModule (mkModuleName "Data.Record") Nothing + let emp = Orig recM $ mkVarOcc "emptyRec" + eql = Orig recHKM $ mkDataOcc ":=" + flabl = Orig recHKM $ mkDataOcc "FieldLabel" + flablTy = Orig recHKM $ mkTcOcc "FieldLabel" + castE = Orig recHKM $ mkVarOcc "castRecord" + addF = Orig recM $ mkVarOcc "&+" + toBody (L l HsRecField {..}) = + let L fldL fldB = hsRecFieldLbl + in L l $ + OpApp + EpAnnNotUsed + ( L (noAnnSrcSpan fldL) $ + ExprWithTySig + EpAnnNotUsed + (noLocA $ HsVar NoExtField (noLocA flabl)) + ( HsWC NoExtField + $ noLocA + $ HsSig NoExtField (HsOuterImplicit NoExtField) + $ noLocA + $ HsAppTy + NoExtField + ( noLocA $ + HsTyVar EpAnnNotUsed NotPromoted (noLocA flablTy) + ) + $ noLocA + $ HsTyLit NoExtField + $ HsStrTy NoSourceText + $ occNameFS + $ occName + $ unLoc + $ rdrNameFieldOcc fldB + ) + ) + (noLocA $ HsVar NoExtField $ noLocA eql) + hsRecFieldArg + bdy = + L gLoc + $ HsApp + EpAnnNotUsed + (noLocA $ HsVar NoExtField $ noLocA castE) + $ noLocA + $ HsPar EpAnnNotUsed + $ noLocA + $ foldl + ( \a b -> + OpApp + EpAnnNotUsed + (noLocA a) + (noLocA $ HsVar NoExtField $ noLocA addF) + b + ) + (HsVar NoExtField $ noLocA emp) + $ map toBody fs + return bdy diff --git a/elgenerics-containers/src/Data/Sum/Class.hs b/elgenerics-containers/src/Data/Sum/Class.hs new file mode 100644 index 0000000..d19eca7 --- /dev/null +++ b/elgenerics-containers/src/Data/Sum/Class.hs @@ -0,0 +1,113 @@ +{-# LANGUAGE DataKinds #-} +{-# LANGUAGE DefaultSignatures #-} +{-# LANGUAGE GADTs #-} +{-# LANGUAGE TypeFamilies #-} +{-# LANGUAGE UndecidableInstances #-} + +module Data.Sum.Class ( + HasSummand (..), + inject, + project, + ginject, + SumPath, + Path' (..), + KnownPath (..), +) where + +import Data.Maybe +import Data.Proxy +import Data.TypeLevel.Maybe +import Data.TypeLevel.Path +import GHC.TypeLits + +inject :: (HasSummand c a) => c -> a +{-# INLINE [1] inject #-} +inject = inject' + +project :: (HasSummand c a) => a -> Maybe c +{-# INLINE [1] project #-} +project = project' + +{-# RULES +"project/inject" forall x. + project (inject x) = + Just x +"inject/project" forall x. + inject (fromJust (project x)) = + x + #-} + +inject0 :: SumPath c f -> c -> f () +inject0 K c = K1 c +inject0 (M f) c = M1 $ inject0 f c +inject0 (InL f) c = L1 $ inject0 f c +inject0 (InR g) c = R1 $ inject0 g c + +project0 :: SumPath c f -> f () -> Maybe c +project0 K (K1 c) = Just c +project0 (M p) (M1 f) = project0 p f +project0 (InL p) (L1 f) = project0 p f +project0 (InR p) (R1 f) = project0 p f +project0 _ _ = Nothing + +ginject :: (Generic a) => SumPath c (Rep a) -> c -> a +ginject pth c = to $ inject0 pth c + +gproject :: (Generic a) => SumPath c (Rep a) -> a -> Maybe c +gproject pth = project0 pth . from + +{- | 値コンストラクタを持つか? + + Generic を使ったデフォルト実装では、 + 自動でコンストラクタを探してきて inject する。 + + __注__: 一旦 @'Generic'@ を介して変換するので、 + @'inject'@, @'project'@ 共に \(O(\log n)\) + 時間計算量が掛かる(ここで \(n\) はデータ構築子の数)。 + + 構築子が少なければあまり影響はないが、そうではない場合は + 個別にちゃんと @'inject'@ を実装してやること。 +-} +class HasSummand c a where + inject' :: c -> a + default inject' :: + ( Generic a + , KnownPath SumOnly c (Rep a) (ConsPath c a) + ) => + c -> + a + inject' = ginject (getPath (Proxy @c) (Proxy @a)) + + project' :: a -> Maybe c + default project' :: + ( Generic a + , KnownPath SumOnly c (Rep a) (ConsPath c a) + ) => + a -> + Maybe c + project' = gproject (getPath (Proxy @c) (Proxy @a)) + +instance {-# OVERLAPPING #-} HasSummand c c where + inject' = id + project' = Just + +getPath :: + forall c a pxy. + (KnownPath SumOnly c (Rep a) (ConsPath c a)) => + pxy c -> + pxy a -> + SumPath c (Rep a) +getPath _ _ = pathVal (Proxy :: Proxy (ConsPath c a)) + +type ConsPath :: + forall c -> forall a -> SumPath c (Rep a) +type family ConsPath c a :: SumPath c (Rep a) where + ConsPath c a = + FromJust + ( 'Text "A type `" + ':<>: 'ShowType a + ':<>: 'Text "' doesn't have unary constructor with type `" + ':<>: 'ShowType c + ':<>: 'Text "'" + ) + (PositionOf SumOnly c a) diff --git a/elgenerics-containers/src/Data/TypeLevel/BinTree.hs b/elgenerics-containers/src/Data/TypeLevel/BinTree.hs new file mode 100644 index 0000000..33b56b8 --- /dev/null +++ b/elgenerics-containers/src/Data/TypeLevel/BinTree.hs @@ -0,0 +1,50 @@ +{-# LANGUAGE DataKinds #-} +{-# LANGUAGE TypeFamilies #-} +{-# LANGUAGE UndecidableInstances #-} + +module Data.TypeLevel.BinTree (BinTree (..), Bin, Val, Stop, MkBin, ToList, FromList) where + +import Data.TypeLevel.List +import GHC.Generics +import Type.Reflection + +data BinTree a + = Bin Nat (BinTree a) (BinTree a) + | Val a + | Stop + deriving (Typeable, Generic) + +type Val = 'Val + +type Bin = 'Bin + +type Stop = 'Stop + +type family Size (tree :: BinTree a) :: Nat where + Size 'Stop = 0 + Size ('Val _) = 1 + Size (Bin n _ _) = n + +type MkBin l r = Bin (Size l + Size r) l r + +type FromList as = FromListAux (Map 'Val as) + +type family FromListAux (as :: [BinTree a]) :: BinTree a where + FromListAux '[] = 'Stop + FromListAux '[t] = t + FromListAux xs = + FromListAux (MkBins xs) + +type family MkBins (trs :: [BinTree a]) :: [BinTree a] where + MkBins '[] = '[] + MkBins '[t] = '[t] + MkBins (x ': y ': xs) = + MkBin x y ': MkBins xs + +type ToList tree = ToListAux '[] tree + +type family ToListAux (acc :: [a]) (tree :: BinTree a) :: [a] where + ToListAux acc 'Stop = acc + ToListAux acc ('Val a) = a ': acc + ToListAux acc ('Bin _ l r) = + ToListAux (ToListAux acc r) l diff --git a/elgenerics-containers/src/Data/TypeLevel/Path.hs b/elgenerics-containers/src/Data/TypeLevel/Path.hs new file mode 100644 index 0000000..c51dfa4 --- /dev/null +++ b/elgenerics-containers/src/Data/TypeLevel/Path.hs @@ -0,0 +1,134 @@ +{-# LANGUAGE DataKinds #-} +{-# LANGUAGE GADTs #-} +{-# LANGUAGE TypeFamilies #-} +{-# LANGUAGE UndecidableInstances #-} + +module Data.TypeLevel.Path ( + Path' (..), + Path, + PathSpec (..), + PathType, + SOP, + ProdOnly, + SumOnly, + SumPath, + ProdPath, + FactorsOf, + FactorOfF, + KnownPath (..), + PositionOf, + PositionsOf, + PositionOfF, + PositionOf', + module GHC.Generics, +) where + +import Data.Kind +import Data.Proxy +import Data.TypeLevel.Applicative +import Data.TypeLevel.Function +import GHC.Generics hiding (S) +import GHC.TypeLits + +data PathSpec = PathType Bool Bool + deriving (Read, Show, Eq, Ord) + +type PathType = 'PathType + +type SOP = 'PathType 'True 'True + +type ProdOnly = 'PathType 'False 'True + +type SumOnly = 'PathType 'True 'False + +type SumPath = Path' SumOnly + +type ProdPath = Path' ProdOnly + +type Path = Path' SOP + +data Path' (t :: PathSpec) c (f :: Type -> Type) where + K :: Path' t c (K1 i c) + M :: Path' t c f -> Path' t c (M1 i x f) + InL :: Path' (PathType 'True b) c f -> Path' (PathType 'True b) c (f :+: g) + InR :: Path' (PathType 'True b) c g -> Path' (PathType 'True b) c (f :+: g) + GoL :: Path' (PathType b 'True) c f -> Path' (PathType b 'True) c (f :*: g) + GoR :: Path' (PathType b 'True) c g -> Path' (PathType b 'True) c (f :*: g) + +deriving instance Show (Path' t c f) + +type family PositionOf' t a f :: Maybe (Path' t a f) where + PositionOf' t a f = PositionOfF Maybe t a f + +type family PositionsOf t a f :: [Path' t a f] where + PositionsOf t a f = PositionOfF [] t a f + +type PositionOfF :: + forall (p :: Type -> Type) -> + forall (t :: PathSpec) -> + forall (a :: Type) -> + forall (f :: Type -> Type) -> + p (Path' t a f) +type family PositionOfF p t (a :: Type) (f :: Type -> Type) :: p (Path' t a f) where + PositionOfF p _ a (K1 i a) = Pure 'K + PositionOfF p t a (M1 i c f) = Con 'M <$> PositionOfF p t a f + PositionOfF p (PathType 'True b) a (l :+: r) = + (Con 'InL <$> PositionOfF p (PathType 'True b) a l) + <|> (Con 'InR <$> PositionOfF p (PathType 'True b) a r) + PositionOfF p (PathType b 'True) a (l :*: r) = + (Con 'GoL <$> PositionOfF p (PathType b 'True) a l) + <|> (Con 'GoR <$> PositionOfF p (PathType b 'True) a r) + PositionOfF _ _ _ _ = Empty + +class KnownPath t c f (p :: Path' t c f) where + pathVal :: proxy p -> Path' t c f + +instance KnownPath t c (K1 i c) 'K where + pathVal _ = K + +instance (KnownPath t a f p) => KnownPath t a (M1 i c f) ('M p) where + pathVal _ = M $ pathVal (Proxy :: Proxy p) + +instance + {-# OVERLAPPING #-} + (KnownPath (PathType 'True b) a l p) => + KnownPath (PathType 'True b) a (l :+: r) ('InL p) + where + pathVal _ = InL $ pathVal @(PathType 'True b) (Proxy :: Proxy p) + +instance + {-# OVERLAPPING #-} + (KnownPath (PathType 'True b) a r p) => + KnownPath (PathType 'True b) a (l :+: r) ('InR p) + where + pathVal _ = InR $ pathVal @(PathType 'True b) (Proxy :: Proxy p) + +instance + (KnownPath (PathType b 'True) a l p) => + KnownPath (PathType b 'True) a (l :*: r) ('GoL p) + where + pathVal _ = GoL $ pathVal @(PathType b 'True) (Proxy :: Proxy p) + +instance + (KnownPath (PathType b 'True) a r p) => + KnownPath (PathType b 'True) a (l :*: r) ('GoR p) + where + pathVal _ = GoR $ pathVal @(PathType b 'True) (Proxy :: Proxy p) + +type PositionOf :: + forall (t :: PathSpec) -> + forall (a :: Type) -> + forall (b :: Type) -> + Maybe (Path' t a (Rep b)) +type family PositionOf t a b :: Maybe (Path' t a (Rep b)) where + PositionOf t a b = PositionOf' t a (Rep b) + +type FactorsOf a = FactorOfF [] (Rep a) + +type family FactorOfF p a :: p Type where + FactorOfF p (K1 i c) = Pure c + FactorOfF p U1 = Empty + FactorOfF p (M1 i c f) = FactorOfF p f + FactorOfF p (f :*: g) = FactorOfF p f <|> FactorOfF p g + FactorOfF p (f :+: g) = + TypeError ('Text "Cannot define a factor of sum types") diff --git a/elgenerics-containers/src/Data/Union.hs b/elgenerics-containers/src/Data/Union.hs new file mode 100644 index 0000000..3a7cf21 --- /dev/null +++ b/elgenerics-containers/src/Data/Union.hs @@ -0,0 +1,140 @@ +{-# LANGUAGE AllowAmbiguousTypes #-} +{-# LANGUAGE DataKinds #-} +{-# LANGUAGE DefaultSignatures #-} +{-# LANGUAGE GADTs #-} +{-# LANGUAGE TemplateHaskell #-} +{-# LANGUAGE TypeFamilies #-} +{-# LANGUAGE UndecidableInstances #-} +{-# OPTIONS_GHC -fplugin GHC.TypeLits.KnownNat.Solver #-} +{-# OPTIONS_GHC -funbox-strict-fields -Wno-orphans #-} + +module Data.Union ( + Union, + KnownTyList, + inject, + project, + projectEither, + Inhabited (..), + IsSum (..), + decompose, + fromSingleton, + absurd, + weaken, + elimAll, +) where + +import Data.Coerce +import Data.Constraint.Operators +import Data.Functor.Identity +import Data.Inhabited +import Data.Kind (Type) +import Data.Membership +import Data.Proxy +import Data.TypeLevel.List +import Data.Union.HigherKinded qualified as HK +import Data.Union.Internal qualified as HK +import GHC.Generics +import Unsafe.Coerce + +type Union = HK.Union Identity + +decompose :: forall a as. Union (a ': as) -> Either (Union as) a +{-# INLINE decompose #-} +decompose = coerce $ HK.decompose @Identity @a @as + +inject :: forall a as. (Member a as) => a -> Union as +{-# INLINE [1] inject #-} +inject = HK.inject . Identity + +absurd :: Union '[] -> a +{-# INLINE absurd #-} +absurd = HK.absurd + +project :: forall a as. (Member a as) => Union as -> Maybe a +{-# INLINE project #-} +project = coerce @(Maybe (Identity a)) . HK.project + +projectEither :: + forall a as. + (Member a as) => + Union as -> + Either (Union (DeleteOne a as)) a +{-# INLINE projectEither #-} +projectEither = coerce $ HK.projectEither @Identity @a @as + +fromSingleton :: forall a. Union '[a] -> a +{-# INLINE fromSingleton #-} +fromSingleton = coerce $ HK.fromSingleton @Identity @a + +weaken :: Union as -> Union (a ': as) +{-# INLINE weaken #-} +weaken = HK.weaken + +class IsSum c where + type Summands c :: [Type] + type Summands c = GSums (Rep c) + toOpenUnion :: c -> Union (Summands c) + default toOpenUnion :: + (Generic c, GIsSum (Rep c), GSums (Rep c) ~ Summands c) => + c -> + Union (Summands c) + toOpenUnion = gToUnion . from + fromOpenUnion :: Union (Summands c) -> c + default fromOpenUnion :: + (Generic c, GIsSum (Rep c), GSums (Rep c) ~ Summands c) => + Union (Summands c) -> + c + fromOpenUnion = to . gFromUnion + +instance IsSum (Either a b) + +class GIsSum f where + type GSums f :: [Type] + gToUnion :: f () -> Union (GSums f) + gFromUnion :: Union (GSums f) -> f () + +instance GIsSum (K1 i c) where + type GSums (K1 i c) = '[c] + gToUnion = HK.Summand 0 + {-# INLINE gToUnion #-} + gFromUnion (HK.Summand _ v) = K1 $ unsafeCoerce v + {-# INLINE gFromUnion #-} + +shiftIdx :: Word -> Union as -> Union bs +{-# INLINE shiftIdx #-} +shiftIdx i (HK.Summand j v) = HK.Summand (i + j) v + +instance (KnownNat (Length (GSums f)), GIsSum f, GIsSum g) => GIsSum (f :+: g) where + type GSums (f :+: g) = GSums f ++ GSums g + gToUnion (L1 f) = shiftIdx 0 $ gToUnion f + gToUnion (R1 g) = + shiftIdx (fromIntegral $ natVal $ Proxy @(Length (GSums f))) $ + gToUnion g + gFromUnion (HK.Summand i v) = + let offset = fromIntegral (natVal $ Proxy @(Length (GSums f))) + in if i < offset + then L1 $ gFromUnion (HK.Summand i v) + else R1 $ gFromUnion (HK.Summand (i - offset) v) + +instance (GIsSum f) => GIsSum (M1 i c f) where + type GSums (M1 i c f) = GSums f + gToUnion = gToUnion . unM1 + gFromUnion = M1 . gFromUnion + +elimAll :: + forall c r as. + (All c as) => + (forall x. (Member x as, c x) => x -> r) -> + Union as -> + r +elimAll f (HK.Summand k v) = + withKnownNat k $ \(Proxy :: Proxy k) -> + withMembershipC @c (elemAtMembership @k @as) $ + f @(ElemAt k as) (unsafeCoerce v) + +instance + {-# OVERLAPPING #-} + (All Show as) => + Show (Union as) + where + showsPrec d = elimAll @Show (showsPrec d) diff --git a/elgenerics-containers/src/Data/Union/HigherKinded.hs b/elgenerics-containers/src/Data/Union/HigherKinded.hs new file mode 100644 index 0000000..7a255c5 --- /dev/null +++ b/elgenerics-containers/src/Data/Union/HigherKinded.hs @@ -0,0 +1,142 @@ +{-# LANGUAGE AllowAmbiguousTypes #-} +{-# LANGUAGE DataKinds #-} +{-# LANGUAGE DefaultSignatures #-} +{-# LANGUAGE GADTs #-} +{-# LANGUAGE TemplateHaskell #-} +{-# LANGUAGE TypeFamilies #-} +{-# LANGUAGE UndecidableInstances #-} +{-# OPTIONS_GHC -Wno-orphans -dcore-lint #-} +{-# OPTIONS_GHC -fobject-code #-} +{-# OPTIONS_GHC -fplugin Data.TypeLevel.List.Solver #-} +{-# OPTIONS_GHC -fplugin GHC.TypeLits.KnownNat.Solver #-} +{-# OPTIONS_GHC -funbox-strict-fields #-} + +module Data.Union.HigherKinded ( + Union, + KnownTyList, + inject, + project, + projectEither, + Inhabited (..), + decompose, + fromSingleton, + absurd, + weaken, + elimAll, +) where + +import Control.DeepSeq +import Data.Constraint.Operators +import Data.HList.HigherKinded +import Data.Inhabited +import Data.Membership +import Data.Proxy +import Data.Sum.Class qualified as Sum +import Data.TypeLevel.List +import Data.Union.Internal +import Data.Vector.Unboxed qualified as U +import Data.Vector.Unboxed.Deriving +import Unsafe.Coerce + +instance + (All Show (Map h as), KnownTyList as) => + Show (Union h as) + where + showsPrec d = elimAll @_ @Show (showsPrec d) + +instance (All NFData (Map h as), KnownTyList as) => NFData (Union h as) where + rnf = elimAll @_ @NFData rnf + +decompose :: Union h (a ': as) -> Either (Union h as) (h a) +{-# INLINE decompose #-} +decompose (Summand i v) = + if i == 0 + then Right $ unsafeCoerce v + else Left $ Summand (i - 1) v + +inject :: forall h a as. (Member a as) => h a -> Union h as +{-# INLINE [1] inject #-} +inject a = Summand (idx @a @as) a + +idx :: forall a as. (Member a as) => Word +idx = fromIntegral $ natVal $ Proxy @(Index a as) + +absurd :: Union h '[] -> a +{-# INLINE absurd #-} +absurd = undefined + +project :: forall h a as. (Member a as) => Union h as -> Maybe (h a) +{-# INLINE project #-} +project (Summand i v) = + if i == idx @a @as + then Just $ unsafeCoerce v + else Nothing + +projectEither :: + forall h a as. + (Member a as) => + Union h as -> + Either (Union h (DeleteOne a as)) a +{-# INLINE projectEither #-} +projectEither (Summand i v) = + let n = idx @a @as + in if i == n + then Right $ unsafeCoerce v + else Left $ Summand (if i < n then i else i + 1) v + +fromSingleton :: Union h '[a] -> h a +fromSingleton (Summand _ v) = unsafeCoerce v + +weaken :: Union h as -> Union h (a ': as) +{-# INLINE weaken #-} +weaken (Summand i v) = Summand (i + 1) v + +instance (Member a as) => Sum.HasSummand (h a) (Union h as) where + inject' = inject + project' = project + +fromHList :: (Word, HList h as) -> Union h as +{-# INLINE fromHList #-} +fromHList (n, hl) = + withKnownNat n $ \k -> + Summand n $ hindex k hl + +toHList :: + forall h as. + (KnownTyList as, All Inhabited (Map h as)) => + Union h as -> + (Word, HList h as) +toHList (Summand i v) = + (,) i $ + generate @h @as $ \pk@(Proxy :: Proxy k) -> + let k = natVal pk + in withMembership (elemAtMembership @k @(Map h as)) $ + if k == fromIntegral i + then unsafeCoerce v + else inhabitant + +elimAll :: + forall h c r as. + (All c (Map h as), KnownTyList as) => + (forall x. (Member x as, c (h x)) => h x -> r) -> + Union h as -> + r +elimAll f (Summand k v) = + withKnownNat k $ \(Proxy :: Proxy k) -> + withMembershipC @c (elemAtMembership @k @(Map h as)) $ + withMembership (elemAtMembership @k @as) $ + f @(ElemAt k as) (unsafeCoerce v) + +derivingUnbox + "Union" + [t| + forall h as. + ( KnownTyList as + , All U.Unbox (Map h as) + , All Inhabited (Map h as) + ) => + Union h as -> + (Word, HList h as) + |] + [|toHList|] + [|fromHList|] diff --git a/elgenerics-containers/src/Data/Union/Internal.hs b/elgenerics-containers/src/Data/Union/Internal.hs new file mode 100644 index 0000000..965b040 --- /dev/null +++ b/elgenerics-containers/src/Data/Union/Internal.hs @@ -0,0 +1,10 @@ +{-# LANGUAGE DataKinds #-} +{-# LANGUAGE GADTs #-} +{-# OPTIONS_GHC -funbox-strict-fields #-} + +module Data.Union.Internal where + +import Data.Kind (Type) + +data Union (h :: k -> Type) (vs :: [k]) where + Summand :: !Word -> v -> Union h vs diff --git a/elgenerics-containers/test/Data/Record/Builder/HigherKinded/BottomUpSpec.hs b/elgenerics-containers/test/Data/Record/Builder/HigherKinded/BottomUpSpec.hs new file mode 100644 index 0000000..5bfe93b --- /dev/null +++ b/elgenerics-containers/test/Data/Record/Builder/HigherKinded/BottomUpSpec.hs @@ -0,0 +1,138 @@ +{-# LANGUAGE BlockArguments #-} +{-# LANGUAGE DataKinds #-} +{-# LANGUAGE DeriveAnyClass #-} +{-# LANGUAGE DerivingStrategies #-} +{-# LANGUAGE DerivingVia #-} +{-# LANGUAGE GADTs #-} +{-# LANGUAGE LambdaCase #-} +{-# LANGUAGE OverloadedLabels #-} +{-# LANGUAGE PartialTypeSignatures #-} +{-# LANGUAGE RecordWildCards #-} +{-# LANGUAGE TypeFamilies #-} +{-# LANGUAGE UndecidableInstances #-} +{-# OPTIONS_GHC -Wall -Wno-orphans -Wno-partial-type-signatures #-} + +module Data.Record.Builder.HigherKinded.BottomUpSpec where + +import Control.Arrow ( + Arrow (second), + first, + ) +import Data.DList qualified as DL +import Data.Function (on) +import Data.Functor.Const (Const (Const)) +import Data.Kind (Type) +import Data.List (nub, nubBy, sortOn) +import Data.Proxy (Proxy) +import Data.Record.Builder.HigherKinded.BottomUp ( + RecordBuilder, + build, + ) +import Data.Record.Builder.HigherKinded.BottomUp qualified as Bup +import Data.Record.Cases +import Data.Record.HigherKinded ( + Field, + OnEntry (OnEntry), + field, + foldMapRec, + fromHRecord, + fromRecord, + (:=) (..), + ) +import Data.Tagged (Tagged (Tagged)) +import Data.TypeLevel.Known ( + HasSing (promote), + Known, + SList (..), + SNat, + SomeSing (MkSomeSing), + sKnownVal', + withKnown', + withKnownNat', + ) +import Data.TypeLevel.Nat (Nat, natVal) +import Data.TypeLevel.OrdMap ( + SField ((:%::)), + SortableLabels, + sSortPermutation, + ) +import Test.QuickCheck ( + NonNegative (..), + PrintableString (..), + (===), + ) +import Test.Tasty (TestTree, testGroup) +import Test.Tasty.QuickCheck ( + tabulate, + testProperty, + ) +import Type.Reflection (Typeable, typeRep) + +type H = OnEntry (Const (Integer, String)) + +data SomeRecordBuilder where + MkRecBuilder :: + (SortableLabels ps, Known ps, Typeable ps) => + RecordBuilder H (ps :: [Field Nat Type]) -> + SomeRecordBuilder + +test_Buz0 :: TestTree +test_Buz0 = + testGroup + "Builds fixed record into native record properly" + [ testProperty "Simple" \buz0@Buz0 {..} -> + fromRecord + ( Bup.build $ + Bup.empty + Bup.&+ #ddd + := Tagged ddd + Bup.&+ #ggg + := Tagged ggg + ) + === buz0 + , testProperty "Higher-Kinded" \buz0@Buz0 {..} -> + fromHRecord @(OnEntry Maybe) @Buz0 + ( Bup.build $ + Bup.empty + Bup.&+ #ddd + := OnEntry ddd + Bup.&+ #ggg + := OnEntry ggg + ) + === buz0 + ] + +test_builder :: TestTree +test_builder = testProperty "Builds random records properly" $ + \(as0 :: [(NonNegative Integer, PrintableString)]) -> + let as = map (first getNonNegative) as0 + us = nubBy ((==) `on` fst) as + sorted = map (second getPrintableString) $ sortOn fst us + in case promote @[Nat] $ map (fromIntegral . fst) us of + MkSomeSing (slist :: SList ps) -> + case toRecordBuilder slist $ map (getPrintableString . snd) us of + MkRecBuilder builder -> + tabulate "# of Elements" [show $ length us] + $ tabulate + "# of distinct associated values" + [show $ length $ nub $ map snd us] + $ let lst = + foldMapRec + ( \(_ :: Proxy k) (_ :: Proxy l) _ (OnEntry (Const s)) -> + DL.singleton s + ) + $ build builder + in DL.toList lst === sorted + +toRecordBuilder :: SList (a :: [Nat]) -> [String] -> SomeRecordBuilder +toRecordBuilder SNil _ = MkRecBuilder Bup.empty +toRecordBuilder (:%) {} [] = error "toRecordBuilder: Could not happen!" +toRecordBuilder ((a :: SNat n) :% as) (x : xs) = + withKnownNat' a $ + case toRecordBuilder as xs of + MkRecBuilder (b0 :: RecordBuilder H ps) -> + withKnown' (sSortPermutation $ (a :%:: typeRep @Type) :% sKnownVal' @ps) $ + MkRecBuilder $ + b0 + Bup.&+ field @n + := OnEntry (Const (fromIntegral $ natVal a, x) :: Const (Integer, String) Type) diff --git a/elgenerics-containers/test/Data/Record/Builder/HigherKindedSpec.hs b/elgenerics-containers/test/Data/Record/Builder/HigherKindedSpec.hs new file mode 100644 index 0000000..17a181d --- /dev/null +++ b/elgenerics-containers/test/Data/Record/Builder/HigherKindedSpec.hs @@ -0,0 +1,55 @@ +{-# LANGUAGE BlockArguments #-} +{-# LANGUAGE DataKinds #-} +{-# LANGUAGE DeriveAnyClass #-} +{-# LANGUAGE DerivingStrategies #-} +{-# LANGUAGE DerivingVia #-} +{-# LANGUAGE GADTs #-} +{-# LANGUAGE LambdaCase #-} +{-# LANGUAGE OverloadedLabels #-} +{-# LANGUAGE PartialTypeSignatures #-} +{-# LANGUAGE RecordWildCards #-} +{-# LANGUAGE TypeFamilies #-} +{-# LANGUAGE UndecidableInstances #-} +{-# OPTIONS_GHC -Wall -Wno-orphans -Wno-partial-type-signatures #-} + +module Data.Record.Builder.HigherKindedSpec where + +import Data.Record.Builder.HigherKinded qualified as B +import Data.Record.Cases +import Data.Record.HigherKinded ( + Fields, + OnEntry (OnEntry), + fromHRecord', + fromRecord, + (:=) (..), + ) +import Data.Tagged (Tagged (Tagged)) +import Test.QuickCheck ((===)) +import Test.Tasty (TestTree, testGroup) +import Test.Tasty.QuickCheck (testProperty) + +test_Buz0 :: TestTree +test_Buz0 = + testGroup + "Builds fixed record into native record properly" + [ testProperty "Simple" \buz0@Buz0 {..} -> + fromRecord @Buz0 @(Fields Buz0) + ( B.build $ + B.empty + B.&+ #ddd + := Tagged ddd + B.&+ #ggg + := Tagged ggg + ) + === buz0 + , testProperty "Higher-Kinded" \buz0@Buz0 {..} -> + fromHRecord' + ( B.build $ + B.empty + B.&+ #ddd + := OnEntry ddd + B.&+ #ggg + := OnEntry ggg + ) + === buz0 + ] diff --git a/elgenerics-containers/test/Data/Record/Cases.hs b/elgenerics-containers/test/Data/Record/Cases.hs new file mode 100644 index 0000000..55aced6 --- /dev/null +++ b/elgenerics-containers/test/Data/Record/Cases.hs @@ -0,0 +1,98 @@ +{-# LANGUAGE DataKinds #-} +{-# LANGUAGE DeriveAnyClass #-} +{-# LANGUAGE DerivingStrategies #-} +{-# LANGUAGE DisambiguateRecordFields #-} +{-# LANGUAGE DuplicateRecordFields #-} +{-# LANGUAGE ExplicitNamespaces #-} +{-# LANGUAGE GADTs #-} +{-# LANGUAGE OverloadedLabels #-} +{-# LANGUAGE RecordWildCards #-} +{-# LANGUAGE UndecidableInstances #-} +{-# OPTIONS_GHC -fplugin Data.TypeLevel.List.Overloaded #-} + +module Data.Record.Cases where + +import Data.Kind (Type) +import Data.Record (IsRecord) +import Data.Record qualified as Simple +import Data.Record.HigherKinded ( + FromAscList, + HRecordable, + IsHRecord, + Recordable, + (:::), + ) +import Data.Record.HigherKinded qualified as HK +import Data.Type.Equality (type (~~)) +import GHC.Generics (Generic) +import GHC.TypeLits (Symbol) +import Test.QuickCheck (Arbitrary (..), genericShrink) + +type AscFields1 = FromAscList '["a" ::: Int, "b" ::: Bool, "c" ::: ()] + +ascSimpleRecord1 :: Simple.Record AscFields1 +ascSimpleRecord1 = + Simple.emptyRec + Simple.&+ #a + Simple.:= 12 + Simple.&+ #b + Simple.:= False + Simple.&+ #c + Simple.:= () + +mkAscSimpleRecord1 :: Int -> Bool -> () -> Simple.Record AscFields1 +mkAscSimpleRecord1 a b c = + Simple.emptyRec + Simple.&+ #a + Simple.:= a + Simple.&+ #b + Simple.:= b + Simple.&+ #c + Simple.:= c + +newtype Foo a = Foo {unFoo :: Simple.Record '["a" ::: Int, "b" ::: a, "c" ::: ()]} + deriving (Generic, Show, Eq) + deriving anyclass (IsRecord) + +deriving anyclass instance IsHRecord HK.STagged (Foo a) + +data Bar c = Bar {a :: Int, b :: Bool, c :: c} + deriving (Generic, Show, Eq) + +deriving anyclass instance (Recordable (Bar c)) => IsRecord (Bar c) + +data Buz a = Buz {buzX :: Maybe Int, buzY :: Maybe Bool, buzZ :: a} + deriving (Generic, Show, Eq, Ord) + +deriving anyclass instance (Recordable (Buz a)) => IsRecord (Buz a) + +deriving anyclass instance + IsHRecord (HK.OnEntry Maybe :: Symbol -> Type -> Type) (Buz (Maybe a)) + +instance (Arbitrary a) => Arbitrary (Buz a) where + arbitrary = Buz <$> arbitrary <*> arbitrary <*> arbitrary + shrink = genericShrink + +data Buz0 = Buz0 {ddd :: Maybe Int, ggg :: Maybe Bool} + deriving (Generic, Show, Eq, Ord) + deriving anyclass (IsRecord) + +deriving anyclass instance + IsHRecord (HK.OnEntry Maybe :: Symbol -> Type -> Type) Buz0 + +instance Arbitrary Buz0 where + arbitrary = Buz0 <$> arbitrary <*> arbitrary + shrink = genericShrink + +data MyHKD h = MyHKD {hInt :: h Int, hBool :: h Bool} + deriving (Generic) + +deriving instance (Recordable (MyHKD h)) => IsRecord (MyHKD h) + +deriving stock instance (Show (h Int), Show (h Bool)) => Show (MyHKD h) + +deriving anyclass instance + ( HRecordable (HK.OnEntry h :: Symbol -> Type -> Type) (MyHKD h) + , HK.OnEntry h ~~ (h' :: Symbol -> Type -> Type) + ) => + IsHRecord h' (MyHKD h) diff --git a/elgenerics-containers/test/Data/Record/Failures.hs b/elgenerics-containers/test/Data/Record/Failures.hs new file mode 100644 index 0000000..1e0ca80 --- /dev/null +++ b/elgenerics-containers/test/Data/Record/Failures.hs @@ -0,0 +1,31 @@ +{-# LANGUAGE DataKinds #-} +{-# LANGUAGE GADTs #-} +{-# LANGUAGE OverloadedLabels #-} +{-# LANGUAGE TemplateHaskell #-} +{-# OPTIONS_GHC -fdefer-type-errors -Wno-deferred-type-errors #-} + +module Data.Record.Failures where + +import Control.Lens +import Data.Record qualified as Simple +import Data.Record.Cases +import Data.Record.HigherKinded qualified as HK +import Data.Tagged (Tagged (..)) + +typeMismatch :: Maybe Bool +typeMismatch = unTagged <$> HK.projField @"a" ascSimpleRecord1 + +mismatchUpdate :: Char -> Simple.Record AscFields1 -> Simple.Record AscFields1 +mismatchUpdate ch = HK.recFieldTraversal @"a" .~ Tagged ch + +unmergeable :: Simple.Record AscFields1 +unmergeable = + Simple.emptyRec + Simple.&+ #a + Simple.:= (12 :: Int) + Simple.&+ #b + Simple.:= True + Simple.&+ #c + Simple.:= () + Simple.&+ #a + Simple.:= (42 :: Int) diff --git a/elgenerics-containers/test/Data/Record/HigherKindedSpec.hs b/elgenerics-containers/test/Data/Record/HigherKindedSpec.hs new file mode 100644 index 0000000..8be1ad6 --- /dev/null +++ b/elgenerics-containers/test/Data/Record/HigherKindedSpec.hs @@ -0,0 +1,497 @@ +{-# LANGUAGE AllowAmbiguousTypes #-} +{-# LANGUAGE BlockArguments #-} +{-# LANGUAGE DataKinds #-} +{-# LANGUAGE DeriveAnyClass #-} +{-# LANGUAGE DerivingStrategies #-} +{-# LANGUAGE DerivingVia #-} +{-# LANGUAGE GADTs #-} +{-# LANGUAGE LambdaCase #-} +{-# LANGUAGE OverloadedLabels #-} +{-# LANGUAGE OverloadedStrings #-} +{-# LANGUAGE PartialTypeSignatures #-} +{-# LANGUAGE RecordWildCards #-} +{-# LANGUAGE TypeFamilies #-} +{-# LANGUAGE UndecidableInstances #-} +{-# OPTIONS_GHC -Wall -Wno-orphans -Wno-partial-type-signatures #-} +{-# OPTIONS_GHC -fplugin Data.Record.Plugin #-} +{-# OPTIONS_GHC -fplugin Data.TypeLevel.List.Solver #-} +{-# OPTIONS_GHC -fplugin GHC.TypeLits.KnownNat.Solver #-} +{-# OPTIONS_GHC -fplugin GHC.TypeLits.Presburger #-} +{-# OPTIONS_GHC -fplugin-opt Data.Record.Plugin:MyRecord #-} +{-# OPTIONS_GHC -fplugin-opt GHC.TypeLits.Presburger:allow-negated-numbers #-} + +module Data.Record.HigherKindedSpec where + +import Control.DeepSeq (NFData, force) +import Control.Exception ( + TypeError (TypeError), + evaluate, + try, + ) +import Control.Lens (Identity, (&), (.~), (^.), (^?)) +import Data.Kind +import Data.Proxy +import Data.Record.Cases +import Data.Record.Failures ( + mismatchUpdate, + typeMismatch, + unmergeable, + ) +import Data.Record.HigherKinded +import Data.Record.HigherKinded qualified as HK +import Data.Tagged +import Data.Text qualified as T +import Data.TypeLevel.Known +import Data.TypeLevel.Nat +import Data.Vector qualified as V +import Data.Void (Void) +import GHC.Generics +import GHC.TypeLits (Symbol) +import Test.QuickCheck +import Test.Tasty +import Test.Tasty.HUnit +import Test.Tasty.QuickCheck +import Type.Reflection + +data Test1 = Test1 + { foo :: Integer + , bar :: Bool + , buz :: Maybe String + , quux :: Either Ordering Int + , dablin :: V.Vector Double + } + deriving (Generic, Typeable, Eq, Show, Ord) + deriving anyclass (IsRecord, IsHRecord STagged) + +goldenTest1_raw :: Test1 +goldenTest1_raw = + Test1 + { foo = (12 :: Integer) + , bar = True + , buz = Just "dear" + , quux = Left LT + , dablin = V.replicate 50 pi + } + +goldenTest1_extrec :: Record STagged (Fields Test1) +goldenTest1_extrec = toRecord $ goldenTest1_raw + +proxyType :: a -> Proxy a +proxyType = const Proxy + +instance Arbitrary Test1 where + arbitrary = + Test1 + <$> arbitrary + <*> arbitrary + <*> arbitrary + <*> arbitrary + <*> (V.fromList <$> arbitrary) + +deriving newtype instance (Arbitrary a) => Arbitrary (Tagged s a) + +instance + (AllOM (OverC h Arbitrary) dic) => + Arbitrary (Record h dic) + where + arbitrary = + generateRecM $ \(_ :: Proxy l) (_ :: Proxy v) _ -> + arbitrary @(h l v) + +type TypeLabelledFields = + FromList + '[ String ::: 2 + , Int ::: 4 + , Maybe Bool ::: 3 + , () ::: 0 + , Ordering ::: 5 + ] + +data Vec a n where + VNil :: Vec a 0 + (:<) :: a -> Vec a n -> Vec a (1 + n) + +infixr 9 :< + +deriving instance Typeable Vec + +deriving instance (Show a) => Show (Vec a n) + +deriving instance (Eq a) => Eq (Vec a n) + +tyLabRec :: Record Vec TypeLabelledFields +tyLabRec = castRecord tyLabRec' + +type Zero = 0 + +type RawTypeFields = + ( (Ordering ::: 5) + <: (Maybe Bool ::: 3) + <: (Int ::: 4) + <: (String ::: 2) + <: Singleton () 0 + ) + +fiveOrderings :: Vec Ordering 5 +fiveOrderings = GT :< EQ :< LT :< EQ :< GT :< VNil + +type FiveOrds = Vec Ordering 5 + +tyLabRec' :: Record Vec RawTypeFields +tyLabRec' = + singletonRec (VNil @()) + &+ field @String + := ("foo" :< "buz" :< VNil) + &+ field @Int + := (42 :< 5 :< 9 :< (-3) :< VNil) + &+ field @(Maybe Bool) + := (Just True :< Nothing :< Just False :< VNil) + &+ field @Ordering + := fiveOrderings + +tyLabRecSimple :: Record Proxy2 RawTypeFields +tyLabRecSimple = + singletonRec (Proxy2 @() @0) + &+ field @String + := Proxy2 + &+ field @Int + := Proxy2 + &+ field @(Maybe Bool) + := Proxy2 + &+ field @Ordering + := Proxy2 + +type VecRep a n = + D1 + ('MetaData "Vec" "Data.Record.HigherKindedSpec" "elgenerics" 'False) + ( C1 + ('MetaCons "MkVec" 'PrefixI 'False) + (VecRepAuxN (n === 0) (n === 1) a n) + ) + +type NoLab = + S1 ('MetaSel 'Nothing 'NoSourceUnpackedness 'NoSourceStrictness 'DecidedLazy) + +type family VecRepAuxN is0 is1 a n :: Type -> Type where + VecRepAuxN 'True _ _a 0 = U1 + VecRepAuxN 'False 'True a 1 = NoLab (Rec0 a) + VecRepAuxN 'False 'False a n = + NoLab (Rec0 a) + :*: VecRepAuxN ((n - 1) === 0) ((n - 1) === 1) a (n - 1) + +data Proxy2 a b = Proxy2 + deriving (Read, Show, Eq, Ord, Typeable, Generic) + +toVecRepAux :: + forall a n x. + (KnownNat n) => + Vec a n -> + VecRepAuxN (n === 0) (n === 1) a n x +toVecRepAux = + case sTestEquality sn (sKnownVal' @0) of + Equal -> const U1 + NonEqual -> + case sTestEquality sn (sKnownVal' @1) of + Equal -> \case + (a :< VNil) -> M1 $ K1 a + (_ :< _ :< _) -> error "impossible" + NonEqual -> \case + (a :< as) -> + M1 (K1 a) :*: toVecRepAux @a @(n - 1) as + where + sn = sKnownVal' @n + +fromVecRepAux :: forall a n x. (KnownNat n) => VecRepAuxN (n === 0) (n === 1) a n x -> Vec a n +fromVecRepAux = + case sTestEquality sn (sKnownVal' @0) of + Equal -> const VNil + NonEqual -> + case sTestEquality sn (sKnownVal' @1) of + Equal -> \case + M1 (K1 x) -> x :< VNil + NonEqual -> \case + (M1 (K1 a) :*: r) -> + withKnownNat' (sn %- sKnownVal' @1) $ + a :< fromVecRepAux @a @(n - 1) r + where + sn = sKnownVal' @n + +type ThreeBools = Vec Bool 3 + +instance (KnownNat n) => Generic (Vec a n) where + type Rep (Vec a n) = VecRep a n + from = M1 . M1 . toVecRepAux + to = fromVecRepAux . unM1 . unM1 + +generateVecA :: + forall f a n. + (Applicative f, KnownNat n) => + (Int -> f a) -> + f (Vec a n) +generateVecA fa = go (sKnownVal' @0) + where + sn = sKnownVal' @n + go :: forall m. SNat m -> f (Vec a (n - m)) + go sm = withKnownNat' sm $ + case sTestEquality sm sn of + Equal -> pure VNil + NonEqual -> + (:<) + <$> fa (fromIntegral $ natVal sm) + <*> go (sm %+ sKnownVal' @1) + +replicateVecA :: forall f a n. (Applicative f, KnownNat n) => f a -> f (Vec a n) +replicateVecA fa = go (sKnownVal' @0) + where + sn = sKnownVal' @n + go :: forall m. SNat m -> f (Vec a (n - m)) + go sm = + case sTestEquality sm sn of + Equal -> pure VNil + NonEqual -> (:<) <$> fa <*> withKnownNat' sm (go $ sm %+ sKnownVal' @1) + +replicateVec' :: forall a n. (KnownNat n) => a -> Vec a n +replicateVec' a = go (sKnownVal' @n) + where + go :: forall m. SNat m -> Vec a m + go sm = + case sTestEquality sm (sKnownVal' @0) of + Equal -> VNil + NonEqual -> a :< withKnownNat' sm (go $ sm %- sKnownVal' @1) + +instance (KnownNat n, Arbitrary a) => Arbitrary (Vec a n) where + arbitrary = replicateVecA arbitrary + +instance (Arbitrary a) => Arbitrary (V.Vector a) where + arbitrary = V.fromList <$> arbitrary + +test_generics :: TestTree +test_generics = + testGroup + "Generics" + [ testGroup + "to . from == id" + [ testProperty "Fields Test1" $ \rec1 -> + to (from (rec1 :: Record STagged (Fields Test1))) + === rec1 + , testProperty "Record Vec TypeLablledFields" $ \rec1 -> + to (from (rec1 :: Record Vec TypeLabelledFields)) + === rec1 + , testProperty "Record Vec RawTypeFields" $ \rec1 -> + to (from (rec1 :: Record Vec RawTypeFields)) + === rec1 + ] + ] + +test_symbol_rec :: TestTree +test_symbol_rec = + testGroup + "Symbol-labelled rank-1 record" + [ testProperty "fromRecord . toRecord == id" $ + \t1@Test1 {} -> + fromRecord (toRecord t1) == t1 + , testProperty "toRecord . fromRecord == castRecord" $ + \rec1 -> + toRecord (fromRecord @Test1 @(Fields Test1) rec1) == castRecord rec1 + , testProperty "fromHRecord . toHRecord == id" $ + \t1@Test1 {} -> + fromHRecord (toHRecord @STagged t1) == t1 + , testProperty "toHRecord . fromHRecord == castRecord" $ + \rec1 -> + toHRecord (fromHRecord @STagged @Test1 @(Fields Test1) rec1) == castRecord rec1 + , testProperty "HKD-like conversion" \hInt hBool -> + let hkd = MyHKD {..} + ext = + toHRecord @(HK.OnEntry Identity :: Symbol -> Type -> Type) + hkd + in ext + ^. recField #hInt + === OnEntry hInt + .&&. ext + ^. recField #hBool + === OnEntry hBool + ] + +fieldNotFound :: Maybe a +fieldNotFound = unTagged <$> projField @"z" ascSimpleRecord1 + +test_projField :: TestTree +test_projField = + testGroup + "projField" + [ testCase "Should return Nothing for non-existent field" do + fieldNotFound @?= (Nothing :: Maybe Int) + fieldNotFound @?= (Nothing :: Maybe Bool) + fieldNotFound @?= (Nothing :: Maybe String) + , testCase "Should throw type-error when the field type mismatched" do + shouldThrowTypeMismatch (Just "a") typeMismatch + ] + +test_IsHRecord :: TestTree +test_IsHRecord = + testGroup + "IsHRecord" + [ testProperty "Handles specialised instance well (Buz)" $ + \(buz :: Buz (Maybe String)) -> + tabulate + "Maybe cons" + [chkMaybe $ buzX buz, chkMaybe $ buzY buz, chkMaybe $ buzZ buz] + $ let toRec = toHRecord @(HK.OnEntry Maybe :: Symbol -> Type -> Type) + in buz + === fromHRecord (toRec buz) + .&&. conjoin + [ toRec buz ^. HK.recField #buzX === OnEntry (buzX buz) + , toRec buz ^. HK.recField #buzY === OnEntry (buzY buz) + , toRec buz ^. HK.recField #buzZ === OnEntry (buzZ buz) + ] + , testProperty "Handles specialised instance well (Buz0)" $ + \(buz :: Buz0) -> + tabulate + "Maybe cons" + [chkMaybe $ ddd buz, chkMaybe $ ggg buz] + $ buz + === fromHRecord @(HK.OnEntry Maybe) @Buz0 + ( HK.emptyRec + HK.&+ #ddd + := OnEntry (ddd buz) + HK.&+ #ggg + := OnEntry (ggg buz) + ) + .&&. let recs = toHRecord @(HK.OnEntry Maybe :: Symbol -> Type -> Type) buz + in conjoin + [ recs ^. recField #ddd === OnEntry (ddd buz) + , recs ^. recField #ggg === OnEntry (ggg buz) + ] + ] + +chkMaybe :: Maybe a -> String +chkMaybe Just {} = "Just" +chkMaybe Nothing {} = "Nothing" + +test_mergeRec :: TestTree +test_mergeRec = + testGroup + "mergeRec" + [ testProperty "from record-test" $ + \a c d g -> + let r = + HK.mergeRec + ( HK.emptyRec @Symbol @Type @(HK.OnEntry' Symbol Maybe) + HK.&+ #ccc + := HK.OnEntry (c :: Maybe Int) + HK.&+ #ggg + := HK.OnEntry (g :: Maybe Bool) + ) + ( HK.emptyRec @Symbol @Type @(HK.OnEntry' Symbol Maybe) + HK.&+ #aaa + := HK.OnEntry (a :: Maybe Bool) + HK.&+ #ddd + := HK.OnEntry (d :: Maybe ()) + ) + in conjoin + [ r ^. recField #aaa === OnEntry a + , r ^. recField #ccc === OnEntry c + , r ^. recField #ddd === OnEntry d + , r ^. recField #ggg === OnEntry g + ] + , testProperty + "complex" + \a b c d e g -> + let r = + HK.mergeRec + ( HK.singletonRec (MyDep (sKnownVal' @"eee") (e :: String)) + HK.&+ #ccc + := MyDep sKnownVal' (c :: Int) + HK.&+ #ggg + := MyDep sKnownVal' (g :: Maybe Bool) + ) + ( HK.emptyRec + HK.&+ #aaa + := MyDep sKnownVal' (a :: Bool) + HK.&+ #ddd + := MyDep sKnownVal' (d :: Maybe ()) + HK.&+ #bbb + := MyDep sKnownVal' (b :: [Int]) + ) + in conjoin + [ r ^. recField #aaa === MyDep sKnownVal' a + , r ^. recField #bbb === MyDep sKnownVal' b + , r ^. recField #ccc === MyDep sKnownVal' c + , r ^. recField #ddd === MyDep sKnownVal' d + , r ^. recField #eee === MyDep sKnownVal' e + , r ^. recField #ggg === MyDep sKnownVal' g + ] + , testCase "Rejects non-disjoint merging" do + eith <- try $ evaluate $ force unmergeable + case eith of + Left te@(TypeError msg) + | "OverlappingKey \"a\"" `T.isInfixOf` T.pack msg -> + pure () + | otherwise -> + assertFailure $ + "Overlapping key exception expected, but got another type error:\n" + <> show te + Right val -> + assertFailure $ + "Type error expected, but got: " + <> show val + ] + +data MyDep k n = MyDep (SSymbol k) n + deriving (Show, Eq, Ord, Typeable, Generic) + +test_recFieldTraversal :: TestTree +test_recFieldTraversal = + testGroup + "recFieldTraversal" + [ testCase "Accessing non-existent field results in Nothing" do + ascSimpleRecord1 ^? HK.recFieldTraversal @"d" @Bool @?= Nothing + ascSimpleRecord1 ^? HK.recFieldTraversal @"d" @Int @?= Nothing + ascSimpleRecord1 ^? HK.recFieldTraversal @"d" @String @?= Nothing + , testCase "Mutating non-existent field results in identity" do + (ascSimpleRecord1 & HK.recFieldTraversal @"d" @Bool .~ Tagged False) + @?= ascSimpleRecord1 + (ascSimpleRecord1 & HK.recFieldTraversal @"d" @Int .~ Tagged 12) + @?= ascSimpleRecord1 + (ascSimpleRecord1 & HK.recFieldTraversal @"d" @Void .~ Tagged undefined) + @?= ascSimpleRecord1 + , testProperty "Mutating existent field with expected type updates properly" $ + \a a' b c -> + let r = mkAscSimpleRecord1 a b c + in (r & HK.recFieldTraversal @"a" .~ Tagged a') + === mkAscSimpleRecord1 a' b c + , testProperty + "Mutating existent field with wrong type results in type error" + \a a' b c -> + let r = mkAscSimpleRecord1 a b c + in ioProperty $ shouldThrowTypeMismatch (Just "a") $ mismatchUpdate a' r + ] + +shouldThrowTypeMismatch :: + (NFData a, Show a) => + Maybe String -> + a -> + Assertion +shouldThrowTypeMismatch mlab a = do + eith <- try $ evaluate $ force a + case eith of + Left te@(TypeError msg) + | let tmsg = T.pack msg + , (_, lft) <- T.breakOn "A label:" tmsg + , not $ T.null lft + , maybe + True + ( \lbl -> + let rest = T.strip $ T.drop 8 lft + in T.pack (show lbl) `T.isPrefixOf` rest + ) + mlab + , "must be associated with a type" `T.isInfixOf` lft -> + pure () + | otherwise -> + assertFailure $ + "Type mismatch error for value must be thrown, but got:" + <> show te + Right p -> + assertFailure $ + "Type error expected, but got: " <> show p diff --git a/elgenerics-containers/test/Data/Record/PluginSpec.hs b/elgenerics-containers/test/Data/Record/PluginSpec.hs new file mode 100644 index 0000000..aba822f --- /dev/null +++ b/elgenerics-containers/test/Data/Record/PluginSpec.hs @@ -0,0 +1,39 @@ +{-# LANGUAGE BlockArguments #-} +{-# LANGUAGE DataKinds #-} +{-# LANGUAGE OverloadedLabels #-} +{-# LANGUAGE RecordWildCards #-} +{-# OPTIONS_GHC -dcore-lint #-} +{-# OPTIONS_GHC -fplugin Data.Record.Plugin #-} +{-# OPTIONS_GHC -fplugin-opt Data.Record.Plugin:MyRecord #-} + +module Data.Record.PluginSpec where + +import Control.Lens ((^.)) +import Data.Record (Record, fieldL, (:::)) +import Data.TypeLevel.OrdMap (FromAscList) +import Test.Tasty (TestTree) +import Test.Tasty.HUnit (testCase, (@?=)) +import Test.Tasty.QuickCheck (conjoin, testProperty, (===)) + +type Record1 = Record (FromAscList '["a" ::: Int, "b" ::: Bool, "c" ::: ()]) + +record :: Record1 +record = MyRecord {a = 42 :: Int, b = False, c = ()} + +test_RecordPlugin_Cons :: TestTree +test_RecordPlugin_Cons = + testCase "Constructor gives an expected result" do + record ^. fieldL #a @?= (42 :: Int) + record ^. fieldL #b @?= False + record ^. fieldL #c @?= () + +test_Record_Random :: TestTree +test_Record_Random = testProperty "Randomly generated field cons" $ + \int p unit -> + let r :: Record1 + r = MyRecord {a = int :: Int, b = p :: Bool, c = unit :: ()} + in conjoin + [ r ^. fieldL #a === int + , r ^. fieldL #b === p + , r ^. fieldL #c === unit + ] diff --git a/elgenerics-containers/test/Data/RecordSpec.hs b/elgenerics-containers/test/Data/RecordSpec.hs new file mode 100644 index 0000000..edb9e87 --- /dev/null +++ b/elgenerics-containers/test/Data/RecordSpec.hs @@ -0,0 +1,40 @@ +{-# LANGUAGE BlockArguments #-} +{-# LANGUAGE DataKinds #-} +{-# LANGUAGE OverloadedStrings #-} + +module Data.RecordSpec where + +import Data.Record (IsRecord (fromRecord), toRecord) +import Data.Record.Cases +import Data.Record.HigherKinded qualified as HK +import Test.Tasty +import Test.Tasty.HUnit (testCase, (@?=)) +import Test.Tasty.QuickCheck (testProperty, (.&&.), (===)) + +test_IsRecord_IsHRecord_newtype :: TestTree +test_IsRecord_IsHRecord_newtype = + testCase "IsRecord/IsHRecord works properly for newtyped simple record" do + let fromRecorded = fromRecord ascSimpleRecord1 + fromHReced = HK.fromHRecord ascSimpleRecord1 + directFoo = Foo @Bool ascSimpleRecord1 + fromRecorded @?= directFoo + fromRecorded @?= fromHReced + +test_IsRecord_IsHRecord_newtype_randomised :: TestTree +test_IsRecord_IsHRecord_newtype_randomised = + testProperty + "IsRecord/IsHRecord works properly for newtyped simple record (radom)" + $ \x y z -> + let fromRecorded = fromRecord $ mkAscSimpleRecord1 x y z + fromHReced = HK.fromHRecord $ mkAscSimpleRecord1 x y z + directFoo = Foo @Bool $ mkAscSimpleRecord1 x y z + in fromRecorded === directFoo + .&&. fromRecorded === fromHReced + +test_nativeRecords :: TestTree +test_nativeRecords = testProperty + "Conversion b/w native records" + \x y z -> + let ext = mkAscSimpleRecord1 x y z + bar = Bar x y z + in ext === toRecord bar .&&. fromRecord ext === bar diff --git a/elgenerics-containers/test/Spec.hs b/elgenerics-containers/test/Spec.hs new file mode 100644 index 0000000..327adf4 --- /dev/null +++ b/elgenerics-containers/test/Spec.hs @@ -0,0 +1 @@ +{-# OPTIONS_GHC -F -pgmF tasty-discover -optF --tree-display #-} diff --git a/elgenerics-known/.gitignore b/elgenerics-known/.gitignore new file mode 100644 index 0000000..c368d45 --- /dev/null +++ b/elgenerics-known/.gitignore @@ -0,0 +1,2 @@ +.stack-work/ +*~ \ No newline at end of file diff --git a/elgenerics-known/ChangeLog.md b/elgenerics-known/ChangeLog.md new file mode 100644 index 0000000..1a3229c --- /dev/null +++ b/elgenerics-known/ChangeLog.md @@ -0,0 +1,3 @@ +# Changelog for elgenerics-known + +## Unreleased changes diff --git a/elgenerics-known/LICENSE b/elgenerics-known/LICENSE new file mode 100644 index 0000000..de78212 --- /dev/null +++ b/elgenerics-known/LICENSE @@ -0,0 +1,30 @@ +Copyright DeepFlow, Inc. (c) 2019 + +All rights reserved. + +Redistribution and use in source and binary forms, with or without +modification, are permitted provided that the following conditions are met: + + * Redistributions of source code must retain the above copyright + notice, this list of conditions and the following disclaimer. + + * Redistributions in binary form must reproduce the above + copyright notice, this list of conditions and the following + disclaimer in the documentation and/or other materials provided + with the distribution. + + * Neither the name of DeepFlow, Inc. nor the names of other + contributors may be used to endorse or promote products derived + from this software without specific prior written permission. + +THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS +"AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT +LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR +A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT +OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, +SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT +LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, +DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY +THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT +(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE +OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. diff --git a/elgenerics-known/README.md b/elgenerics-known/README.md new file mode 100644 index 0000000..aecac38 --- /dev/null +++ b/elgenerics-known/README.md @@ -0,0 +1,16 @@ +# `elgenerics-known` + +A battle-tested dependently-typed programming library in Haskell with various type-level containers and plugins. +See [monorepo's README](https://github.com/deepflowinc/elgenerics/README.md) for more details. + +## Contributing + +Please feel free to open an issue, but also please search for existing issues to check if there already is a similar one. + +See [CONTRIBUTING.md][CONTRIBUTING] for more details. + +[CONTRIBUTING]: https://github.com/deepflowinc/elgenerics/blob/master/CONTRIBUTING.md + +## Copyright + +(c) 2019-present, DeepFlow Inc. diff --git a/elgenerics-known/Setup.hs b/elgenerics-known/Setup.hs new file mode 100644 index 0000000..e8ef27d --- /dev/null +++ b/elgenerics-known/Setup.hs @@ -0,0 +1,3 @@ +import Distribution.Simple + +main = defaultMain diff --git a/elgenerics-known/app/NormDefs.hs b/elgenerics-known/app/NormDefs.hs new file mode 100644 index 0000000..9d09459 --- /dev/null +++ b/elgenerics-known/app/NormDefs.hs @@ -0,0 +1,35 @@ +{-# LANGUAGE DataKinds #-} +{-# LANGUAGE TemplateHaskell #-} +{-# LANGUAGE TypeFamilies #-} +{-# LANGUAGE UndecidableInstances #-} +{-# OPTIONS_GHC -fplugin Data.TypeLevel.Normalise.Plugin #-} + +module NormDefs where + +import Data.Proxy +import Data.TypeLevel.Ord +import Data.TypeLevel.OrdMap (FromList, (:::)) +import Data.TypeLevel.Typeable +import Data.Typeable +import GHC.Generics (Generic) + +data FTags = A | B | C | D | E + deriving (Generic, Show, Typeable) + +type A = 'A + +type B = 'B + +type C = 'C + +type D = 'D + +type E = 'E + +deriveTypeRep ''FTags + +instance POrd FTags where + type Compare l r = Compare (Proxy l) (Proxy r) + +type ADict0 a b c d e = + FromList '[E ::: a, D ::: b, C ::: c, A ::: d, B ::: e] diff --git a/elgenerics-known/app/normalise-test.hs b/elgenerics-known/app/normalise-test.hs new file mode 100644 index 0000000..1a36261 --- /dev/null +++ b/elgenerics-known/app/normalise-test.hs @@ -0,0 +1,30 @@ +{-# LANGUAGE DataKinds #-} +{-# LANGUAGE TemplateHaskell #-} +{-# LANGUAGE TypeFamilies #-} +{-# LANGUAGE UndecidableInstances #-} +{-# OPTIONS_GHC -fplugin Data.TypeLevel.Normalise.Plugin #-} + +module Main where + +import Data.TypeLevel.Normalise.Plugin +import Data.TypeLevel.OrdMap (FromList, (:::)) +import NormDefs + +type ADict a b c d e = + Normalise + (FromList '[E ::: a, D ::: b, C ::: c, A ::: d, B ::: e]) + +data Foo a b = Foo + +type OneTwoDict = ADict0 1 2 3 4 5 + +type TyDict = ADict0 Int String Bool (Maybe Bool) () + +class MyMap ty + +instance MyMap TyDict + +instance MyMap OneTwoDict + +main :: IO () +main = return () diff --git a/elgenerics-known/app/simple-plugin-test.hs b/elgenerics-known/app/simple-plugin-test.hs new file mode 100644 index 0000000..02ca0c2 --- /dev/null +++ b/elgenerics-known/app/simple-plugin-test.hs @@ -0,0 +1,58 @@ +{-# LANGUAGE DataKinds #-} +{-# LANGUAGE GADTs #-} +{-# LANGUAGE TemplateHaskell #-} +{-# LANGUAGE TypeFamilies #-} +{-# LANGUAGE UndecidableInstances #-} +{-# OPTIONS_GHC -dcore-lint -fprint-explicit-foralls -fprint-explicit-kinds #-} +{-# OPTIONS_GHC -fplugin Data.TypeLevel.List.Solver #-} + +module Main where + +import Data.Constraint.Operators (MaybeC) +import Data.Kind (Constraint, Type) +import Data.Proxy +import Data.TypeLevel.Known (Known) +import Data.TypeLevel.Maybe (FromMaybe) +import Data.TypeLevel.OrdMap +import Type.Reflection (Typeable) + +data Dict c where + Dict :: (c) => Dict c + +class C (k :: Type) (v :: Type) + +trivialOM :: + (AllOM (c :: k -> Type -> Constraint) dic, Member l (dic :: OrdMap k Type)) => + Proxy c -> + Proxy dic -> + Proxy l -> + Dict (c l (Lookup' l dic)) +trivialOM _ _ _ = Dict + +elimMaybC :: + (Known may, MaybeC Typeable may) => + Proxy may -> + Dict (Typeable (FromMaybe Int may)) +elimMaybC _ = Dict + +class D (k :: Type) where + unC :: Proxy k -> String + +instance D Int where + unC _ = "Int" + +instance D Bool where + unC _ = "Bool" + +elimAllOMLookup :: + forall (om :: OrdMap Bool Type) (def :: Type) (x :: Bool). + (AllOM (EntryC D) (om :: OrdMap Bool Type), D def, Known x) => + Proxy x -> + Proxy om -> + Proxy def -> + String +elimAllOMLookup _ _ _ = + unC $ Proxy @(FromMaybe @Type def (Lookup @Bool @Type x om)) + +main :: IO () +main = return () diff --git a/elgenerics-known/elgenerics-known.cabal b/elgenerics-known/elgenerics-known.cabal new file mode 100644 index 0000000..34beeac --- /dev/null +++ b/elgenerics-known/elgenerics-known.cabal @@ -0,0 +1,165 @@ +cabal-version: 3.4 +name: elgenerics-known +version: 0.1.0.0 +category: Data, Generic Programming +synopsis: A battle-tested dependently-typed programming library for Haskell, with powerful type-level ordmaps and type-checker plugins. +description: Please see the README on GitHub at +author: DeepFlow, Inc. +maintainer: DeepFlow, Inc. +copyright: (c) 2019-present, DeepFlow, Inc. +license: BSD-3-Clause +license-file: LICENSE +build-type: Simple +extra-doc-files: + ChangeLog.md + README.md + +common defaults + build-depends: base >=4.7 && <5 + ghc-options: + -Wall + -Wcompat + -Widentities + -Wincomplete-record-updates + -Wincomplete-uni-patterns + -Wmissing-export-lists + -Wmissing-home-modules + -Wpartial-fields + -Wno-redundant-constraints + -Wunused-packages + + default-language: GHC2021 + other-modules: Paths_elgenerics_known + autogen-modules: Paths_elgenerics_known + +library + import: defaults + hs-source-dirs: src + -- cabal-gild: discover src --exclude=src/Data/TypeLevel/Known/Core.hs --exclude=src/Data/UnionFind/Primitive.hs + exposed-modules: + Control.Category.Monoid + Data.Constraint.Deferrable.Solver + Data.Constraint.Operators + Data.Constraint.TH + Data.Inhabited + Data.Membership + Data.TypeLevel.Applicative + Data.TypeLevel.Bool + Data.TypeLevel.Eq + Data.TypeLevel.Foldable + Data.TypeLevel.Function + Data.TypeLevel.Known + Data.TypeLevel.Known.TH + Data.TypeLevel.List + Data.TypeLevel.List.Core + Data.TypeLevel.List.Overloaded + Data.TypeLevel.List.Properties + Data.TypeLevel.List.Solver + Data.TypeLevel.List.Solver.Constraint + Data.TypeLevel.List.Solver.Free + Data.TypeLevel.List.Solver.Generation + Data.TypeLevel.List.Solver.Reduce + Data.TypeLevel.List.Solver.Syntax + Data.TypeLevel.List.Solver.Utils + Data.TypeLevel.List.Unsafe + Data.TypeLevel.Maybe + Data.TypeLevel.Monoid + Data.TypeLevel.Nat + Data.TypeLevel.Normalise.Plugin + Data.TypeLevel.Ord + Data.TypeLevel.Ord.Internal + Data.TypeLevel.OrdMap + Data.TypeLevel.OrdMap.Internal + Data.TypeLevel.Tuple + Data.TypeLevel.Typeable + GHC.TcPluginM.Orphans + + other-modules: + Data.TypeLevel.Known.Core + Data.UnionFind.Primitive + + build-depends: + constraints, + containers, + deepseq, + dlist, + foldl, + ghc, + ghc-tcplugins-extra, + ghc-typelits-knownnat, + lens, + linear, + primitive, + safe-exceptions, + syb, + template-haskell, + th-abstraction, + th-desugar, + th-utilities, + these, + transformers, + union-find, + vector, + +executable normalise-test + import: defaults + main-is: normalise-test.hs + other-modules: NormDefs + hs-source-dirs: app + build-depends: + base, + elgenerics-known, + +executable simple-plugin-test + import: defaults + main-is: simple-plugin-test.hs + other-modules: NormDefs + hs-source-dirs: app + build-depends: + base, + elgenerics-known, + +test-suite elgenerics-known-test + import: defaults + type: exitcode-stdio-1.0 + main-is: Spec.hs + hs-source-dirs: test + -- cabal-gild: discover test --exclude=test/Spec.hs + other-modules: + Data.Constraint.Deferrable.SolverSpec + Data.Constraint.Deferrable.SolverSpec.Cases + Data.Constraint.Deferrable.SolverSpec.Undeferreds + Data.TypeLevel.KnownSpec + Data.TypeLevel.ListSpec + Data.TypeLevel.ListSpec.Cases + Data.TypeLevel.ListSpec.Undeferred + Data.TypeLevel.Nat.Definitions + Data.TypeLevel.NatSpec + Data.TypeLevel.OrdMapSpec + Data.TypeLevel.OrdMapSpec.Cases + Data.TypeLevel.OrdMapSpec.Failures + Helpers + + ghc-options: + -threaded + -rtsopts + -with-rtsopts=-N + + build-tool-depends: + tasty-discover:tasty-discover + + build-depends: + QuickCheck, + base >=4.7 && <5, + constraints, + containers, + deepseq, + dlist, + elgenerics-known, + inspection-testing, + tasty, + tasty-expected-failure, + tasty-hunit, + tasty-inspection-testing, + tasty-quickcheck, + template-haskell, diff --git a/elgenerics-known/src/Control/Category/Monoid.hs b/elgenerics-known/src/Control/Category/Monoid.hs new file mode 100644 index 0000000..16dfaf3 --- /dev/null +++ b/elgenerics-known/src/Control/Category/Monoid.hs @@ -0,0 +1,22 @@ +{-# LANGUAGE DerivingStrategies #-} +{-# LANGUAGE DerivingVia #-} + +-- | Monoid instances made out of @'Arrows'@ +module Control.Category.Monoid (EndoC (..), EndoM (..)) where + +import Control.Arrow +import Control.Category as Cat +import Data.Coerce + +newtype EndoC p a = EndoC {appEndoA :: p a a} + +instance (Category p) => Semigroup (EndoC p a) where + (<>) = coerce $ (Cat..) @p @a @a @a + +instance (Category p) => Monoid (EndoC p a) where + mempty = coerce $ Cat.id @p @a + +newtype EndoM m a = EndoM {appEndoM :: a -> m a} + deriving + (Semigroup, Monoid) + via EndoC (Kleisli m) a diff --git a/elgenerics-known/src/Data/Constraint/Deferrable/Solver.hs b/elgenerics-known/src/Data/Constraint/Deferrable/Solver.hs new file mode 100644 index 0000000..2e468e4 --- /dev/null +++ b/elgenerics-known/src/Data/Constraint/Deferrable/Solver.hs @@ -0,0 +1,218 @@ +{-# LANGUAGE OverloadedStrings #-} +{-# LANGUAGE RecordWildCards #-} +{-# LANGUAGE ViewPatterns #-} + +module Data.Constraint.Deferrable.Solver (plugin) where + +import Data.Function +import Data.IORef +import Data.List (find) +import Data.Map.Strict qualified as M +import Data.Maybe +import GHC.Core.Class +import GHC.Core.Predicate +import GHC.Core.TyCo.Rep (UnivCoProvenance (PluginProv)) +import GHC.Plugins hiding (TcPlugin) +import GHC.Tc.Plugin hiding (newGiven, newWanted) +import GHC.Tc.Types (TcPlugin (..), TcPluginResult (..)) +import GHC.Tc.Types.Constraint +import GHC.Tc.Types.Evidence +import GHC.TcPluginM.Extra + +plugin :: Plugin +plugin = + defaultPlugin + { tcPlugin = Just . deferrableTcPlugin + , pluginRecompile = purePlugin + } + +deferrableTcPlugin :: [CommandLineOption] -> TcPlugin +deferrableTcPlugin opts = + TcPlugin + { tcPluginInit = initDeferrableState opts + , tcPluginSolve = deferrableSolver + , tcPluginStop = finaliseDeferrableState + } + +finaliseDeferrableState :: + DeferrableState -> TcPluginM () +finaliseDeferrableState DS {..} = do + tcPluginIO $ writeIORef deferred M.empty + pure () + +data NameTbl = NameTbl + { _Deferrable :: Class + , _ReifiedDeferrable :: TyCon + , _presentDictId :: Id + } + +newtype CType = CType {runCType :: Type} + +instance Eq CType where + (==) = eqType `on` runCType + +instance Ord CType where + compare = nonDetCmpType `on` runCType + +data DeferrableState = DS + { nameTbl :: NameTbl + , undeferOpens :: Bool + , deferred :: IORef (M.Map CType Ct) + } + +initDeferrableState :: + [CommandLineOption] -> + TcPluginM DeferrableState +initDeferrableState opts = do + deferred <- tcPluginIO $ newIORef M.empty + constrMod <- lookupModule (mkModuleName "Data.Constraint.Deferrable") "constraints" + opsMod <- lookupModule (mkModuleName "Data.Constraint.Operators") "elgenerics-known" + Just _Deferrable <- + fmap tyConClass_maybe . tcLookupTyCon + =<< lookupName constrMod (mkTcOcc "Deferrable") + _ReifiedDeferrable <- + tcLookupTyCon + =<< lookupName opsMod (mkTcOcc "ReifiedDeferrable") + _presentDictId <- + tcLookupId + =<< lookupName opsMod (mkVarOcc "presentDict") + let nameTbl = NameTbl {..} + undeferOpens = elem "undefer-open-constraints" opts + pure DS {..} + +deferrableSolver :: + DeferrableState -> + [Ct] -> + [Ct] -> + [Ct] -> + TcPluginM TcPluginResult +-- Reduction: geneates @Deferrable@s from +-- the given (non-deferrable) constraints. +deferrableSolver env givens [] [] = do + defs <- deriveDeferrables env givens + pure $ TcPluginOk [] defs + +-- Solving phase: +-- +-- For each @Deferrable p@, we do: +-- 1. Checks if @p@ is in [G]ivens +-- 2. if absent and @p@ has no free variable, +-- adds @p@ to the new [W]anteds and use it. +deferrableSolver env@DS {..} givens _ wanteds = do + let gs' = flattenGivens givens + subs = map fst $ mkSubst' givens + ws' = + mapMaybe (\o -> (o,) <$> deconsDeferrable nameTbl (ctPred $ newCt o)) $ + map (WithOrig <$> id <*> substCt subs) wanteds + (solveds, newWants) <- + unzip . catMaybes <$> mapM (uncurry $ trySolve env gs') ws' + pure $ TcPluginOk solveds $ catMaybes newWants + +trySolve :: + DeferrableState -> + [Ct] -> + WithOrig -> + PredType -> + TcPluginM (Maybe ((EvTerm, Ct), Maybe Ct)) +trySolve DS {nameTbl = tbl@NameTbl {}, ..} gs WithOrig {..} targPred = do + case find ((== CType targPred) . CType . ctPred) gs of + Just ct -> do + let undefEv = buildUndeferred tbl targPred $ ctEvExpr $ ctEvidence ct + pure $ Just ((undefEv, origCt), Nothing) + _ + | noFreeVarsOfType targPred || undeferOpens -> do + ctEv <- newWantedOrHole (ctLoc origCt) targPred + let want = mkNonCanonical' (ctLoc origCt) ctEv + undefEv = buildUndeferred tbl targPred $ ctEvExpr ctEv + tcPluginIO $ + modifyIORef' deferred $ + M.insert (CType targPred) want + pure $ Just ((undefEv, origCt), Just want) + | otherwise -> pure Nothing + +data WithOrig = WithOrig {origCt :: Ct, newCt :: Ct} + +data WithCtLoc a = WithCtLoc CtLoc a + deriving (Foldable) + +buildUndeferred :: NameTbl -> Type -> CoreExpr -> EvTerm +buildUndeferred NameTbl {..} ty dict = + EvExpr + $ Cast + ( Var _presentDictId + `App` Type ty + `App` dict + ) + $ trustMe' + "buildEv" + (mkAppTy (mkTyConTy _ReifiedDeferrable) ty) + (mkAppTy (mkTyConTy $ classTyCon _Deferrable) ty) + +deriveDeferrables :: + DeferrableState -> [Ct] -> TcPluginM [Ct] +deriveDeferrables DS {nameTbl = tbl@NameTbl {..}, ..} gs0 = do + defs <- tcPluginIO $ readIORef deferred + let subs = map fst $ mkSubst' gs0 + gs = flattenGivens gs0 + locConsts = + [ WithCtLoc (ctLoc ct) (ct', p) + | ct <- gs + , let ct' = substCt subs ct + p = ctPred ct' + , CType p `M.notMember` defs + , case classifyPredType p of + ClassPred cls _ -> cls /= _Deferrable + _ -> True + ] + cts <- mapM (buildEv tbl) locConsts + tcPluginIO $ + modifyIORef' deferred $ + M.union + ( M.fromList $ + zipWith + (\(WithCtLoc _ (_, p)) ct -> (CType p, ct)) + locConsts + cts + ) + tcPluginTrace "deferrable: " $ + ppr cts + pure cts + +buildEv :: + NameTbl -> WithCtLoc (Ct, Type) -> TcPluginM Ct +buildEv tbl@NameTbl {..} (WithCtLoc loc (ct, ty)) = do + let defTy = mkAppTy (mkTyConTy $ classTyCon _Deferrable) ty + g <- + newGiven loc defTy $ + buildUndeferred tbl ty $ + ctEvExpr (ctEvidence ct) + + pure $ mkNonCanonical' loc g + +mkNonCanonical' :: + CtLoc -> CtEvidence -> Ct +mkNonCanonical' origCtl ev = + let ct_ls = ctLocSpan origCtl + ctl = ctEvLoc ev + wanted = mkNonCanonical ev + in setCtLoc wanted (setCtLocSpan ctl ct_ls) + +trustMe' :: String -> Type -> Type -> Coercion +trustMe' msg = + mkUnivCo + (PluginProv $ "Data.Constraint.Deferrable.Solver: " ++ msg) + Representational + +deconsDeferrable :: + NameTbl -> Type -> Maybe Type +deconsDeferrable NameTbl {..} ty + | ClassPred cls [prd] <- classifyPredType ty + , cls == _Deferrable = + Just prd + | otherwise = Nothing + +newWantedOrHole :: CtLoc -> PredType -> TcPluginM CtEvidence +newWantedOrHole loc p@(classifyPredType -> EqPred {}) = do + hole <- newCoercionHole p + return $ CtWanted p (HoleDest hole) WDeriv loc +newWantedOrHole loc c = newWanted loc c diff --git a/elgenerics-known/src/Data/Constraint/Operators.hs b/elgenerics-known/src/Data/Constraint/Operators.hs new file mode 100644 index 0000000..9812089 --- /dev/null +++ b/elgenerics-known/src/Data/Constraint/Operators.hs @@ -0,0 +1,256 @@ +{-# LANGUAGE AllowAmbiguousTypes #-} +{-# LANGUAGE DataKinds #-} +{-# LANGUAGE GADTs #-} +{-# LANGUAGE LambdaCase #-} +{-# LANGUAGE MagicHash #-} +{-# LANGUAGE QuantifiedConstraints #-} +{-# LANGUAGE TemplateHaskell #-} +{-# LANGUAGE TypeFamilies #-} +{-# LANGUAGE UndecidableInstances #-} +{-# LANGUAGE UndecidableSuperClasses #-} +{-# LANGUAGE ViewPatterns #-} +{-# OPTIONS_GHC -Wno-orphans #-} +{-# OPTIONS_GHC -fplugin GHC.TypeLits.KnownNat.Solver #-} + +module Data.Constraint.Operators ( + All, + Prod, + Trivially, + MaybeC, + withAllFromMember, + collectAllDict, + elimByAll, + genDicts, + ElemDict (..), + reifyDict, + DeferrableFor, + undefer, + presentDict, + superDict, + deferViaSuper, + deferWith, + ReifiedDeferrable (..), + withTailMember, + module Data.Constraint.TH, + deferAllWithDict, + elimFromMaybeC, + elimFromMaybeC', + CustomDict (..), +) where + +import Data.Constraint +import Data.Constraint.Deferrable +import Data.Constraint.TH +import Data.Functor ((<&>)) +import Data.Proxy +import Data.TypeLevel.Known (Known (..)) +import Data.TypeLevel.Known.TH (sCases) +import Data.TypeLevel.List.Core +import Data.TypeLevel.List.Unsafe +import Data.TypeLevel.Maybe (FromMaybe) +import GHC.Exts +import GHC.TypeNats +import Unsafe.Coerce + +type family Prod (c :: [k -> Constraint]) (a :: k) :: Constraint where + Prod '[] _ = () + Prod (c ': cs) v = (c v, Prod cs v) + +type family Trivially a :: Constraint where + Trivially _ = () + +type family MaybeC (c :: k -> Constraint) (mk :: Maybe k) :: Constraint where + MaybeC _ 'Nothing = () + MaybeC c ('Just a) = c a + +data ElemDict (c :: k -> Constraint) (xs :: [k]) where + ElemDict :: Proxy# x -> !Natural -> Dict (c x) -> ElemDict c xs + +-- 素直に型クラスだけを使った @All@ の定義では、 +-- @All c (x ': xs)@ から @All c xs@ を推論するのが不可能になる。 +-- これは、インスタンス解決において、インスタンスに付いている文脈は +-- 解決後消去されるという挙動による(この挙動は OVERLAPPING や +-- Flexible Instancesの事を考えると自然である)。 +-- しかし、それでは余りに @'All'@ 制約が使いづらくなってしまうため、 +-- 相互再帰的に「前までの辞書の情報を全部持っている」という気持ちを、 +-- @All'@ 型族によって表現して、@All@ の親クラス制約としている。 +type family All' (c :: k -> Constraint) (xs :: [k]) :: Constraint where + All' _ '[] = () + All' c (x ': xs) = (c x, All c xs) + +class (All' c xs) => All (c :: k -> Constraint) (xs :: [k]) where + nthElemDict :: Natural -> Proxy# xs -> Int -> ElemDict c xs + genDicts' :: Natural -> Proxy# xs -> [ElemDict c xs] + +instance All c '[] where + nthElemDict _ _ _ = error "nthElemDict for empty list" + {-# INLINE nthElemDict #-} + genDicts' _ _ = [] + {-# INLINE genDicts' #-} + +instance (All c xs, c x) => All c (x ': xs) where + nthElemDict !k _ !n + | n == 0 = ElemDict (proxy# :: Proxy# x) k $ Dict @(c x) + | otherwise = unsafeCoerce $ nthElemDict @_ @c @xs (k + 1) proxy# (n - 1) + {-# INLINE nthElemDict #-} + genDicts' !n _ = + ElemDict (proxy# :: Proxy# x) n (Dict @(c x)) + : unsafeCoerce (genDicts' @_ @c @xs (n + 1) proxy#) + {-# INLINE genDicts' #-} + +data AllDict c (x :: k) (xs :: [k]) where + There :: (c x) => AllDict c x xs + +reifyDict :: + forall k c (x :: k) xs. + (Member x xs, All c xs) => + AllDict c x xs +reifyDict = + let n = fromIntegral $ natVal' @(Index x xs) proxy# + in case nthElemDict @_ @c @xs 0 proxy# n of + ElemDict _ _ (unsafeCoerce @_ @(Dict (c x)) -> Dict) -> There + +elimByAll :: + forall c x xs r. + (All c xs, Member x xs) => + ((c x) => r) -> + r +elimByAll f = case reifyDict @_ @c @x @xs of + There -> f + +genDicts :: forall c xs. (All c xs) => [ElemDict c xs] +genDicts = genDicts' @_ @c @xs 0 proxy# + +class (Deferrable (c a)) => DeferrableFor c a + +instance (Deferrable (c a)) => DeferrableFor c a + +instance + (KnownTyList xs, All (DeferrableFor c) xs) => + Deferrable (All c xs) + where + deferEither (_ :: proxy (All c xs)) f = + go 0 (tyListSkeleton @xs) <&> \Dict -> f + where + go :: + (All (DeferrableFor c) ys) => + Int -> + PList ys -> + Either String (Dict (All c ys)) + go !_ PNil = Right Dict + go !n (PCons (_ :: Proxy# y) sxs) = + case deferEither_ @(c y) @(Dict (c y)) Dict of + Left err -> + Left $ + show n + ++ "th element of the given type-level list fails to satisfy constraint; " + ++ err + Right Dict -> go (n + 1) sxs <&> \Dict -> Dict + +-- Orphan instances for n-tuples of constraints +fmap concat $ mapM deriveTupleDeferrable [2 .. 62] + +undefer :: forall p r. (p) => ((Deferrable p) => r) -> r +undefer = deferWith $ presentDict @p + +deferAllWithDict :: + forall c xs. + (KnownTyList xs) => + (forall x. (Member x xs) => Proxy x -> Either String (Dict (c x))) -> + Either String (Dict (All c xs)) +deferAllWithDict = go $ tyListSkeleton @xs + where + go :: + PList ys -> + (forall x. (Member x ys) => Proxy x -> Either String (Dict (c x))) -> + Either String (Dict (All c ys)) + go PNil _ = Right Dict + go (PCons (_ :: Proxy# x) (ys :: PList ys)) deferrer = do + let def' :: forall z. (Member z ys) => Proxy z -> Either String (Dict (c z)) + def' = withTailMember @z @ys @x deferrer + Dict <- go ys def' + Dict <- deferrer @x Proxy + pure Dict + +deferViaSuper :: + forall c d r. + ((c) => d, Deferrable c) => + ((Deferrable d) => r) -> + r +deferViaSuper = deferWith $ superDict @c @d + +newtype WithDeferred p r + = WithDeferred ((Deferrable p) => r) + +newtype ReifiedDeferrable (c :: Constraint) + = ReifiedDeferrable + (forall proxy r. proxy c -> ((c) => r) -> Either String r) + +deferWith :: + forall c r. + ReifiedDeferrable c -> + ((Deferrable c) => r) -> + r +deferWith def wd = + (unsafeCoerce (WithDeferred @c @r wd) :: ReifiedDeferrable c -> r) + def + +presentDict :: (c) => ReifiedDeferrable c +presentDict = ReifiedDeferrable $ \_ act -> Right act + +superDict :: forall c d. ((c) => d, Deferrable c) => ReifiedDeferrable d +superDict = ReifiedDeferrable $ \_ act -> deferEither_ @c act + +withAllFromMember :: + forall c xs r. + (KnownTyList xs) => + (forall x. (Member x xs) => Proxy x -> Dict (c x)) -> + ((All c xs) => r) -> + r +withAllFromMember f = withDict (collectAllDict @c @xs f) + +collectAllDict :: + forall c xs. + (KnownTyList xs) => + (forall x. (Member x xs) => Proxy x -> Dict (c x)) -> + Dict (All c xs) +collectAllDict = go $ tyListSkeleton @xs + where + go :: + PList ys -> + (forall x. (Member x ys) => Proxy x -> Dict (c x)) -> + Dict (All c ys) + go PNil _ = Dict + go (PCons (_ :: Proxy# x) (ys :: PList ys)) f = + let f' :: forall z. (Member z ys) => Proxy z -> Dict (c z) + f' = withTailMember @z @ys @x f + in case (f @x Proxy, go ys f') of + (Dict, Dict) -> Dict + +withTailMember :: + forall z ys w r. + (Member z ys) => + ((Member z (w ': ys)) => r) -> + r +withTailMember = + unsafeWithKnownMember @z @(w ': ys) + (fromIntegral $ natVal @(Index z ys) Proxy + 1) + +elimFromMaybeC :: + forall c x m r. + (c x, MaybeC c m, Known m) => + ((c (FromMaybe x m)) => r) -> + r +{-# INLINE elimFromMaybeC #-} +elimFromMaybeC = $(sCases ''Maybe [|sKnownVal' @m|] [|\act -> act|]) + +-- | a variant of 'elimFromMaybeC' with all the kinds are explicitly quantified and returns custom dict. +elimFromMaybeC' :: + forall k (c :: k -> Constraint) (x :: k) (m :: Maybe k). + (c x, MaybeC c m, Known m) => + CustomDict (c (FromMaybe x m)) +{-# INLINE elimFromMaybeC' #-} +elimFromMaybeC' = elimFromMaybeC @c @x @m CDict + +data CustomDict c where + CDict :: (c) => CustomDict c diff --git a/elgenerics-known/src/Data/Constraint/TH.hs b/elgenerics-known/src/Data/Constraint/TH.hs new file mode 100644 index 0000000..f20b05a --- /dev/null +++ b/elgenerics-known/src/Data/Constraint/TH.hs @@ -0,0 +1,86 @@ +{-# LANGUAGE TemplateHaskell #-} +{-# OPTIONS_GHC -Wno-incomplete-uni-patterns #-} + +module Data.Constraint.TH ( + deriveTupleDeferrable, + deriveDeferrableTransitively, +) where + +import Control.Monad +import Data.Constraint.Deferrable +import Data.Foldable +import Data.Functor ((<&>)) +import Data.Proxy +import Language.Haskell.TH +import Language.Haskell.TH.Datatype (applySubstitution, resolveTypeSynonyms, unifyTypes) +import TH.Utilities (tyVarBndrName, typeToNamedCon) + +-- | Derives +deriveTupleDeferrable :: Int -> DecsQ +deriveTupleDeferrable n = do + vs@(v0 : vs_) <- replicateM n (newName "a") + insts <- isInstance ''Deferrable [foldl' AppT (TupleT n) $ map VarT vs] + if insts + then pure [] + else + pure <$> do + r <- newName "r" + instanceD + (sequence [[t|Deferrable $(varT x)|] | x <- vs]) + [t|Deferrable $(foldl' appT (tupleT n) $ map varT vs)|] + [ funD + 'deferEither + [ clause + [wildP, varP r] + ( normalB $ + foldr + (\v k -> [|join $ deferEither (Proxy :: Proxy $(varT v)) $k|]) + [|deferEither (Proxy :: Proxy $(varT v0)) $(varE r)|] + vs_ + ) + [] + ] + ] + +splitCtx :: Type -> ([Name], Cxt, Type) +splitCtx (ForallT ns c ty) = + (map tyVarBndrName ns, c, ty) +splitCtx t = ([], [], t) + +deriveDeferrableTransitively :: + TypeQ -> DecsQ +deriveDeferrableTransitively typ = do + r <- newName "r" + rTy <- newName "r" + (_, ctx0, constr) <- splitCtx <$> typ + Just (n, args) <- typeToNamedCon <$> resolveTypeSynonyms constr + insts <- + reifyInstances n args <&> \is -> + [i | i@InstanceD {} <- is] + fmap concat $ + forM insts $ \ ~(InstanceD ovl ctx_ inst _) -> do + subs <- unifyTypes [inst, constr] + let inst' = applySubstitution subs inst + ctx = map (applySubstitution subs) ctx_ + deferInner t = [|deferEither_ @($(pure t)) @(Either String $(varT rTy))|] + bdy + | null ctx = [|Right $(varE r)|] + | otherwise = + foldl' + (\a b -> [|join $ $b $a|]) + ([|deferEither_ @($(pure $ head ctx)) @($(varT rTy)) $(varE r)|]) + $ map deferInner + $ tail ctx + ctxs = ctx0 ++ map (ConT ''Deferrable `AppT`) ctx + + sequence + [ instanceWithOverlapD + ovl + (pure ctxs) + [t|Deferrable $(pure inst')|] + [ funD + 'deferEither + [ clause [wildP, sigP (varP r) [t|($(pure inst')) => $(varT rTy)|]] (normalB bdy) [] + ] + ] + ] diff --git a/elgenerics-known/src/Data/Inhabited.hs b/elgenerics-known/src/Data/Inhabited.hs new file mode 100644 index 0000000..1719edd --- /dev/null +++ b/elgenerics-known/src/Data/Inhabited.hs @@ -0,0 +1,110 @@ +{-# LANGUAGE DefaultSignatures #-} +{-# LANGUAGE DeriveAnyClass #-} +{-# LANGUAGE DerivingStrategies #-} + +module Data.Inhabited ( + Inhabited (..), + defaultInhabitant, +) where + +import Data.Functor.Identity +import Data.Proxy +import Data.Vector qualified as V +import Data.Vector.Unboxed qualified as U +import GHC.Generics +import Linear as Lin +import Linear.V + +{- | 何でも良いので要素を(\(\perp\)以外に)一つ以上持つ型のクラス。 + @Default@ のように何らかの意味は要求せず、とにかく何かあれば良い。 +-} +class Inhabited a where + inhabitant :: a + default inhabitant :: + (Generic a, GInhabited (Rep a)) => + a + inhabitant = defaultInhabitant + +defaultInhabitant :: + (Generic a, GInhabited (Rep a)) => + a +defaultInhabitant = to ginhabitant + +instance Inhabited Bool where + inhabitant = True + +instance + (Inhabited a, Inhabited b) => + Inhabited (a, b) + +instance + (Inhabited a, Inhabited b, Inhabited c) => + Inhabited (a, b, c) + +instance + (Inhabited a, Inhabited b, Inhabited c, Inhabited d) => + Inhabited (a, b, c, d) + +instance + (Inhabited a, Inhabited b, Inhabited c, Inhabited d, Inhabited e) => + Inhabited (a, b, c, d, e) + +instance Inhabited (Maybe a) where + inhabitant = Nothing + +instance Inhabited [a] + +instance Inhabited (V.Vector a) where + inhabitant = V.empty + +instance (U.Unbox a) => Inhabited (U.Vector a) where + inhabitant = U.empty + +instance Inhabited Int where + inhabitant = 0 + +instance Inhabited Integer where + inhabitant = 0 + +instance Inhabited Double where + inhabitant = 0 + +instance (Inhabited t) => Inhabited (Identity t) where + inhabitant = Identity inhabitant + +instance Inhabited () where + inhabitant = () + +deriving anyclass instance (Inhabited a) => Inhabited (V3 a) + +deriving anyclass instance (Inhabited a) => Inhabited (V0 a) + +deriving anyclass instance (Inhabited a) => Inhabited (Lin.V1 a) + +deriving anyclass instance (Inhabited a) => Inhabited (V2 a) + +deriving anyclass instance (Inhabited a) => Inhabited (V4 a) + +instance (Dim n, Inhabited a) => Inhabited (V n a) where + inhabitant = V $ V.replicate (reflectDim $ Proxy @n) inhabitant + +class GInhabited f where + ginhabitant :: f () + +instance GInhabited U1 where + ginhabitant = U1 + +instance (GInhabited f, GInhabited g) => GInhabited (f :*: g) where + ginhabitant = ginhabitant :*: ginhabitant + +{- | 本当は @f@ と @g@ __どちらか一方__で十分だが、 + Haskell は現状で型クラス制約に OR を許さないので左だけになっている +-} +instance (GInhabited f) => GInhabited (f :+: g) where + ginhabitant = L1 ginhabitant + +instance (GInhabited f) => GInhabited (M1 i c f) where + ginhabitant = M1 ginhabitant + +instance (Inhabited a) => GInhabited (K1 i a) where + ginhabitant = K1 inhabitant diff --git a/elgenerics-known/src/Data/Membership.hs b/elgenerics-known/src/Data/Membership.hs new file mode 100644 index 0000000..4c61797 --- /dev/null +++ b/elgenerics-known/src/Data/Membership.hs @@ -0,0 +1,266 @@ +{-# LANGUAGE AllowAmbiguousTypes #-} +{-# LANGUAGE DataKinds #-} +{-# LANGUAGE GADTs #-} +{-# LANGUAGE MagicHash #-} +{-# LANGUAGE TypeFamilies #-} +{-# LANGUAGE UndecidableInstances #-} +{-# OPTIONS_GHC -funbox-strict-fields #-} + +module Data.Membership ( + Membership, + elemAtMembership, + membership, + withMembership, + withMembershipC, + mapMembership, + consMembership, + SortByWithIndex, + Subset, + HasElem, + position, + subDict, + sortSubset, + unsortSubset, + Sortable, + type (∈), + type (⊆), + permutation, + permutationWith, + fromKnownTyListC, + fromKnownTyList, + foldMapTyListC, + foldMapTyList, + foldrMTyListC, + foldrMTyList, + foldrTyListC, + foldrTyList, + foldlMTyListC', + foldlMTyList', + module Data.TypeLevel.Nat, + module Data.TypeLevel.Tuple, +) where + +import Control.Category.Monoid +import Data.Coerce +import Data.Constraint +import Data.Constraint.Operators +import Data.Foldable (fold) +import Data.List (elemIndex) +import Data.Maybe +import Data.Monoid (Endo (..)) +import Data.Proxy +import Data.TypeLevel.List.Core +import Data.TypeLevel.List.Unsafe +import Data.TypeLevel.Nat +import Data.TypeLevel.Ord +import Data.TypeLevel.Tuple +import GHC.Exts +import Unsafe.Coerce + +newtype Membership (a :: k) (as :: [k]) = Membership Word + +instance Show (Membership a as) where + showsPrec _ (Membership i) = showChar '@' . shows i + +membership :: forall a as. (Member a as) => Membership a as +membership = Membership $ fromIntegral $ natVal $ Proxy @(Index a as) + +mapMembership :: forall h a as. Membership a as -> Membership (h a) (Map h as) +mapMembership = coerce + +type a ∈ as = Member a as + +type as ⊆ bs = Subset as bs + +type Subset as bs = All (HasElem bs) as + +newtype WrapM a as r = WrapM ((Member a as) => r) + +withMembership :: + forall a as r. + Membership a as -> + ((Member a as) => r) -> + r +withMembership (Membership a) f = + unsafeCoerce (WrapM @a @as @r f) (fromIntegral a :: Natural) + +withMembershipC :: + forall c a as r. + (All c as) => + Membership a as -> + ((c a, Member a as) => r) -> + r +withMembershipC mem f = withMembership mem $ f \\ subDict @c @a @as + +position :: forall a as. (Member a as) => Word +position = fromIntegral $ natVal (Proxy @(Index a as)) + +subDict :: + forall c a as. + (All c as, Member a as) + :- c a +subDict = Sub $ elimByAll @c @a @as Dict + +elemAtMembership :: forall n as. (KnownNat n) => Membership (ElemAt n as) as +elemAtMembership = Membership $ fromIntegral $ natVal $ Proxy @n + +fromKnownTyListC :: + forall c as r proxy. + (All c as) => + (forall x. (Member x as, c x) => Proxy x -> r) -> + proxy as -> + [r] +fromKnownTyListC f _ = + map + ( \(ElemDict (_ :: Proxy# x) w (Dict :: Dict (c x))) -> + unsafeWithKnownMember @x @as w $ + f (Proxy @x) + ) + $ genDicts @c @as + +fromKnownTyList :: + forall as r proxy. + (KnownTyList as) => + (forall x. (Member x as) => Proxy x -> r) -> + proxy as -> + [r] +fromKnownTyList f _ = + [ withKnownNat (fromIntegral n) $ \(Proxy :: Proxy n) -> + withMembership (elemAtMembership @n @as) $ + f (Proxy @(ElemAt n as)) + | n <- [0 .. fromIntegral (natVal @(Length as) Proxy) - 1 :: Int] + ] + +foldMapTyList :: + forall as w proxy. + (KnownTyList as, Monoid w) => + (forall x. (Member x as) => Proxy x -> w) -> + proxy as -> + w +foldMapTyList f = fold . fromKnownTyList @as f + +foldMapTyListC :: + forall c as w proxy. + (KnownTyList as, All c as, Monoid w) => + (forall x. (Member x as, c x) => Proxy x -> w) -> + proxy as -> + w +foldMapTyListC f = fold . fromKnownTyListC @c @as f + +foldrMTyListC :: + forall c as m b proxy. + (KnownTyList as, All c as, Monad m) => + (forall x. (Member x as, c x) => Proxy x -> b -> m b) -> + b -> + proxy as -> + m b +foldrMTyListC f = + flip $ + appEndoM . foldMapTyListC @c (\p -> EndoM $ f p) + +foldrMTyList :: + forall as m b proxy. + (KnownTyList as, Monad m) => + (forall x. (Member x as) => Proxy x -> b -> m b) -> + b -> + proxy as -> + m b +foldrMTyList f = + flip $ + appEndoM . foldMapTyList (\p -> EndoM $ f p) + +foldrTyList :: + forall as b proxy. + (KnownTyList as) => + (forall x. (Member x as) => Proxy x -> b -> b) -> + b -> + proxy as -> + b +foldrTyList f = + flip $ + appEndo . foldMapTyList (\p -> Endo $ f p) + +foldrTyListC :: + forall c as b proxy. + (KnownTyList as, All c as) => + (forall x. (Member x as, c x) => Proxy x -> b -> b) -> + b -> + proxy as -> + b +foldrTyListC f = + flip $ + appEndo . foldMapTyListC @c (\p -> Endo $ f p) + +foldlMTyListC' :: + forall c as m b proxy. + (KnownTyList as, All c as, Monad m) => + (forall x. (Member x as, c x) => Proxy x -> b -> m b) -> + b -> + proxy as -> + m b +foldlMTyListC' f = \z0 ps -> + foldrTyListC @c (\p k z -> (k $!) =<< f p z) return ps z0 + +foldlMTyList' :: + forall as m b proxy. + (KnownTyList as, Monad m) => + (forall x. (Member x as) => Proxy x -> b -> m b) -> + b -> + proxy as -> + m b +foldlMTyList' f = \z0 ps -> + foldrTyList (\p k z -> (k $!) =<< f p z) return ps z0 + +class (Member a xs) => HasElem xs a + +instance (Member a xs) => HasElem xs a + +permutation :: + forall xs ys. + (Subset xs ys) => + [Word] +permutation = + fromKnownTyListC @(HasElem ys) @xs + (\(Proxy :: (HasElem ys x) => Proxy x) -> position @x @ys) + Proxy + +permutationWith :: + forall xs ys. + (KnownTyList xs) => + (forall x. (Member x xs) => Proxy x -> Membership x ys) -> + [Word] +{-# INLINE permutationWith #-} +permutationWith pos = + fromKnownTyList @xs + (\(Proxy :: Proxy x) -> coerce $ pos $ Proxy @x) + Proxy + +type SortByWithIndex cmp xs = + SortBy (Comparing2 cmp Snd1) (Indexed xs) + +type Sortable cmp xs = + (All KnownNat (MapApply Fst1 (SortByWithIndex cmp xs))) + +natListVal :: (All KnownNat xs) => Proxy xs -> [Natural] +natListVal = fromKnownTyListC @KnownNat natVal + +sortSubset :: + forall cmp x xs. + (Member x xs, Sortable cmp xs) => + Membership x (SortBy cmp xs) +sortSubset = + let is = natListVal @(MapApply Fst1 (SortByWithIndex cmp xs)) Proxy + Membership i = membership @x @xs + in Membership (fromIntegral $ fromJust $ elemIndex (fromIntegral i) is) + +unsortSubset :: + forall cmp x xs. + (Member x (SortBy cmp xs), Sortable cmp xs) => + Membership x xs +unsortSubset = + let is = natListVal @(MapApply Fst1 (SortByWithIndex cmp xs)) Proxy + Membership i = membership @x @(SortBy cmp xs) + in Membership $ fromIntegral (is !! fromIntegral i) + +consMembership :: forall z ys w. (Member z ys) => Membership z (w ': ys) +consMembership = withTailMember @z @ys @w membership diff --git a/elgenerics-known/src/Data/TypeLevel/Applicative.hs b/elgenerics-known/src/Data/TypeLevel/Applicative.hs new file mode 100644 index 0000000..78da9c3 --- /dev/null +++ b/elgenerics-known/src/Data/TypeLevel/Applicative.hs @@ -0,0 +1,86 @@ +{-# LANGUAGE DataKinds #-} +{-# LANGUAGE MagicHash #-} +{-# LANGUAGE TypeFamilies #-} +{-# LANGUAGE UndecidableInstances #-} + +module Data.TypeLevel.Applicative ( + PFunctor (..), + PApplicative (..), + PAlternative (..), + FMap1, + FMap2, + sFMapMaybe, + sFMapMaybe', +) where + +import Data.TypeLevel.Function +import Data.TypeLevel.Known +import Data.TypeLevel.List qualified as L +import Data.TypeLevel.Maybe qualified as M +import GHC.Exts (Proxy#) + +data FMap1 (f :: k ~> k') :: h k ~> h k' + +type instance Apply (FMap1 f) fx = f <$> fx + +data FMap2 :: (k ~> k') ~> h k ~> h k' + +type instance Apply FMap2 f = FMap1 f + +class PFunctor f where + type (<$>) (fun :: a ~> b) (fa :: f a) :: f b + +class (PFunctor f) => PApplicative f where + type Pure (x :: a) :: f a + type (<*>) (fun :: f (a ~> b)) (fa :: f a) :: f b + +class (PApplicative f) => PAlternative f where + type (<|>) (l :: f a) (r :: f a) :: f a + type Empty :: f a + +type MapMaybe :: forall a b. (a ~> b) -> Maybe a -> Maybe b +type family MapMaybe (f :: a ~> b) (ma :: Maybe a) :: Maybe b where + MapMaybe f 'Nothing = 'Nothing + MapMaybe f ('Just a) = 'Just (Apply f a) + +type family AppMaybe (mf :: Maybe (a ~> b)) (ma :: Maybe a) :: Maybe b where + AppMaybe ('Just f) ('Just a) = 'Just (Apply f a) + AppMaybe _ _ = 'Nothing + +instance PFunctor Maybe where + type (<$>) f a = MapMaybe f a + +instance PApplicative Maybe where + type Pure a = 'Just a + type (<*>) f a = AppMaybe f a + +instance PAlternative Maybe where + type Empty = 'Nothing + type (<|>) fa fb = (M.<|>) fa fb + +instance PFunctor [] where + type (<$>) f a = L.MapApply f a + +type family AppList (fs :: [a ~> b]) (as :: [a]) :: [b] where + AppList '[] _ = '[] + AppList (f ': fs) as = (L.++) (L.MapApply f as) (AppList fs as) + +instance PApplicative [] where + type Pure a = '[a] + type (<*>) fs as = AppList fs as + +instance PAlternative [] where + type Empty = '[] + type (<|>) as bs = (L.++) as bs + +sFMapMaybe :: (SApply f) => Proxy# (f :: k ~> k') -> SMaybe (a :: Maybe k) -> SMaybe (f <$> a) +sFMapMaybe _ SNothing = SNothing +sFMapMaybe sf (SJust a) = SJust $ sApply sf a + +sFMapMaybe' :: + forall k k' (f :: k ~> k') (a :: Maybe k). + (SApply f) => + Proxy# f -> + Sing a -> + Sing (MapMaybe f a) +sFMapMaybe' = sFMapMaybe diff --git a/elgenerics-known/src/Data/TypeLevel/Bool.hs b/elgenerics-known/src/Data/TypeLevel/Bool.hs new file mode 100644 index 0000000..686734f --- /dev/null +++ b/elgenerics-known/src/Data/TypeLevel/Bool.hs @@ -0,0 +1,56 @@ +{-# LANGUAGE DataKinds #-} +{-# LANGUAGE TypeFamilies #-} +{-# OPTIONS_GHC -Wno-orphans #-} + +module Data.TypeLevel.Bool ( + type (&&), + (%&&), + type (||), + (%||), + type Not, + sNot, + type CmpBool, + sCmpBool, +) where + +import Data.TypeLevel.Known + +type family (&&) (a :: Bool) (b :: Bool) :: Bool where + 'True && b = b + 'False && _ = 'False + +infixr 3 &&, %&& + +(%&&) :: SBool a -> SBool b -> SBool (a && b) +STrue %&& a = a +SFalse %&& _ = SFalse + +type family (||) (a :: Bool) (b :: Bool) :: Bool where + 'True || _ = 'True + 'False || b = b + +infixr 2 ||, %|| + +(%||) :: SBool a -> SBool b -> SBool (a || b) +STrue %|| _ = STrue +SFalse %|| a = a + +type family Not (a :: Bool) :: Bool where + Not 'True = 'False + Not 'False = 'True + +sNot :: SBool a -> SBool (Not a) +sNot STrue = SFalse +sNot SFalse = STrue + +type family CmpBool (l :: Bool) (r :: Bool) :: Ordering where + CmpBool 'True 'True = 'EQ + CmpBool 'False 'False = 'EQ + CmpBool 'True 'False = 'GT + CmpBool 'False 'True = 'LT + +sCmpBool :: SBool l -> SBool r -> SOrdering (CmpBool l r) +sCmpBool SFalse SFalse = SEQ +sCmpBool SFalse STrue = SLT +sCmpBool STrue STrue = SEQ +sCmpBool STrue SFalse = SGT diff --git a/elgenerics-known/src/Data/TypeLevel/Eq.hs b/elgenerics-known/src/Data/TypeLevel/Eq.hs new file mode 100644 index 0000000..1f5a0ad --- /dev/null +++ b/elgenerics-known/src/Data/TypeLevel/Eq.hs @@ -0,0 +1,24 @@ +{-# LANGUAGE DataKinds #-} +{-# LANGUAGE TypeFamilies #-} +{-# LANGUAGE UndecidableInstances #-} + +module Data.TypeLevel.Eq where + +import Data.Type.Equality qualified as GHC +import GHC.TypeLits + +class PEq k where + type (==) (a :: k) (b :: k) :: Bool + +type EqNat l r = OrderingToEq (CmpNat l r) + +type family OrderingToEq cmp where + OrderingToEq 'LT = 'False + OrderingToEq 'EQ = 'True + OrderingToEq 'GT = 'False + +instance PEq Natural where + type l == r = l GHC.== r + +instance PEq Symbol where + type l == r = l GHC.== r diff --git a/elgenerics-known/src/Data/TypeLevel/Foldable.hs b/elgenerics-known/src/Data/TypeLevel/Foldable.hs new file mode 100644 index 0000000..86b75a9 --- /dev/null +++ b/elgenerics-known/src/Data/TypeLevel/Foldable.hs @@ -0,0 +1,24 @@ +{-# LANGUAGE DataKinds #-} +{-# LANGUAGE TypeFamilies #-} +{-# LANGUAGE UndecidableInstances #-} + +module Data.TypeLevel.Foldable where + +import Data.TypeLevel.Applicative +import Data.TypeLevel.Function +import Data.TypeLevel.Monoid + +class PFoldable f where + type FoldMap (fun :: a ~> w) (c :: f a) :: w + type Fold (ws :: f w) :: w + type Fold ws = FoldMap Id1 ws + +class (PFunctor t, PFoldable t) => PTraversable t where + type Traverse (fun :: a ~> f b) (arg :: t a) :: f (t b) + +instance PFoldable [] where + type FoldMap fun c = FoldMapList fun c + +type family FoldMapList (f :: k ~> w) (as :: [k]) where + FoldMapList _ '[] = Mempty + FoldMapList f (x ': xs) = Apply f x <> FoldMapList f xs diff --git a/elgenerics-known/src/Data/TypeLevel/Function.hs b/elgenerics-known/src/Data/TypeLevel/Function.hs new file mode 100644 index 0000000..a3a797a --- /dev/null +++ b/elgenerics-known/src/Data/TypeLevel/Function.hs @@ -0,0 +1,87 @@ +{-# LANGUAGE AllowAmbiguousTypes #-} +{-# LANGUAGE DataKinds #-} +{-# LANGUAGE DerivingStrategies #-} +{-# LANGUAGE GADTs #-} +{-# LANGUAGE MagicHash #-} +{-# LANGUAGE TypeFamilies #-} +{-# LANGUAGE UndecidableInstances #-} + +module Data.TypeLevel.Function ( + type (~>), + type (.:), + type Con, + Con1, + BiCon, + BiCon1, + Apply, + Applied (..), + Id1, + Const2, + Const1, + Dom, + Cod, +) where + +import Control.DeepSeq +import Data.Kind +import GHC.Generics + +infixr 0 ~> + +type k ~> k' = k -> k' -> Type + +type family Apply (n :: k ~> k') (a :: k) :: k' + +data (.:) (a :: k' ~> k'') (b :: k ~> k') :: k ~> k'' + +type instance + Apply (f .: g) b = + Apply f (Apply g b) + +data Con (c :: k -> k') :: k ~> k' + +type instance Apply (Con c) a = c a + +data Con1 :: (k -> k') ~> k ~> k' + +type instance Apply Con1 f = Con f + +data BiCon (c :: k -> k' -> k'') :: k ~> k' ~> k'' + +type instance Apply (BiCon f) x = BiCon1 f x + +data BiCon1 (c :: k -> k' -> k'') (x :: k) :: k' ~> k'' + +type instance Apply (BiCon1 f x) y = f x y + +newtype Applied n a = Applied {runApplied :: Apply n a} + deriving (Generic) + +deriving newtype instance (Show (Apply n a)) => Show (Applied n a) + +deriving newtype instance (Eq (Apply n a)) => Eq (Applied n a) + +deriving newtype instance (Ord (Apply n a)) => Ord (Applied n a) + +deriving newtype instance (NFData (Apply n a)) => NFData (Applied n a) + +data Id1 :: k ~> k + +type instance Apply Id1 a = a + +type family Dom p where + Dom (a ~> b) = a + +-- Dom (a -> b) = a +type family Cod p where + Cod (a ~> b) = b + +-- Cod (a -> b) = b + +data Const2 :: a ~> b ~> a + +data Const1 (x :: a) :: b ~> a + +type instance Apply Const2 a = Const1 a + +type instance Apply (Const1 a) _ = a diff --git a/elgenerics-known/src/Data/TypeLevel/Known.hs b/elgenerics-known/src/Data/TypeLevel/Known.hs new file mode 100644 index 0000000..75b99aa --- /dev/null +++ b/elgenerics-known/src/Data/TypeLevel/Known.hs @@ -0,0 +1,88 @@ +{-# LANGUAGE AllowAmbiguousTypes #-} +{-# LANGUAGE DataKinds #-} +{-# LANGUAGE DerivingVia #-} +{-# LANGUAGE GADTs #-} +{-# LANGUAGE LambdaCase #-} +{-# LANGUAGE MagicHash #-} +{-# LANGUAGE TemplateHaskell #-} +{-# LANGUAGE TypeFamilies #-} +{-# LANGUAGE TypeFamilyDependencies #-} +{-# LANGUAGE UndecidableInstances #-} +{-# OPTIONS_GHC -Wno-orphans #-} + +module Data.TypeLevel.Known ( + module Data.TypeLevel.Known.Core, + module Data.TypeLevel.Known.TH, + (%===), + triviallyEqual, + SMaybe (..), + KnownMaybe, + maybeVal, + sMaybeVal, + toSomeMaybe, + SThese (..), + KnownThese, + theseVal, + sTheseVal, + toSomeThese, + This, + That, + MkThese, + SEither (..), + KnownEither, + Left, + Right, + eitherVal, + sEitherVal, + toSomeEither, + SBool (..), + KnownBool, + boolVal, + sBoolVal, + toSomeBool, + SOrdering (..), + orderingVal, + sOrderingVal, + type EQ, + type GT, + type LT, + toSomeOrdering, +) where + +import Data.Constraint.Deferrable +import Data.Proxy +import Data.These +import Data.Type.Equality +import Data.TypeLevel.Known.Core +import Data.TypeLevel.Known.TH +import Unsafe.Coerce (unsafeCoerce) + +deriveAllKnown True ''Maybe +deriveAllKnown True ''Either +deriveAllKnown True ''These + +type MkThese = Data.TypeLevel.Known.These + +triviallyEqual :: + forall x r. (((x == x) ~ 'True) => r) -> r +triviallyEqual f = + case unsafeCoerce (Refl @0) :: (x == x) :~: 'True of + Refl -> f + +_suppress_Maybe :: Proxy '(Just, Nothing) +_suppress_Maybe = Proxy + +deriveAllKnown True ''Bool + +_suppress_Bool :: Proxy '(True, False) +_suppress_Bool = Proxy + +deriveAllKnown True ''Ordering + +(%===) :: (STestEquality k) => Sing (a :: k) -> Sing b -> SBool (a === b) +a %=== b = + case sTestEquality a b of + Equal -> STrue + NonEqual -> SFalse + +infix 4 %=== diff --git a/elgenerics-known/src/Data/TypeLevel/Known/Core.hs b/elgenerics-known/src/Data/TypeLevel/Known/Core.hs new file mode 100644 index 0000000..1f545ae --- /dev/null +++ b/elgenerics-known/src/Data/TypeLevel/Known/Core.hs @@ -0,0 +1,593 @@ +{-# LANGUAGE AllowAmbiguousTypes #-} +{-# LANGUAGE DataKinds #-} +{-# LANGUAGE DerivingVia #-} +{-# LANGUAGE GADTs #-} +{-# LANGUAGE LambdaCase #-} +{-# LANGUAGE MagicHash #-} +{-# LANGUAGE QuantifiedConstraints #-} +{-# LANGUAGE TypeFamilies #-} +{-# LANGUAGE TypeFamilyDependencies #-} +{-# LANGUAGE UndecidableInstances #-} + +module Data.TypeLevel.Known.Core ( + Sing, + SNat, + SSymbol, + knownSymbolVal, + knownNatVal, + STestEquality (..), + sTestTypeableEquality, + Equality (..), + WrapSing (..), + STuple (..), + STriple (..), + SList (..), + SUnit (..), + SVoid (), + Known (..), + ShowSing (), + ShowSing' (), + withKnown, + withKnown', + knownVal#, + knownVal, + knownVal', + sKnownVal#, + sKnownVal, + withKnownNat', + toKnownNat, + withKnownSymbol', + toKnownSymbol, + SomeTypeRep' (..), + SomeSing (..), + HasSing (..), + SingTypeable (..), + withSingTypeable, + type (===), + SApply (..), + Snd, + Snd1, + Fst, + Fst1, + First, + First2, + First1, + Second, + Second2, + Second1, + Uncurry, + Swap, + Swap1, +) where + +import Data.Kind (Type) +import Data.Proxy +import Data.Type.Equality (TestEquality (..), gcastWith, type (==)) +import Data.TypeLevel.Function +import Data.Void (Void) +import GHC.Exts +import GHC.TypeLits (KnownSymbol, SomeSymbol (..), Symbol, someSymbolVal, symbolVal') +import GHC.TypeNats (KnownNat, Nat, SomeNat (SomeNat), natVal', someNatVal) +import Numeric.Natural (Natural) +import Type.Reflection +import Type.Reflection.Unsafe (typeRepFingerprint) +import Unsafe.Coerce (unsafeCoerce) + +type family Sing :: k -> Type + +data SomeSing k where + MkSomeSing :: Sing (a :: k) -> SomeSing k + +instance (ShowSing k) => Show (SomeSing k) where + showsPrec d (MkSomeSing sng) = + showParen (d > 10) $ + showString "MkSomeSing " . showsPrec 11 sng + +newtype WithKnown a r = WithKnown ((Known a) => r) + +withKnown' :: forall a r. Sing a -> ((Known a) => r) -> r +withKnown' s act = + unsafeCoerce (WithKnown @a @r act) s + +withKnown :: + forall a r. Sing a -> ((Known a) => Proxy a -> r) -> r +withKnown s act = withKnown' @a @(Proxy a -> r) s act Proxy + +class HasSing k where + type Demote k :: Type + type Demote k = k + demote :: Sing (a :: k) -> Demote k + promote :: Demote k -> SomeSing k + +class (Typeable k) => SingTypeable k where + singTypeRep :: Sing (x :: k) -> TypeRep x + +withSingTypeable :: + (SingTypeable k) => Sing (x :: k) -> ((Typeable x) => r) -> r +{-# INLINE withSingTypeable #-} +withSingTypeable sing = withTypeable (singTypeRep sing) + +{- | A type @a@ whose singleton is known statically (corresponds to 'SingI' in @singletons@). + c.f. 'sKnownVal', 'sKnownVal#', 'withKnown', and 'withKnown'' +-} +class Known a where + sKnownVal' :: Sing a + +sKnownVal# :: (Known a) => Proxy# a -> Sing a +sKnownVal# (_ :: Proxy# a) = sKnownVal' @a + +sKnownVal :: (Known a) => pxy a -> Sing a +sKnownVal (_ :: pxy a) = sKnownVal' @a + +knownVal# :: + forall {k} (a :: k). + (Known (a :: k), HasSing k) => + Proxy# a -> + Demote k +knownVal# _ = demote @k $ sKnownVal' @a + +knownVal' :: + forall {k} (a :: k). + (Known a, HasSing k) => + Demote k +knownVal' = demote @k $ sKnownVal' @a + +knownVal :: + forall {k} (a :: k) pxy. + (Known a, HasSing k) => + pxy a -> + Demote k +knownVal = const $ knownVal' @a + +data Equality a b where + Equal :: (a ~ b, (a == b) ~ 'True, (a === b) ~ 'True) => Equality a b + NonEqual :: ((a === b) ~ 'False, (a == b) ~ 'False) => Equality a b + +deriving instance Show (Equality a b) + +class STestEquality k where + sTestEquality :: Sing (a :: k) -> Sing b -> Equality a b + +newtype SNat (n :: Nat) = SNat {unSNat :: Natural} + deriving (Eq, Ord) + +instance Show (SNat n) where + showsPrec d (SNat n) = showsPrec d n + +knownNatVal :: SNat n -> Natural +{-# INLINE knownNatVal #-} +knownNatVal = unSNat + +type instance Sing = SNat + +instance SingTypeable Nat where + singTypeRep sn = withKnownNat' sn typeRep + {-# INLINE singTypeRep #-} + +instance HasSing Nat where + type Demote Nat = Natural + demote = coerce + promote = MkSomeSing . coerce + +deriving via + WrapSing + instance + TestEquality SNat + +instance STestEquality Nat where + {-# INLINE sTestEquality #-} + sTestEquality = \(SNat l) (SNat r) -> + if l == r + then unsafeCoerce $ Equal @() @() + else unsafeCoerce $ NonEqual @1 @2 + +instance (KnownNat n) => Known n where + sKnownVal' = SNat $ natVal' @n proxy# + +toKnownNat :: forall n r. (Known n) => ((KnownNat n) => r) -> r +toKnownNat act = + case someNatVal $ unSNat $ sKnownVal' @n of + SomeNat (_ :: Proxy n') -> + gcastWith (unsafeCoerce $ Refl @() :: n :~: n') act + +withKnownNat' :: + SNat n -> + ((Known n, KnownNat n) => r) -> + r +{-# INLINE withKnownNat' #-} +withKnownNat' (sn :: SNat n) = \a -> withKnown' sn $ toKnownNat @n a + +newtype SSymbol (s :: Symbol) = SSymbol {unSSymbol :: String} + deriving (Eq, Ord) + +instance Show (SSymbol sym) where + showsPrec d = showsPrec d . unSSymbol + +type instance Sing = SSymbol + +knownSymbolVal :: SSymbol n -> String +{-# INLINE knownSymbolVal #-} +knownSymbolVal = unSSymbol + +withKnownSymbol' :: + forall sym r. SSymbol sym -> ((Known sym, KnownSymbol sym) => r) -> r +{-# INLINE withKnownSymbol' #-} +withKnownSymbol' ssym = \a -> withKnown' ssym $ toKnownSymbol @sym a + +toKnownSymbol :: + forall sym r. + (Known sym) => + ((KnownSymbol sym) => r) -> + r +toKnownSymbol act = + case someSymbolVal $ unSSymbol $ sKnownVal' @sym of + SomeSymbol (_ :: Proxy sym') -> + gcastWith (unsafeCoerce (Refl @()) :: sym :~: sym') act + +instance (KnownSymbol s) => Known s where + sKnownVal' = SSymbol $ symbolVal' @s proxy# + +instance HasSing Symbol where + type Demote Symbol = String + demote = unSSymbol + promote = MkSomeSing . SSymbol + +instance SingTypeable Symbol where + singTypeRep ssym = withKnownSymbol' ssym typeRep + {-# INLINE singTypeRep #-} + +deriving via + WrapSing + instance + TestEquality SSymbol + +instance STestEquality Symbol where + {-# INLINE sTestEquality #-} + sTestEquality = \(SSymbol l) (SSymbol r) -> + if l == r + then unsafeCoerce $ Equal @() @() + else unsafeCoerce $ NonEqual @"" @"x" + +newtype WrapSing a = WrapSing {unwrapSing :: Sing a} + +deriving newtype instance (Show (Sing a)) => Show (WrapSing a) + +instance (STestEquality k) => TestEquality (WrapSing :: k -> Type) where + {-# INLINE testEquality #-} + testEquality = \(WrapSing l) (WrapSing r) -> + case sTestEquality l r of + Equal -> Just Refl + _ -> Nothing + +sTestTypeableEquality :: + forall a b. + (Typeable a, Typeable b) => + Equality a b +{-# INLINE sTestTypeableEquality #-} +sTestTypeableEquality = + case testEquality (typeRep @a) (typeRep @b) of + Just Refl -> unsafeCoerce $ Equal @() + Nothing -> unsafeCoerce $ NonEqual @1 @2 + +data STuple (tpl :: (a, b)) where + SPair :: Sing a -> Sing b -> STuple '(a, b) + +deriving instance (ShowSing a, ShowSing b) => Show (STuple (tpl :: (a, b))) + +type instance Sing = STuple + +instance (Known a, Known b) => Known '(a, b) where + sKnownVal' = SPair sKnownVal' sKnownVal' + +instance + (SingTypeable a, SingTypeable b) => + SingTypeable (a, b) + where + {-# INLINE singTypeRep #-} + singTypeRep (SPair l r) = + withSingTypeable l $ withSingTypeable r typeRep + +instance (HasSing a, HasSing b) => HasSing (a, b) where + type Demote (a, b) = (Demote a, Demote b) + demote = \case + SPair a b -> (demote a, demote b) + promote = \(a, b) -> + case (promote a, promote b) of + (MkSomeSing l, MkSomeSing r) -> MkSomeSing $ SPair l r + +instance + (STestEquality a, STestEquality b) => + STestEquality (a, b) + where + {-# INLINE sTestEquality #-} + sTestEquality = \(SPair a b) (SPair a' b') -> + case (sTestEquality a a', sTestEquality b b') of + (Equal, Equal) -> Equal + (NonEqual, _) -> unsafeCoerce $ NonEqual @0 @1 + (_, NonEqual) -> unsafeCoerce $ NonEqual @0 @1 + +deriving via + WrapSing + instance + (STestEquality a, STestEquality b) => + TestEquality (STuple :: (a, b) -> Type) + +data STriple (tpl :: (a, b, c)) where + SMkTriple :: Sing a -> Sing b -> Sing c -> STriple '(a, b, c) + +deriving instance + (ShowSing a, ShowSing b, ShowSing c) => + Show (STriple (tpl :: (a, b, c))) + +type instance Sing = STriple + +instance (Known a, Known b, Known c) => Known '(a, b, c) where + sKnownVal' = SMkTriple sKnownVal' sKnownVal' sKnownVal' + +instance (SingTypeable a, SingTypeable b, SingTypeable c) => SingTypeable (a, b, c) where + {-# INLINE singTypeRep #-} + singTypeRep (SMkTriple a b c) = + withSingTypeable a $ + withSingTypeable b $ + withSingTypeable c typeRep + +instance (HasSing a, HasSing b, HasSing c) => HasSing (a, b, c) where + type Demote (a, b, c) = (Demote a, Demote b, Demote c) + demote = \case + SMkTriple a b c -> (demote a, demote b, demote c) + promote = \(a, b, c) -> + case (promote a, promote b, promote c) of + (MkSomeSing l, MkSomeSing r, MkSomeSing u) -> + MkSomeSing $ SMkTriple l r u + +instance + (STestEquality a, STestEquality b, STestEquality c) => + STestEquality (a, b, c) + where + {-# INLINE sTestEquality #-} + sTestEquality = \(SMkTriple a b c) (SMkTriple a' b' c') -> + case (sTestEquality a a', sTestEquality b b', sTestEquality c c') of + (Equal, Equal, Equal) -> Equal + (NonEqual, _, _) -> unsafeCoerce $ NonEqual @0 @1 + (_, NonEqual, _) -> unsafeCoerce $ NonEqual @0 @1 + (_, _, NonEqual) -> unsafeCoerce $ NonEqual @0 @1 + +deriving via + WrapSing + instance + (STestEquality a, STestEquality b, STestEquality c) => + TestEquality (STriple :: (a, b, c) -> Type) + +data SomeTypeRep' where + MkSomeTypeRep' :: TypeRep (a :: Type) -> SomeTypeRep' + +deriving instance Show SomeTypeRep' + +type instance Sing = (TypeRep :: Type -> Type) + +instance SingTypeable Type where + singTypeRep = id + {-# INLINE singTypeRep #-} + +instance HasSing Type where + type Demote Type = SomeTypeRep' + demote = MkSomeTypeRep' + promote = \case + MkSomeTypeRep' (rep :: TypeRep a) -> MkSomeSing rep + +instance (Typeable (a :: Type), (a === a) ~ 'True) => Known a where + sKnownVal' = typeRep + {-# INLINE sKnownVal' #-} + +instance STestEquality Type where + {-# INLINE sTestEquality #-} + sTestEquality = \l r -> + if typeRepFingerprint l == typeRepFingerprint r + then unsafeCoerce $ Equal @0 + else unsafeCoerce $ NonEqual @0 @1 + +data SList (xs :: [k]) where + SNil :: SList '[] + (:%) :: Sing x -> SList xs -> SList (x ': xs) + +infixr 8 :% + +instance (ShowSing k) => Show (SList (lst :: [k])) where + showsPrec _ s = showChar '[' . go s . showChar ']' + where + go :: SList (xs :: [k]) -> ShowS + go SNil = id + go (sx :% SNil) = shows sx + go (sx :% sxs) = shows sx . showString ", " . go sxs + +type instance Sing = SList + +deriving instance Typeable SList + +instance (SingTypeable a) => SingTypeable [a] where + {-# INLINE singTypeRep #-} + singTypeRep = go + where + go :: SList (xs :: [a]) -> TypeRep xs + go SNil = typeRep + go (sx :% xs) = + withSingTypeable sx $ withTypeable (go xs) typeRep + +instance Known ('[] :: [k]) where + sKnownVal' = SNil + {-# INLINE sKnownVal' #-} + +instance (Known x, Known xs) => Known (x ': xs) where + sKnownVal' = sKnownVal' :% sKnownVal' + {-# INLINE sKnownVal' #-} + +instance (HasSing k) => HasSing [k] where + type Demote [k] = [Demote k] + demote = \case + SNil -> [] + l :% xs -> demote l : demote xs + {-# INLINE demote #-} + promote = \case + [] -> MkSomeSing SNil + (x : xs) + | MkSomeSing sx <- promote x + , MkSomeSing sxs <- promote xs -> + MkSomeSing $ sx :% sxs + {-# INLINE promote #-} + +instance (STestEquality k) => STestEquality [k] where + {-# INLINE sTestEquality #-} + sTestEquality = \l r -> case (l, r) of + (SNil, SNil) -> Equal + (a :% as, b :% bs) + | Equal <- sTestEquality a b + , Equal <- sTestEquality as bs -> + Equal + _ -> unsafeCoerce $ NonEqual @Int @Bool + +deriving via + WrapSing + instance + (STestEquality k) => + TestEquality (SList :: [k] -> Type) + +{- +-- Sing and Skeleton can be unified using the +-- following HKD-like construction: + +type family SkeletonF (l :: forall k. k -> Type) (self :: a -> Type) (x :: a) + = r | r -> x +type Sing = + SkeletonF WrapSing WrapSing + -- Sing cannot be here b/c it is a (non-saturated) type family! +-} + +data SUnit (a :: ()) where + SUnit :: SUnit '() + +deriving instance Show (SUnit unit) + +type instance Sing = SUnit + +instance SingTypeable () where + singTypeRep SUnit = typeRep + {-# INLINE singTypeRep #-} + +instance Known '() where + sKnownVal' = SUnit + {-# INLINE sKnownVal' #-} + +instance HasSing () where + demote = const () + {-# INLINE demote #-} + promote = const $ MkSomeSing SUnit + {-# INLINE promote #-} + +instance STestEquality () where + sTestEquality SUnit SUnit = Equal + {-# INLINE sTestEquality #-} + +deriving via WrapSing instance TestEquality SUnit + +infix 4 === + +{- | A variant of '(Data.Type.Equality.==)' that takes + only reflexivity into account and stop bothering with + injectivity concerns. +-} +type family (===) (a :: k) (b :: k) :: Bool where + a === a = 'True + a === b = 'False + +data SVoid (void :: Void) deriving (Show) + +type instance Sing = SVoid + +instance HasSing Void where + promote = \case {} + demote = \case {} + +instance STestEquality Void where + sTestEquality = \case {} + +instance SingTypeable Void where + singTypeRep = \case {} + +deriving via + WrapSing + instance + TestEquality (SVoid :: Void -> Type) + +class (forall (z :: k). ShowSing' z) => ShowSing (k :: Type) + +instance (forall (z :: k). ShowSing' z) => ShowSing (k :: Type) + +class (forall sing. (sing ~ Sing) => Show (sing z)) => ShowSing' z + +instance (Show (Sing z)) => ShowSing' z + +type SApply :: forall k k'. (k ~> k') -> Constraint +class SApply (f :: k ~> k') where + sApply :: Proxy# f -> Sing (a :: k) -> Sing (Apply f a :: k') + +-- >>> :t sApply +-- sApply +-- :: forall k k' (f :: k ~> k') (a :: k). +-- SApply f => +-- Proxy# f -> Sing a -> Sing (Apply f a) + +type family Snd (p :: (a, b)) :: b where + Snd '(_, b) = b + +type family Fst (p :: (a, b)) :: a where + Fst '(a, _) = a + +data Snd1 :: (a, b) ~> b + +type instance Apply Snd1 p = Snd p + +data Fst1 :: (a, b) ~> a + +type instance Apply Fst1 p = Fst p + +type family First (f :: a ~> a') (pr :: (a, b)) :: (a', b) where + First f '(a, b) = '(Apply f a, b) + +type family Second (f :: b ~> b') (pr :: (a, b)) :: (a, b') where + Second f '(a, b) = '(a, Apply f b) + +data First2 :: (a ~> a') ~> (a, b) ~> (a', b) + +data First1 (f :: a ~> a') :: (a, b) ~> (a', b) + +data Second2 :: (b ~> b') ~> (a, b) ~> (a, b') + +data Second1 (f :: b ~> b') :: (a, b) ~> (a, b') + +type instance Apply First2 f = First1 f + +type instance Apply (First1 f) p = First f p + +type instance Apply Second2 f = Second1 f + +type instance Apply (Second1 f) p = Second f p + +data Uncurry (a :: b -> c -> d) :: (b, c) ~> d + +type instance Apply (Uncurry f) tpl = f (Fst tpl) (Snd tpl) + +type family Swap (tpl :: (a, b)) :: (b, a) where + Swap '(a, b) = '(b, a) + +data Swap1 :: (a, b) ~> (b, a) + +type instance Apply Swap1 tpl = Swap tpl + +instance SApply (Fst1 :: (k, k') ~> k) where + sApply _ (SPair l _) = l + +instance SApply (Snd1 :: (k, k') ~> k') where + sApply _ (SPair _ r) = r + +instance SApply (Swap1 :: (k, k') ~> (k', k)) where + sApply _ (SPair l r) = SPair r l diff --git a/elgenerics-known/src/Data/TypeLevel/Known/TH.hs b/elgenerics-known/src/Data/TypeLevel/Known/TH.hs new file mode 100644 index 0000000..ba3316b --- /dev/null +++ b/elgenerics-known/src/Data/TypeLevel/Known/TH.hs @@ -0,0 +1,510 @@ +{-# LANGUAGE CPP #-} +{-# LANGUAGE DerivingVia #-} +{-# LANGUAGE LambdaCase #-} +{-# LANGUAGE MagicHash #-} +{-# LANGUAGE RecordWildCards #-} +{-# LANGUAGE TemplateHaskell #-} + +{-# LANGUAGE ViewPatterns #-} +module Data.TypeLevel.Known.TH + ( deriveAllKnown, + defineSingletons, + deriveKnown, + deriveSTestEquality, + deriveSingTypeable, + sCases, + deriveShowSing) +where + +import qualified Control.Foldl as L +import Control.Lens (anyOf, cosmos, to, transform, (%~), (&), (^..), _head) +import Control.Monad +import Data.Char (toLower) +import Data.Foldable (Foldable (foldl'), toList) +import qualified Data.Kind as K +import qualified Data.Set as Set +import Data.Type.Equality +import Data.TypeLevel.Known.Core +import GHC.Generics (Generic) +import Language.Haskell.TH +import Language.Haskell.TH.Desugar +import Language.Haskell.TH.Lens (_VarT) +import Type.Reflection (Typeable, typeRep) +import Unsafe.Coerce +import qualified Data.Kind as Kinds +import Data.Maybe (catMaybes) +import TH.Utilities (typeToNamedCon) + +data DataSeed = DataSeed + { isNew :: NewOrData + , dataContext :: DCxt + , typeName :: Name + , tyvarBndrs :: [DTyVarBndr ()] + , constructors :: [DCon] + , singDataName :: Name + , dfullyInstTy :: DType + , knownClassName :: Name + , singInfos :: [SingInfo] + , argTySet :: Set.Set Type + , argTys :: [Type] + , testEqCtx :: [Type] + } + +withDataSeed :: + (DataSeed -> Q a) -> Name -> Q a +withDataSeed f n = do + Just (DTyConI (DDataD isNew dataContext typeName tyvarBndrs _ constructors _) _) <- dsReify n + unless (null dataContext) $ fail "DatatypeContexts not yet supported" + let singDataName = mkName $ 'S' : nameBase typeName + dtys = map dTyVarBndrToDType tyvarBndrs + dfullyInstTy = foldl DAppT (DConT typeName) dtys + knownClassName = mkName $ "Known" ++ nameBase typeName + singInfos <- mapM (buildSingInfos singDataName) constructors + let argTySet = + L.fold + ( L.premap singFields $ + L.handles L.folded $ + L.premap (sweeten . snd) $ + L.set + ) + singInfos + argTys = Set.toList argTySet + testEqCtx = [ConT ''STestEquality `AppT` ty | ty <- argTys] + + f DataSeed {..} + +deriveShowSing :: Name -> DecsQ +deriveShowSing = fmap pure . withDataSeed deriveShowSingWith + +deriveSTestEquality :: Name -> DecsQ +deriveSTestEquality = fmap pure . withDataSeed deriveSTestEqualityWith + +defineSingletons :: Name -> DecsQ +defineSingletons = withDataSeed defineSingletonsWith + +deriveKnown :: Name -> Q [Dec] +deriveKnown = withDataSeed deriveKnownWith + +defineSingletonsWith :: DataSeed -> DecsQ +defineSingletonsWith DataSeed {..} = do + x <- newName "_x" + let singDataDecl = DataD + [] + singDataName + [KindedTV x () $ sweeten dfullyInstTy] + Nothing + [ GadtC [singConName] + (map + ((Bang NoSourceUnpackedness NoSourceStrictness ,) . sweeten) + singConArgTypes + ) + (sweeten singConRetType) + | SingInfo {..} <- singInfos + ] + [] + singKindSig = DKiSigD singDataName + $ DArrowT `DAppT` dfullyInstTy `DAppT` DConT ''Kinds.Type + pure $ + decsToTH + [ +#if __GLASGOW_HASKELL__ >= 810 + singKindSig +#endif + ] + ++ [ singDataDecl ] + +deriveAllKnown :: + -- | KnownHoge 系の制約シノニムを定義するか? + Bool -> + Name -> + DecsQ +deriveAllKnown defKnown = withDataSeed $ + \ds@DataSeed {..} -> do + a <- newName "_a" + let bndr = map (asSpecified . sweeten) tyvarBndrs + dtys = map dTyVarBndrToDType tyvarBndrs + tys = map sweeten dtys + fullTy = sweeten dfullyInstTy + knownArg = varT a `sigT` fullTy + someTyName = mkName $ "Some" ++ nameBase typeName + someTy = foldl' AppT (ConT someTyName) tys + knownSynCls <- + classD + (pure <$> [t|Known $knownArg|]) + knownClassName + [KindedTV a () fullTy] + [] + [] + knownSynInst <- + instanceD + (pure <$> [t|Known $knownArg|]) + [t|$(conT knownClassName) $(varT a)|] + [] + let demFullTyQ = + foldl + appT + (conT typeName) + [ if unSigT ty `Set.member` argTySet + then [t|Demote $(pure ty)|] + else pure ty + | ty <- tys + ] + x <- newName "_x" + singDec <- defineSingletonsWith ds + stestInstD <- deriveSTestEqualityWith ds + sShowInstD <- deriveShowSingWith ds + + testEqD <- + instanceD + (pure testEqCtx) + [t|TestEquality ($(conT singDataName) :: $(pure fullTy) -> K.Type)|] + [ funD + 'testEquality + [ clause + [] + ( normalB + [|\a_ b_ -> testEquality (WrapSing a_) (WrapSing b_)|] + ) + [] + ] + , pragInlD 'testEquality Inline FunLike AllPhases + ] + + promoteBody <- + lamE [varP x] $ + caseE + (varE x) + $ map buildPromote singInfos + + demoteBody <- + lamE [varP x] $ + caseE + (varE x) + $ map buildDemote singInfos + let someFunCxt = + map (ConT ''HasSing `AppT`) argTys + someFunTy <- + desugar + =<< forallT bndr (pure someFunCxt) [t|$(demFullTyQ) -> $(pure someTy)|] + let toSomeFunName = mkName $ "toSome" ++ nameBase typeName + toSome = + sweeten + (map + DLetDec + [ DSigD toSomeFunName someFunTy + , DFunD toSomeFunName $ + [DClause [] (DVarE 'promote)] + ]) + ++ [PragmaD $ InlineP 'sTestEquality Inline FunLike AllPhases] + pxy <- newName "_pxy" + valTy <- + desugar + =<< forallT + (bndr ++ [KindedTV x SpecifiedSpec fullTy, PlainTV pxy SpecifiedSpec]) + ( pure $ + (ConT knownClassName `AppT` VarT x) : + map (ConT ''HasSing `AppT`) argTys + ) + [t|$(varT pxy) $(varT x) -> $(demFullTyQ)|] + sValTy <- + desugar + =<< [t| + forall x pxy. + $(conT knownClassName) x => + pxy x -> + $(conT singDataName) x + |] + let lowTyName = nameBase typeName & _head %~ toLower + valName = mkName $ lowTyName ++ "Val" + sValName = mkName $ 's' : nameBase typeName ++ "Val" + valDefs = + (PragmaD $ InlineP valName Inline FunLike AllPhases) : + sweeten + (map + DLetDec + [ DSigD valName valTy + , DFunD valName [DClause [] (DVarE 'knownVal)] + , DSigD sValName sValTy + , DFunD sValName [DClause [] (DVarE 'sKnownVal)] + ]) + ++ [PragmaD $ InlineP sValName Inline FunLike AllPhases] + knowns <- deriveKnownWith ds + singTypeableInsts <- singTypeableDecls ds + hasSing <- + instanceD + (pure [ConT ''HasSing `AppT` ty | ty <- argTys]) + [t|HasSing $(pure fullTy)|] + [ tySynInstD $ + tySynEqn + Nothing + [t|Demote $(pure fullTy)|] + demFullTyQ + , funD 'demote [clause [] (normalB $ pure demoteBody) []] + , pragInlD 'demote Inline FunLike AllPhases + , funD 'promote [clause [] (normalB $ pure promoteBody) []] + , pragInlD 'promote Inline FunLike AllPhases + ] + someSingSyn <- + tySynD + someTyName + (map sweeten tyvarBndrs) + [t|SomeSing $(pure fullTy)|] + tyConSyns <- forM singInfos $ \SingInfo {..} -> + tySynD (mkName $ nameBase origConName) [] $ promotedT origConName + return $ + singDec + ++ [stestInstD, testEqD, sShowInstD] + ++ knowns + ++ tyConSyns + ++ [hasSing] + ++ toSome + ++ [someSingSyn] + ++ valDefs + ++ singTypeableInsts + ++ mconcat [[knownSynCls, knownSynInst] | defKnown] + +asSpecified :: TyVarBndr () -> TyVarBndr Specificity +asSpecified (PlainTV na _) = PlainTV na SpecifiedSpec +asSpecified (KindedTV na _ ty) = KindedTV na SpecifiedSpec ty + +deriveSTestEqualityWith :: DataSeed -> Q Dec +deriveSTestEqualityWith DataSeed {..} = do + let noEql = [|unsafeCoerce (NonEqual :: Equality Int Bool)|] + l <- newName "_l" + r <- newName "_r" + stestBody <- + lamE [varP l, varP r] $ + caseE (tupE [varE l, varE r]) $ + map buildEqualityCase singInfos ++ [match wildP (normalB noEql) []] + instanceWithOverlapD + Nothing + (pure testEqCtx) + (conT ''STestEquality `appT` (pure $ sweeten dfullyInstTy)) + [ funD 'sTestEquality [clause [] (normalB $ pure stestBody) []] + , pragInlD 'sTestEquality Inline FunLike AllPhases + ] + + +deriveShowSingWith :: DataSeed -> DecQ +deriveShowSingWith DataSeed{..} = do + s <- newName "s" + standaloneDerivD (pure [ConT ''ShowSing `AppT` arg | arg <- argTys]) + [t|Show ($(conT singDataName) $(varT s `sigT` sweeten dfullyInstTy))|] + + +deriveKnownWith :: DataSeed -> Q [Dec] +deriveKnownWith DataSeed {..} = do + let singInst = + decToTH $ + DTySynInstD $ + DTySynEqn + Nothing + (DConT ''Sing) + (DConT singDataName) + knowns <- mapM buildKnown singInfos + pure $ singInst : knowns + +buildDemote :: SingInfo -> MatchQ +buildDemote SingInfo {..} = do + let body = + normalB $ + foldl' + appE + (conE origConName) + [[|demote $(varE v)|] | (v, _) <- singFields] + match + (conP singConName $ map (varP . fst) singFields) + body + [] + +buildPromote :: SingInfo -> Q Match +buildPromote SingInfo {..} = do + pVars <- mapM (newName . ("_prom_" ++) . nameBase . fst) singFields + let resl = + ConE 'MkSomeSing + `AppE` foldl' + AppE + (ConE singConName) + (map VarE pVars) + gBinds = + PatG $ + zipWith + ( \(orig, _) d -> + BindS (ConP 'MkSomeSing [] [VarP d]) $ + VarE 'promote `AppE` VarE orig + ) + singFields + pVars + body + | null singFields = normalB $ pure resl + | otherwise = guardedB [pure (gBinds, resl)] + match + (conP origConName $ map (varP . fst) singFields) + body + [] + +buildEqualityCase :: SingInfo -> MatchQ +buildEqualityCase SingInfo {..} = do + lArgs <- mapM (newName . (++ "_l") . nameBase . fst) singFields + rArgs <- mapM (newName . (++ "_r") . nameBase . fst) singFields + let equal = ConE 'Equal + subs = + PatG $ + zipWith + ( \l r -> + BindS (ConP 'Equal [] []) $ + foldl' AppE (VarE 'sTestEquality) [VarE l, VarE r] + ) + lArgs + rArgs + body + | null singFields = normalB $ pure equal + | otherwise = guardedB [pure (subs, equal)] + match + ( tupP + [ conP singConName $ map varP lArgs + , conP singConName $ map varP rArgs + ] + ) + body + [] + +buildKnown :: SingInfo -> Q Dec +buildKnown SingInfo {..} = + instanceD + ( sequence + [ [t|Known $(varT var `sigT` sweeten ty)|] + | (var, ty) <- singFields + ] + ) + [t|Known $(pure $ sweeten saturatedCon)|] + [ funD + 'sKnownVal' + [ clause + [] + ( normalB $ + appsE $ + conE singConName : + map (const [|sKnownVal'|]) singFields + ) + [] + ] + , pragInlD 'sKnownVal' Inline FunLike AllPhases + ] + +data SingInfo = SingInfo + { origConName :: Name + , singConName :: Name + , singFields :: [(Name, DType)] + , singRetType :: DType + , singConArgTypes :: [DType] + , singConRetType :: DType + , saturatedCon :: DType + } + deriving (Show, Generic, Typeable) + +buildSingInfos :: + Name -> DCon -> Q SingInfo +buildSingInfos singDataName (DCon _ _ origConName flds singRetType) = do + singFields <- parseFields flds + let singConName = mkName $ 'S' : nameBase origConName + singConArgTypes = map (\(v, ty) -> DConT ''Sing `DAppT` (DVarT v `DSigT` ty)) singFields + saturatedCon = + foldl' DAppT (DConT origConName) $ + map (DVarT . fst) singFields + singConRetType = (DConT singDataName `DAppT` saturatedCon) + pure SingInfo {..} + +parseFields :: DConFields -> Q [(Name, DType)] +parseFields (DNormalC _ fs) = + mapM (\(_, ty) -> (,ty) <$> newName "_v") fs +parseFields (DRecC fs) = + pure $ map (\(var, _, ty) -> (var, ty)) fs + +unSigT :: Type -> Type +unSigT (SigT l _) = unSigT l +unSigT t = t + +sCases :: + -- | A type to match on its singleton ('Bool', not 'SBool'!) + Name -> + -- | A singleton expression to match on (scrutinee) + ExpQ -> + -- | Case body + ExpQ -> + ExpQ +sCases tyName scrutinee body = do + Just (DTyConI _ (Just fs)) <- dsReify ''Sing + let tyCons = + [ con | DTySynInstD (DTySynEqn _ _ ty) <- fs + , Just (con, _) <- pure $ typeToNamedCon $ unSigT $ sweeten ty + ] + conKinds <- catMaybes <$> mapM (\con -> fmap (con,) <$> dsReifyType con) tyCons + let singTy = head + [con + | (con, unForAllT -> DAppT (DAppT DArrowT ty) _) <- conKinds + , (name', _) <- toList $ typeToNamedCon (sweeten ty) + , name' == tyName + ] + Just (DTyConI (DDataD _ _ _ _ _ dcons _) _) <- dsReify singTy + caseE + scrutinee + [ match (recP conName []) (normalB body) [] + | DCon _ _ conName _ _ <- dcons + ] + +unForAllT :: DType -> DType +unForAllT (DForallT _ d) = unForAllT d +unForAllT (DConstrainedT _ d) = unForAllT d +unForAllT ty = ty + +deriveSingTypeable :: + Name -> DecsQ +deriveSingTypeable = withDataSeed singTypeableDecls + +singTypeableDecls :: DataSeed -> Q [Dec] +singTypeableDecls DataSeed {..} = do + let fullTy = sweeten dfullyInstTy + targTy = + transform + ( \case + (SigT l _) -> l + t -> t + ) + fullTy + typeableVars = + Set.toList $ + Set.fromList (fullTy ^.. cosmos . _VarT . to VarT) + Set.\\ argTySet + concretes <- + filterM + ( \ty -> do + ty' <- dsType ty + let isSelf = sweeten ty' == targTy + pure $ anyOf cosmos (\case VarT {} -> True; _ -> False) ty && not isSelf + ) + argTys + ins <- + instanceD + ( (<>) <$> mapM (\arg -> [t|SingTypeable $(pure arg)|]) concretes + <*> mapM (\ty -> [t|Typeable $(pure ty)|]) typeableVars + ) + [t|SingTypeable $(pure fullTy)|] + [ funD + 'singTypeRep + [ do + vs <- mapM (const $ newName "_v") singFields + clause + [conP singConName $ map varP vs] + ( normalB $ + foldr + (\v bdy -> [|withSingTypeable $(varE v) $bdy|]) + [|typeRep|] + vs + ) + [] + | SingInfo {..} <- singInfos + ] + , pragInlD 'singTypeRep Inline FunLike AllPhases + ] + pure [ins] diff --git a/elgenerics-known/src/Data/TypeLevel/List.hs b/elgenerics-known/src/Data/TypeLevel/List.hs new file mode 100644 index 0000000..be2ecc3 --- /dev/null +++ b/elgenerics-known/src/Data/TypeLevel/List.hs @@ -0,0 +1,319 @@ +{-# LANGUAGE AllowAmbiguousTypes #-} +{-# LANGUAGE DataKinds #-} +{-# LANGUAGE GADTs #-} +{-# LANGUAGE TypeFamilies #-} +{-# LANGUAGE UndecidableInstances #-} +{-# OPTIONS_GHC -fplugin GHC.TypeLits.KnownNat.Solver #-} + +module Data.TypeLevel.List ( + Index, + Snoc, + DeleteOne, + Length, + Length1, + Map, + Zip, + Sum, + Take, + Drop, + Sliced, + NotElem, + Replicate, + mapApplyAppend, + KnownTyList, + All, + SplitAt, + MergeBy, + InsertBy, + CmpSymbol2, + CmpSymbol1, + SortBy, + Indexed, + sIndexed, + Member, + Matches, + Matches1, + CatMaybes, + CatMaybes1, + Applies, + Applies2, + Applies1, + AppliesCon, + AppliesCon2, + AppliesCon1, + mapKnownTyList, + mapApplyKnownTyList, + tyListLength, + tyListSkeleton, + takeMapApply, + sortKnownTyList, + indexKnownTyList, + dropMapApply, + sortIdemp, + ElemAt, + Apply, + MapApply, + MapApply1, + type (++), + (%++), + Concat, + ConcatMapApply, + elemAtReplicate, + appendEmptyL, + elemAtZip, + elemAtMap, + elemAtMapApply, + withTailMember, + elemAtIndex, + allAppendDict, + withAllAppend, + ZipWithSame, + ZipSame, + ZipWith, + KnownNatList, + natListVal, + KnownSymbolList, + KnownTypeableList, + sLength, + module Data.TypeLevel.List.Properties, + module Data.Membership, +) where + +import Data.Constraint +import Data.Constraint.Operators +import Data.Membership +import Data.Type.Equality +import Data.TypeLevel.Function +import Data.TypeLevel.Known +import Data.TypeLevel.List.Core +import Data.TypeLevel.List.Overloaded () +import Data.TypeLevel.List.Properties +import Data.TypeLevel.List.Unsafe +import Data.TypeLevel.Ord.Internal +import GHC.TypeLits hiding (natVal) +import Type.Reflection +import Unsafe.Coerce + +type family DeleteOne (a :: k) (as :: [k]) where + DeleteOne a (a ': as) = as + DeleteOne a (b ': as) = b ': DeleteOne a as + DeleteOne _ '[] = '[] + +indexKnownTyList :: + forall as r. + (KnownTyList as) => + ((KnownTyList (Indexed as)) => r) -> + r +{-# INLINE indexKnownTyList #-} +indexKnownTyList = + unsafeWithKnownTyListBy @(Indexed as) @as + +mapKnownTyList :: + forall h as r. + (KnownTyList as) => + ((KnownTyList (Map h as)) => r) -> + r +mapKnownTyList = + unsafeWithKnownTyListBy @(Map h as) @as + +sortKnownTyList :: + forall cmp as r. + (KnownTyList as) => + ((KnownTyList (SortBy cmp as)) => r) -> + r +sortKnownTyList = + unsafeWithKnownTyListBy @(SortBy cmp as) @as + +mapApplyKnownTyList :: + forall h as r. + (KnownTyList as) => + ((KnownTyList (MapApply h as)) => r) -> + r +mapApplyKnownTyList = + unsafeWithKnownTyListBy @(MapApply h as) @as + +type family Zip as bs where + Zip as '[] = '[] + Zip '[] bs = '[] + Zip (a ': as) (b ': bs) = (a, b) ': Zip as bs + +elemAtZip :: forall k as bs. ElemAt k (Zip as bs) :~: (ElemAt k as, ElemAt k bs) +elemAtZip = unsafeCoerce $ Refl @() + +elemAtMap :: forall k f as. ElemAt k (Map f as) :~: f (ElemAt k as) +elemAtMap = unsafeCoerce $ Refl @() + +elemAtMapApply :: forall k f as. ElemAt k (MapApply f as) :~: Apply f (ElemAt k as) +elemAtMapApply = unsafeCoerce $ Refl @() + +elemAtIndex :: forall x xs. ElemAt (Index x xs) xs :~: x +elemAtIndex = unsafeCoerce $ Refl @() + +type family Concat (as :: [[k]]) :: [k] where + Concat '[] = '[] + Concat (as ': ass) = as ++ Concat ass + +appendEmptyL :: + forall xs. '[] ++ xs :~: xs +appendEmptyL = unsafeCoerce $ Refl @() + +type ConcatMapApply (f :: k ~> [k1]) (as :: [k]) = Concat (MapApply f as) + +type family CatMaybes (ms :: [Maybe k]) :: [k] where + CatMaybes '[] = '[] + CatMaybes ('Just x ': xs) = x ': CatMaybes xs + CatMaybes (_ ': xs) = CatMaybes xs + +data CatMaybes1 :: [Maybe k] ~> [k] + +type instance Apply CatMaybes1 a = CatMaybes a + +type family Sum (ns :: [Nat]) :: Nat where + Sum '[] = 0 + Sum (n ': ns) = n + Sum ns + +type SplitAt n xs = '(Take n xs, Drop n xs) + +type family Sliced (ls :: [Nat]) (as :: [k]) :: [[k]] where + Sliced '[] _ = '[] + Sliced (n ': ns) xs = Take n xs ': Sliced ns (Drop n xs) + +type KnownNatList ns = (All KnownNat ns) + +natListVal :: forall ns proxy. (KnownNatList ns) => proxy ns -> [Word] +natListVal = fromKnownTyListC @KnownNat (fromIntegral . natVal) + +type KnownSymbolList ns = (All KnownSymbol ns) + +type KnownTypeableList ns = (All Typeable ns) + +type family ZipWithSame (f :: a -> b -> c) (as :: [a]) (bs :: [b]) :: [c] where + ZipWithSame _ '[] '[] = '[] + ZipWithSame f (a ': as) (b ': bs) = f a b ': ZipWithSame f as bs + ZipWithSame _ as bs = + TypeError + ( 'Text "Zipping lists of different length: " + ':<>: 'ShowType as + ':<>: 'Text " with " + ':<>: 'ShowType bs + ) + +type ZipSame as bs = ZipWithSame (,) as bs + +data CmpSymbol2 :: Symbol ~> Symbol ~> Ordering + +data CmpSymbol1 (s :: Symbol) :: Symbol ~> Ordering + +type instance Apply CmpSymbol2 s = CmpSymbol1 s + +type instance Apply (CmpSymbol1 s) t = CmpSymbol s t + +type family NotElem a as :: Constraint where + NotElem a (a ': as) = + TypeError + ('Text "A type " ':<>: 'ShowType a ':<>: 'Text " already in entry") + NotElem a (_ ': as) = NotElem a as + NotElem _ '[] = () + +type family InsertBy cmp x xs where + InsertBy _ x '[] = '[x] + InsertBy cmp x (y ': ys) = + CaseOrdering + (Apply (Apply cmp x) y) + (x ': y ': ys) + (y ': ys) + (y ': InsertBy cmp x ys) + +type family Replicate (n :: Nat) (x :: k) :: [k] where + Replicate 0 _ = '[] + Replicate n x = x ': Replicate (n - 1) x + +elemAtReplicate :: + forall n k t. ElemAt k (Replicate n t) :~: t +elemAtReplicate = unsafeCoerce (Refl @()) + +mapApplyAppend :: + MapApply f (xs ++ ys) :~: (MapApply f xs ++ MapApply f ys) +mapApplyAppend = unsafeCoerce $ Refl @() + +takeMapApply :: + forall f n xs. MapApply f (Take n xs) :~: Take n (MapApply f xs) +takeMapApply = unsafeCoerce $ Refl @() + +dropMapApply :: + forall f n xs. MapApply f (Drop n xs) :~: Drop n (MapApply f xs) +dropMapApply = unsafeCoerce $ Refl @() + +type family ZipWith (f :: a ~> b ~> c) (as :: [a]) (bs :: [b]) :: [c] where + ZipWith _ '[] _ = '[] + ZipWith _ _ '[] = '[] + ZipWith f (a ': as) (b ': bs) = Apply (Apply f a) b ': ZipWith f as bs + +sortIdemp :: + forall cmp xs. + SortBy cmp (SortBy cmp xs) + :~: SortBy cmp xs +sortIdemp = unsafeCoerce $ Refl @() + +type family Applies (fs :: [k -> k]) (k0 :: k) :: k where + Applies '[] k0 = k0 + Applies (f ': fs) k0 = f (Applies fs k0) + +data Applies2 :: [k -> k] ~> k ~> k + +data Applies1 (fs :: [k -> k]) :: k ~> k + +type instance Apply Applies2 fs = Applies1 fs + +type instance Apply (Applies1 fs) a = Applies fs a + +type family AppliesCon (fs :: [k ~> k]) (z :: k) :: k where + AppliesCon '[] x = x + AppliesCon (f ': fs) x = Apply f (AppliesCon fs x) + +data AppliesCon2 :: [k ~> k] ~> k ~> k + +data AppliesCon1 (fs :: [k ~> k]) :: k ~> k + +type instance Apply AppliesCon2 fs = AppliesCon1 fs + +type instance Apply (AppliesCon1 fs) x = AppliesCon fs x + +sLength :: SList xs -> SNat (Length xs) +sLength SNil = sKnownVal' +sLength (_ :% rest) = sKnownVal' @1 %+ sLength rest + +sIndexed :: SList xs -> SList (Indexed xs) +sIndexed = sIndexedAux $ sKnownVal' @0 + +sIndexedAux :: SNat n -> SList xs -> SList (IndexedAux n xs) +sIndexedAux _ SNil = SNil +sIndexedAux n (x :% xs) = + SPair n x :% sIndexedAux (n %+ sKnownVal' @1) xs + +infixr 5 %++ + +(%++) :: SList xs -> SList ys -> SList (xs ++ ys) +SNil %++ ys = ys +(x :% xs) %++ ys = x :% (xs %++ ys) + +allAppendDict :: + forall c xs ys. + (KnownTyList xs, KnownTyList ys, All c xs, All c ys) => + Dict (All c (xs ++ ys)) +allAppendDict = go (tyListSkeleton @xs) (tyListSkeleton @ys) + where + go :: + (All c as, All c bs) => + PList as -> + PList bs -> + Dict (All c (as ++ bs)) + go PNil _ = Dict + go (PCons _ xs) ys = withDict (go xs ys) Dict + +withAllAppend :: + forall c xs ys r. + (KnownTyList xs, KnownTyList ys, All c xs, All c ys) => + ((All c (xs ++ ys)) => r) -> + r +withAllAppend = withDict (allAppendDict @c @xs @ys) diff --git a/elgenerics-known/src/Data/TypeLevel/List/Core.hs b/elgenerics-known/src/Data/TypeLevel/List/Core.hs new file mode 100644 index 0000000..9080a80 --- /dev/null +++ b/elgenerics-known/src/Data/TypeLevel/List/Core.hs @@ -0,0 +1,135 @@ +{-# LANGUAGE AllowAmbiguousTypes #-} +{-# LANGUAGE DataKinds #-} +{-# LANGUAGE GADTs #-} +{-# LANGUAGE MagicHash #-} +{-# LANGUAGE TypeFamilies #-} +{-# LANGUAGE UndecidableInstances #-} +{-# OPTIONS_GHC -fplugin GHC.TypeLits.KnownNat.Solver #-} + +module Data.TypeLevel.List.Core where + +import Data.TypeLevel.Function +import Data.TypeLevel.Ord.Internal +import GHC.Exts +import GHC.TypeLits +import Unsafe.Coerce (unsafeCoerce) + +type family Length (as :: [k]) where + Length '[] = 0 + Length (_ ': as) = 1 + Length as + +data Length1 :: [k] ~> Nat + +type instance Apply Length1 ks = Length ks + +type SortBy cmp ks = SortByAux cmp (Length ks) ks + +type family SortByAux cmp n ks where + SortByAux _ _ '[] = '[] + SortByAux _ _ '[x] = '[x] + SortByAux cmp n xs = + MergeBy + cmp + (SortByAux cmp (n `Div` 2) (Take (n `Div` 2) xs)) + (SortByAux cmp (n - (n `Div` 2)) (Drop (n `Div` 2) xs)) + +type family Take (n :: Nat) (as :: [k]) :: [k] where + Take 0 _ = '[] + Take n (x ': xs) = x ': Take (n - 1) xs + Take _ _ = '[] + +type family Drop (n :: Nat) (as :: [k]) :: [k] where + Drop 0 xs = xs + Drop n (x ': xs) = Drop (n - 1) xs + Drop _ '[] = '[] + +type family + MergeBy + (cmp :: k ~> k ~> Ordering) + (ls :: [k]) + (rs :: [k]) :: + [k] + where + MergeBy _ '[] rs = rs + MergeBy _ ls '[] = ls + MergeBy cmp (x ': xs) (y ': ys) = + CaseOrdering + (Apply (Apply cmp x) y) + (x ': MergeBy cmp xs (y ': ys)) + (x ': y ': MergeBy cmp xs ys) + (y ': MergeBy cmp (x ': xs) ys) + +type family ElemAt (n :: Nat) ts where + ElemAt 0 (t ': ts) = t + ElemAt n (_ ': ts) = ElemAt (n - 1) ts + ElemAt _ _ = TypeError ('Text "Index out of bounds") + +type Index (a :: k) (ts :: [k]) = Index' a ts '[] + +type family Index' (a :: k) (ts :: [k]) (rs :: [k]) where + Index' a (a ': _) _ = 0 + Index' a (b ': as) rs = 1 + Index' a as (Snoc rs b) + Index' a '[] rs = + TypeError + ( 'Text "A type `" + ':<>: 'ShowType a + ':<>: 'Text "' is not an element of " + ':<>: 'ShowType rs + ) + +type family Snoc (rs :: [k]) (a :: k) where + Snoc '[] a = '[a] + Snoc (b ': bs) a = b ': Snoc bs a + +type Member a as = (KnownNat (Index a as)) + +type family MapApply (n :: k ~> k') (as :: [k]) :: [k'] where + MapApply _ '[] = '[] + MapApply n (a ': as) = Apply n a ': MapApply n as + +data MapApply1 (f :: k ~> k') :: [k] ~> [k'] + +type instance Apply (MapApply1 f) xs = MapApply f xs + +type family Map f as where + Map _ '[] = '[] + Map f (a ': as) = f a ': Map f as + +type family (++) as bs where + (a ': as) ++ bs = a ': (as ++ bs) + '[] ++ bs = bs + +type Indexed (as :: [a]) = IndexedAux 0 as + +type family IndexedAux n xs where + IndexedAux _ '[] = '[] + IndexedAux n (x ': xs) = '(n, x) ': IndexedAux (n + 1) xs + +type KnownTyList xs = KnownNat (Length xs) + +data PList (xs :: [k]) where + PNil :: PList '[] + PCons :: Proxy# x -> PList xs -> PList (x ': xs) + +tyListSkeleton :: + forall xs. + (KnownTyList xs) => + PList xs +tyListSkeleton = go (tyListLength @xs) + where + go :: forall ys. Word -> PList ys + {-# INLINE go #-} + go !0 = unsafeCoerce $ PNil + go n = unsafeCoerce $ PCons (proxy# :: Proxy# Any) $ go (n - 1) + +tyListLength :: forall xs. (KnownTyList xs) => Word +tyListLength = fromIntegral $ natVal' @(Length xs) proxy# + +type family Matches x xs where + Matches x (x ': xs) = x ': Matches x xs + Matches x (_ ': xs) = Matches x xs + Matches _ '[] = '[] + +data Matches1 (x :: k) :: [k] ~> [k] + +type instance Apply (Matches1 x) xs = Matches x xs diff --git a/elgenerics-known/src/Data/TypeLevel/List/Overloaded.hs b/elgenerics-known/src/Data/TypeLevel/List/Overloaded.hs new file mode 100644 index 0000000..26d4d49 --- /dev/null +++ b/elgenerics-known/src/Data/TypeLevel/List/Overloaded.hs @@ -0,0 +1,93 @@ +{-# LANGUAGE AllowAmbiguousTypes #-} +{-# LANGUAGE CPP #-} +{-# LANGUAGE DataKinds #-} +{-# LANGUAGE GADTs #-} +{-# LANGUAGE OverloadedStrings #-} +{-# LANGUAGE RecordWildCards #-} +{-# LANGUAGE TypeFamilies #-} + +module Data.TypeLevel.List.Overloaded (plugin, PElement, PIsList (..)) where + +import Data.Generics (everywhere, mkT) +import GHC +#if MIN_VERSION_ghc(9,0,1) +#if MIN_VERSION_ghc(9,2,0) +import GHC.Unit.Finder +import GHC.Types.TyThing +#else +import GHC.Driver.Finder +#endif +import GHC.Tc.Utils.Monad +import GHC.Plugins +import GHC.Iface.Env (lookupOrig) +#else +import Finder +import GhcPlugins +import IfaceEnv +import TcRnMonad +#endif + +type family PElement ty + +class PIsList ty where + type FromList (as :: [PElement ty]) :: ty + type Cons (a :: PElement ty) (as :: ty) :: ty + type Empty :: ty + +type instance PElement [a] = a + +instance PIsList [a] where + type FromList xs = xs + type Cons x xs = x ': xs + type Empty = '[] + +plugin :: Plugin +plugin = + defaultPlugin + { renamedResultAction = overloadTyLists + , pluginRecompile = purePlugin + } + +data Symbols = Symbols + { emptySymbol :: TyCon + , consSymbol :: TyCon + , fromListSymbol :: TyCon + } + +overloadTyLists :: + [CommandLineOption] -> + TcGblEnv -> + HsGroup GhcRn -> + TcM (TcGblEnv, HsGroup GhcRn) +overloadTyLists _ gblEnv grp = do + env <- getTopEnv + Found _ ovlMod <- + liftIO $ findPluginModule env $ mkModuleName "Data.TypeLevel.List.Overloaded" + fromListSymbol <- lookupTyCon =<< lookupOrig ovlMod (mkTcOcc "FromList") + consSymbol <- lookupTyCon =<< lookupOrig ovlMod (mkTcOcc "Cons") + emptySymbol <- lookupTyCon =<< lookupOrig ovlMod (mkTcOcc "Empty") + let symbs = Symbols {..} + pure (gblEnv, everywhere (mkT $ overloadTy symbs) grp) + +defTyVarX :: XTyVar GhcRn +#if MIN_VERSION_ghc(9,2,5) +defTyVarX = EpAnnNotUsed +#else +defTyVarX = NoExtField +#endif + +noLoc' :: e -> GenLocated (SrcSpanAnn' (EpAnn ann)) e +noLoc' = L (SrcSpanAnn EpAnnNotUsed generatedSrcSpan) + +overloadTy :: Symbols -> HsType GhcRn -> HsType GhcRn +overloadTy Symbols {..} (HsExplicitListTy _ _ []) = + HsTyVar defTyVarX NotPromoted $ noLoc' $ tyConName emptySymbol +overloadTy Symbols {..} tyList@(HsExplicitListTy {}) = + HsAppTy + NoExtField + (noLoc' $ HsTyVar defTyVarX NotPromoted (noLoc' $ tyConName fromListSymbol)) + $ noLoc' tyList +overloadTy Symbols {..} (HsOpTy _ l (L loc nam) r) + | nam == consDataConName = + HsOpTy NoExtField l (L loc $ tyConName consSymbol) r +overloadTy _ ty = ty diff --git a/elgenerics-known/src/Data/TypeLevel/List/Properties.hs b/elgenerics-known/src/Data/TypeLevel/List/Properties.hs new file mode 100644 index 0000000..eba67e0 --- /dev/null +++ b/elgenerics-known/src/Data/TypeLevel/List/Properties.hs @@ -0,0 +1,27 @@ +{-# LANGUAGE DataKinds #-} + +module Data.TypeLevel.List.Properties where + +import Data.TypeLevel.Function + +class PreservesLength p + +class + MonotoneApply + (p :: a ~> b) + (cmp1 :: a ~> a ~> Ordering) + (cmp2 :: b ~> b ~> Ordering) + +class + Monotone + (p :: a -> b) + (cmp1 :: a ~> a ~> Ordering) + (cmp2 :: b ~> b ~> Ordering) + +instance MonotoneApply Id1 c c + +instance PreservesLength Id1 + +instance (Monotone f c d) => MonotoneApply (Con f) c d + +instance (PreservesLength f) => PreservesLength (Con f) diff --git a/elgenerics-known/src/Data/TypeLevel/List/Solver.hs b/elgenerics-known/src/Data/TypeLevel/List/Solver.hs new file mode 100644 index 0000000..a7f55de --- /dev/null +++ b/elgenerics-known/src/Data/TypeLevel/List/Solver.hs @@ -0,0 +1,101 @@ +{-# LANGUAGE CPP #-} +{-# LANGUAGE DataKinds #-} +{-# LANGUAGE GADTs #-} +{-# LANGUAGE LambdaCase #-} +{-# LANGUAGE OverloadedStrings #-} +{-# LANGUAGE RecordWildCards #-} + +module Data.TypeLevel.List.Solver where + +#if MIN_VERSION_ghc(9,0,1) +import GHC.Plugins hiding (TcPlugin, (<>)) +#elif MIN_VERSION_ghc(8,8,1) +import GhcPlugins hiding (TcPlugin, (<>)) +#else +import GhcPlugins hiding ((<>)) +#endif + +#if MIN_VERSION_ghc(9,0,1) +import GHC.Tc.Types.Constraint +import GHC.Tc.Plugin hiding (newGiven, newWanted) +import GHC.Tc.Types +#else +import Constraint +import TcPluginM hiding (newGiven, newWanted) +import TcRnTypes +#endif + +import Control.Arrow ((&&&)) +import Data.IORef +import Data.Map.Strict qualified as Map +import Data.Maybe +import Data.Set qualified as Set +import Data.TypeLevel.List () +import Data.TypeLevel.List.Solver.Constraint +import Data.TypeLevel.List.Solver.Free +import Data.TypeLevel.List.Solver.Generation +import Data.TypeLevel.List.Solver.Syntax +import GHC.TcPluginM.Extra + +plugin :: Plugin +plugin = + defaultPlugin + { tcPlugin = const $ Just checker + , pluginRecompile = const $ return NoForceRecompile + } + +checker :: TcPlugin +checker = + TcPlugin + { tcPluginInit = do + LSS + <$> tcPluginIO (newIORef Set.empty) + <*> setupSymbolTable + <*> tcPluginIO (newIORef Set.empty) + <*> tcPluginIO (newIORef Set.empty) + <*> tcPluginIO (newIORef Map.empty) + <*> tcPluginIO (newIORef Map.empty) + , tcPluginSolve = solve + , tcPluginStop = \(LSS ref _ ref2 ref3 ref4 ref5) -> do + tcPluginIO $ do + writeIORef ref Set.empty + writeIORef ref2 Set.empty + writeIORef ref3 Set.empty + writeIORef ref4 Map.empty + writeIORef ref5 Map.empty + } + +solve :: + ListSolverState -> + [Ct] -> + [Ct] -> + [Ct] -> + TcPluginM TcPluginResult +-- 簡約ステップ:Given として与えられた制約と、 +-- IORef 越しに渡された制約の部分式から、わかる限りの +-- 非自明な等式を生成する。 +-- +solve lss givens [] [] = + TcPluginOk [] + <$> generateNontrivials + lss + givens +-- 制約解消ステップ。運が良ければ呼ばれないが、簡約ステップで所与 +-- の制約だけで駄目な場合、改めて必要な制約を Wanted したりする。 +solve (LSS _ stbl@STbl {} ref doneRef eqDicRef normSt) givens _dervds wanteds = do + tcPluginTrace "LIST: Started with givens" $ ppr givens + tcPluginTrace "LIST: Started with wanteds" $ + ppr + (wanteds, map ((id &&& typeKind) . fst . splitAppTys . ctPred) wanteds) + tcPluginTrace "LIST: Started with deriveds" $ ppr _dervds + let subs = map fst $ mkSubst' givens + ps = + map + (WithCtLoc <$> ctLoc <*> toConstr stbl . ctPred . substCt subs) + wanteds + dones <- tcPluginIO $ readIORef doneRef + tcPluginIO $ writeIORef ref $ Set.fromList ps Set.\\ dones + (es, needss) <- + unzip . catMaybes + <$> mapM (solveConstr subs stbl eqDicRef normSt givens) wanteds + return $ TcPluginOk es $ concat needss diff --git a/elgenerics-known/src/Data/TypeLevel/List/Solver/Constraint.hs b/elgenerics-known/src/Data/TypeLevel/List/Solver/Constraint.hs new file mode 100644 index 0000000..ffb8f71 --- /dev/null +++ b/elgenerics-known/src/Data/TypeLevel/List/Solver/Constraint.hs @@ -0,0 +1,656 @@ +{-# LANGUAGE CPP #-} +{-# LANGUAGE DataKinds #-} +{-# LANGUAGE DerivingStrategies #-} +{-# LANGUAGE GADTs #-} +{-# LANGUAGE LambdaCase #-} +{-# LANGUAGE MultiWayIf #-} +{-# LANGUAGE OverloadedStrings #-} +{-# LANGUAGE RecordWildCards #-} +{-# LANGUAGE ViewPatterns #-} + +module Data.TypeLevel.List.Solver.Constraint where + +import Control.Applicative +import Control.Monad +import Data.Foldable (foldl') +import Data.Foldable qualified as F +import Data.Functor +import Data.IORef +import Data.Map.Strict qualified as M +import Data.Maybe (mapMaybe) +import Data.Set qualified as S +import Data.TypeLevel.List.Solver.Free +import Data.TypeLevel.List.Solver.Reduce +import Data.TypeLevel.List.Solver.Syntax +import Data.TypeLevel.List.Solver.Utils +import GHC.Stack +import GHC.TcPluginM.Extra +#if MIN_VERSION_ghc(9,0,1) +import GHC.Core.Class (Class (classTyCon)) +import GHC.Tc.Types.Constraint +import GHC.Plugins hiding ((<>)) +import GHC.Core.Predicate +import GHC.Tc.Types.Evidence +import GHC.Tc.Plugin hiding (newGiven, newWanted) +import GHC.Types.Id.Make +#else +import Class (Class (classTyCon)) +import Constraint +import GhcPlugins hiding ((<>)) +import MkId (proxyHashId) +import Predicate +import TcEvidence +import TcPluginM hiding (newGiven, newWanted) +#endif + +-- type EvidenceDic = Map WType CtEvidence + +solveConstr :: + [(TcTyVar, Type)] -> + SymbolTable -> + IORef EvidenceDic -> + IORef Normalisation -> + [Ct] -> + Ct -> + TcPluginM (Maybe ((Witness, Ct), [Ct])) +solveConstr subs stbl evDicRef norms givens ct = do + let p = ctPred $ substCt subs ct + cnstr = toConstr stbl p + mresl <- runSolveMode subs stbl evDicRef norms givens ct (doSolve' cnstr) + return (mresl <&> \(a, cts) -> ((a, ct), cts)) + +sortMonotone :: + (HasCallStack) => + FunType -> + Kind -> -- Domain Kind + Kind -> -- Codomain Kind + Term -> -- (Un)curried Function + Term -> -- Compare on Domain + Term -> -- Compare on Codomain + Term -> -- Target list + Term -> -- LHS + Term -> -- RHS + Solver Witness +sortMonotone b dom cod h cmpDom cmpCod _ lhs rhs = do + void $ require $ Monotone b dom cod h cmpDom cmpCod + tbl <- getSymbolTable + return $ evCoercion $ trustMeNominal (fromTerm tbl lhs) (fromTerm tbl rhs) + +decompInnerMember :: + Constr -> Maybe (IsWrapped, Maybe FunType, Kind, Term, Term) +decompInnerMember + (Member b _ (Apply fTy h' x) (Map _ k _ h xs)) + | h' == h = return (b, Just fTy, k, x, xs) +decompInnerMember + ( Member + b + _ + (UnknownTyConApp con args) + (Map _ k _ (UnknownTyConApp con' args') xs) + ) + | con == con' && init args == args' = do + let mb = case tyConInjectivityInfo con of + Injective bs | last bs -> Just Bare + _ | isDataFamilyTyCon con || isDataTyCon con -> Just Bare + _ -> Nothing + return (b, mb, k, last args, xs) +decompInnerMember _ = Nothing + +sing :: Type -> Term -> Solver EvExpr +sing a x = do + stbl@STbl {..} <- getSymbolTable + knownX <- require $ Known a x + let xTy = fromTerm stbl x + theSing = + foldl1' + App + [ Var sKnownVal'FunId + , Type a + , Type xTy + , dictExpr knownX + ] + pure theSing + +mkLocalVar' :: IdDetails -> Name -> Type -> IdInfo -> Id +#if MIN_VERSION_ghc(9,0,1) +mkLocalVar' idflab nam = mkLocalVar idflab nam Many +#else +mkLocalVar' = mkLocalVar +#endif + +doSolve' :: (HasCallStack) => Constr -> Solver Witness +doSolve' + ( EqType + NomEq + l@(Map b k k' h (SortByAux _ cmp _ xs)) + r@(SortByAux _ cmp' _ (Map b' _ _ h' xs')) + ) + | h == h' && xs == xs' && b == b' = + sortMonotone b k k' h cmp cmp' xs l r +doSolve' + ( EqType + NomEq + l@(SortByAux _ cmp' _ (Map b' _ _ h' xs')) + r@(Map b k k' h (SortByAux _ cmp _ xs)) + ) + | h == h' && xs == xs' && b == b' = + sortMonotone b k k' h cmp cmp' xs l r +doSolve' (EqType NomEq l r) = do + stbl <- getSymbolTable + let (l', r') = (reduce l, reduce r) + guard + ( not $ + fromTerm stbl l + `eqType` fromTerm stbl l' + && fromTerm stbl r + `eqType` fromTerm stbl r' + ) + unless (l' == r') $ + void $ + require (EqType NomEq l' r') + return $ evCoercion $ trustMeNominal (fromTerm stbl l) (fromTerm stbl r) +doSolve' (decompInnerMember -> Just (b, _, k, x, xs)) = + unsafeDicToWitnessM =<< require (Member b k x xs) +doSolve' (Member _ _ (ElemAt _ n xs) xs') | xs == xs' = do + unsafeDicToWitnessM =<< require (KnownNat n) +doSolve' (KnownNat (Length k inner)) = + case inner of + Map _ a _ _ xs -> + unsafeDicToWitnessM =<< require (KnownNat (Length a xs)) + SortByAux _ _ _ xs -> + unsafeDicToWitnessM =<< require (KnownNat (Length k xs)) + Indexed k' xs -> + unsafeDicToWitnessM =<< require (KnownNat (Length k' xs)) + _ -> mzero +doSolve' (SortedBy k cmp (SortByAux _ cmp' _ _)) | cmp == cmp' = do + unsafeDicToWitnessM =<< require (SortedBy k cmp (EmptyList k)) +doSolve' (SortedBy k cmp (Map fty a _ h xs)) = do + let cmp2 = Compare2 a + void $ require $ Monotone fty a k h cmp2 cmp + unsafeDicToWitnessM =<< require (SortedBy a cmp2 xs) +doSolve' cwhole@(MaybeC _v' c (MapMaybeApp _ _v'' t (LookupWithIndexOM k v l dic))) = do + stbl@STbl {..} <- getSymbolTable + let fTy = fromTerm stbl t + instHead = fromConstr stbl cwhole + case splitTyConApp_maybe fTy of + Just (con, _) | con == fst1TyCon -> do + let cTy = fromTerm stbl c + lTy = fromTerm stbl l + dicTy = fromTerm stbl dic + knownL <- require $ Known k l + allOMDic <- + require $ + AllOM + k + v + (UnknownTerm $ mkTyConApp entryCTyCon [k, v, cTy]) + dic + let mkDicDataCon = tyConSingleDataCon constsDictTyCon + cDictGoal = mkTyConApp constsDictTyCon [instHead] + cDictLookup = + mkTyConApp + constsDictTyCon + [ fromConstr stbl $ + MaybeC _v' c (UnknownTyConApp lookupOMTyCon [UnknownTerm k, UnknownTerm v, l, dic]) + ] + sOrdDic <- require $ UnknownC $ mkTyConApp sOrdTyCon [k] + let getter = + foldl1' + App + [ Var elimMaybeCLookup'FunId + , Type k + , Type v + , Type cTy + , Type lTy + , Type dicTy + , dictExpr sOrdDic + , dictExpr knownL + , dictExpr allOMDic + ] + `Cast` trustMe' + "doSolve'/MaybeC(Lookup)" + cDictLookup + cDictGoal + uq <- liftTcPluginM newUnique + let nam = mkInternalName uq (mkVarOcc "$fs") noSrcSpan + var = mkLocalVar' VanillaId nam cDictGoal vanillaIdInfo + dicVar <- liftTcPluginM $ newEvVar instHead + pure $ + EvExpr $ + Case + getter + var + instHead + [Alt (DataAlt mkDicDataCon) [dicVar] $ Var dicVar] + _ -> doSolve' $ UnknownC $ fromConstr stbl cwhole +doSolve' knwn@(Known mb e@(MapMaybeApp a b f x)) = do + tbl@STbl {..} <- getSymbolTable + let fTy = fromTerm tbl f + xTy = fromTerm tbl x + instHead = fromConstr tbl knwn + eTy = fromTerm tbl e + singX <- sing (mkTyConApp maybeTyCon [a]) x + sApplyFDic <- require $ UnknownC $ mkTyConApp (classTyCon sApplyClass) [a, b, fTy] + let theSing = + foldl1' + App + [ Var sFMapMaybe'FunId + , Type a + , Type b + , Type fTy + , Type xTy + , dictExpr sApplyFDic + , foldl1' App [Var proxyHashId, Type (a ~> b), Type fTy] + , singX + ] + `Cast` trustMe' "doSolve'/MapMaybe" (mkTyConApp singTyCon [mb, eTy]) instHead + pure $ EvExpr theSing +doSolve' knownLWI@(Known may lwi@(LookupWithIndexOM k v l dic)) = do + tbl@STbl {..} <- getSymbolTable + let lTy = fromTerm tbl l + ordMapTy = mkTyConApp ordMapTyCon [k, v] + lwiE = fromTerm tbl lwi + dicTy = fromTerm tbl dic + instHead = fromConstr tbl knownLWI + lSing <- sing k l + dicSing <- sing ordMapTy dic + sordDic <- require $ UnknownC $ mkTyConApp sOrdTyCon [k] + let looked = + foldl1' + App + [ Var sLookupWithIndex'FunId + , Type k + , Type v + , Type lTy + , Type dicTy + , dictExpr sordDic + , lSing + , dicSing + ] + `Cast` trustMe' + "doSolve'/KnownLWI" + (mkTyConApp singTyCon [may, lwiE]) + instHead + pure $ EvExpr looked +doSolve' (KnownTyList _ inner) = do + mdecons <- deconsKTL inner + case mdecons of + InnerList k' as -> + unsafeDicToWitnessM =<< require (KnownTyList k' as) + InnerOrdMap k v dic -> + unsafeDicToWitnessM =<< require (KnownNat (SizeOM k v dic)) +doSolve' c = do + tbl <- getSymbolTable + givens <- getGivens + let prd = fromConstr tbl c + case splitAppTys prd of + (cnstr, args) + | not (null args) + , let targ = toTerm tbl $ last args + , FromMaybe k def may <- targ -> + solveFromMaybeC (foldl' mkAppTy cnstr $ init args) k def may + _ -> do + Just (clsHead, targ) <- + return $ + do + (cls, args) <- getClassPredTys_maybe prd + guard $ not $ null args + let (hdr, targ) = head <$> splitAt (length args - 1) args + clsHead = mkClassPred cls hdr + return (clsHead, targ) + <|> do + (con, args) <- splitTyConApp_maybe prd + guard $ not $ null args + let (hdr, targ) = head <$> splitAt (length args - 1) args + clsHead = mkTyConApp con hdr + return (clsHead, targ) + <|> splitAppTy_maybe prd + + amd : _ <- + return $ + findAllMembers tbl (toTerm tbl clsHead) (toTerm tbl targ) givens + EvExpr <$> generateDicFromAll amd + +solveFromMaybeC :: Type -> Kind -> Term -> Term -> Solver Witness +solveFromMaybeC c k def may = do + stbl <- getSymbolTable + let instHead = c `mkAppTy` fromTerm stbl (FromMaybe k def may) + maybeCDic <- require (MaybeC k (UnknownTerm c) may) + defDic <- require (UnknownC $ c `mkAppTy` fromTerm stbl def) + knownDic <- require $ Known (mkTyConApp maybeTyCon [k]) may + let getter = + foldl1 + App + [ Var $ elimFromMaybeC'FunId stbl + , Type k + , Type c + , Type $ fromTerm stbl def + , Type $ fromTerm stbl may + , dictExpr defDic + , dictExpr maybeCDic + , dictExpr knownDic + ] + uq <- liftTcPluginM newUnique + let mkDicDataCon = tyConSingleDataCon $ constsDictTyCon stbl + nam = mkInternalName uq (mkVarOcc "$fs") noSrcSpan + v = mkLocalVar' VanillaId nam (mkTyConApp (constsDictTyCon stbl) [instHead]) vanillaIdInfo + dicVar <- liftTcPluginM $ newEvVar instHead + pure $ + EvExpr $ + Case + getter + v + instHead + [Alt (DataAlt mkDicDataCon) [dicVar] $ Var dicVar] + +generateDicFromAll :: AllMemberDic -> Solver EvExpr +generateDicFromAll AllMemberDic {..} = do + tbl@STbl {..} <- getSymbolTable + let chd = fromTerm tbl classHead + x = fromTerm tbl element + k = typeKind x + uq <- liftTcPluginM newUnique + let instHead = chd `mkAppTy` x + dicVar <- liftTcPluginM $ newEvVar instHead + let nam = mkInternalName uq (mkVarOcc "$fs") noSrcSpan + xs = fromTerm tbl superList + concDicType = mkTyConApp allDicTyCon [k, chd, x, xs] + v = mkLocalVar' VanillaId nam concDicType vanillaIdInfo + getter = + foldl1 + App + [ Var reifyDicId + , Type k + , Type chd + , Type x + , Type xs + , memberDic + , allDic + ] + let mkDicDataCon = tyConSingleDataCon allDicTyCon + return $ + Case + getter + v + instHead + [Alt (DataAlt mkDicDataCon) [dicVar] $ Var dicVar] + +generateDicFromAllOM :: + -- | key kind + Kind -> + -- | val kind + Kind -> + -- | Lookup' x dic + Type -> + AllMemberDic -> + Solver EvExpr +generateDicFromAllOM + key + val + lookuped + AllMemberDic {..} = do + tbl@STbl {..} <- getSymbolTable + let chd = fromTerm tbl classHead + xs = fromTerm tbl superList + x = fromTerm tbl element + uq <- liftTcPluginM newUnique + liftTcPluginM $ + tcPluginTrace "LIST: instheads" $ + ppr ((chd, typeKind chd), (x, typeKind x), (lookuped, typeKind lookuped)) + let instHead = instBinaryPred chd x lookuped + nam = mkInternalName uq (mkVarOcc "$fsOMAllMemDecons") noSrcSpan + concDicType = mkTyConApp constsDictTyCon [oldInstHead] + oldLooked = fromTerm tbl $ Lookup'OM key val element superList + oldInstHead = (chd `mkAppTy` x) `mkAppTy` oldLooked + v = mkLocalVar' VanillaId nam concDicType vanillaIdInfo + getter = + foldl1 + App + [ Var allOMDict'FunId + , Type key + , Type val + , Type chd + , Type xs + , Type x + , allDic + , memberDic + ] + let mkDicDataCon = tyConSingleDataCon constsDictTyCon + dicVar <- liftTcPluginM $ newEvVar oldInstHead + return $ + Case + getter + v + instHead + [ Alt + (DataAlt mkDicDataCon) + [dicVar] + $ Var dicVar + `Cast` trustMe' "generateDicFromAllOM" oldInstHead instHead + ] + +instBinaryPred :: Type -> Type -> Type -> Type +instBinaryPred clsHead lab val = + mkAppTys clsHead [lab, val] + +data DecomposedKnownTyList + = InnerList {elKind :: Kind, innerTerm :: Term} + | InnerOrdMap {dKeyKind :: Kind, dValKind :: Kind, innerTerm :: Term} + +deconsKTL :: Term -> Solver DecomposedKnownTyList +deconsKTL = deconsListTerm False + +deconsMember :: Term -> Solver DecomposedKnownTyList +deconsMember = deconsListTerm True + +deconsListTerm :: + -- | 単射の場合のみ同一視するか? + Bool -> + Term -> + Solver DecomposedKnownTyList +deconsListTerm _ (SortByAux k _ _ xs) = return $ InnerList k xs +deconsListTerm False (Map _ a _ _ xs) = return $ InnerList a xs +deconsListTerm True (Map Bare a _ _ xs) = return $ InnerList a xs +deconsListTerm _ (Indexed k xs) = return $ InnerList k xs +deconsListTerm _ (ToListOM k v dic) = do + return $ InnerOrdMap k v dic +deconsListTerm _ (ToListAuxOM k v EmptyList {} dic) = do + return $ InnerOrdMap k v dic +deconsListTerm _ (UnknownTerm ty) + | Just (con, args) <- splitTyConApp_maybe ty + , not (null args) = do + let xs = last args + k' = typeKindElem xs + void $ + require $ + PreservesLength (UnknownTerm $ mkTyConApp con (init args)) + return $ InnerList k' (UnknownTerm xs) +deconsListTerm _ _ = mzero + +data AllMemberDic = AllMemberDic + { classHead :: Term + , superList :: Term + , element :: Term + , memberDic :: CoreExpr + , isMemberWrapped :: IsWrapped + , allDic :: CoreExpr + } + +findAllMembers :: + SymbolTable -> + -- | Class tycon + Term -> + -- | Target term + Term -> + -- | Constraint + Givens -> + [AllMemberDic] +findAllMembers senv@STbl {} clsType targ cDic = + let kind = typeKind $ fromTerm senv targ + (mems, alls) = + M.foldMapWithKey + ( \c ct -> case c of + Member b _ x xs + | x == targ -> (M.singleton xs (b, ct), M.empty) + All k cns xs + | cns == clsType + , k `eqType` kind -> + (M.empty, M.singleton xs ct) + _ -> mempty + ) + cDic + targKey = + M.keysSet mems `S.intersection` M.keysSet alls + in [ AllMemberDic + { classHead = clsType + , superList = xs + , element = targ + , memberDic = buildMemDic senv targ xs $ snd $ mems M.! xs + , isMemberWrapped = fst $ mems M.! xs + , allDic = ctEvExpr $ alls M.! xs + } + | xs <- S.toList targKey + ] + +{- +-- List の場合と異なり、(Member v xs) から c v (Lookup' v xs) +-- までしか言えず、c v x を解決する際には (x ~ Lookup' v xs) +-- が必要になる。どうするか考えものなので、ちょっと考える。 +findAllOMMembers + :: SymbolTable + -> Term -- ^ Class tycon + -> Term -- ^ Target key term + -> Term -- ^ Target value term + -> Givens -- ^ Constraint + -> [(Kind, Kind, AllMemberDic)] +-} +decompOMAlls :: + Solver [Ct] +decompOMAlls = do + givens <- getGivens + tbl <- getSymbolTable + + let kns = + M.mapKeysMonotonic + ( \case + KnownNat n -> n + _ -> error "Could not happen!" + ) + $ M.filterWithKey + ( \case + KnownNat {} -> const True + _ -> const False + ) + givens + let alls = + [ ( k + , v + , l + , AllMemberDic + { classHead = c + , superList = xs + , element = x + , memberDic = buildMemOMDic tbl k v x xs memD + , isMemberWrapped = True + , allDic = ctEvExpr allD + } + , ctev_loc allD + ) + | (AllOM k v c xs, allD) <- M.toList givens + , let dic = + M.fromListWith (<>) $ + map (\elkey -> (omLabel elkey, elkey)) $ + mapMaybe (uncurry $ decompOMMember kns k v xs) $ + M.toList givens + , elKeyDics <- F.toList dic + , let (x, l, memD) = (omLabel elKeyDics, omValue elKeyDics, omDic elKeyDics) + ] + forM alls $ \(k, v, l, amd@AllMemberDic {..}, loc) -> do + let c = fromTerm tbl classHead + x = fromTerm tbl element + let lookedup = fromTerm tbl l + prd = + foldl1' + mkAppTy + [c, x, lookedup] + ev <- EvExpr <$> generateDicFromAllOM k v lookedup amd + mkNonCanonical' loc <$> liftTcPluginM (newGiven loc prd ev) + +decompAlls :: + Solver [Ct] +decompAlls = do + givens <- getGivens + tbl <- getSymbolTable + let alls = + [ ( fromTerm tbl c `mkAppTy` fromTerm tbl x + , AllMemberDic + { classHead = c + , superList = xs + , element = x + , memberDic = buildMemDic tbl x xs memD + , isMemberWrapped = b + , allDic = ctEvExpr allD + } + , ctev_loc allD + ) + | (All k c xs, allD) <- M.toList givens + , (Member b _ x _, memD) <- + filter (isMemberOfC k xs . fst) $ + M.toList givens + ] + forM alls $ \(prd, amd, loc) -> do + ev <- EvExpr <$> generateDicFromAll amd + mkNonCanonical' loc <$> liftTcPluginM (newGiven loc prd ev) + +isMemberOfC :: + Kind -> Term -> Constr -> Bool +isMemberOfC k xs (Member _ k' _ ys) + | xs == ys && k `eqType` k' = True +isMemberOfC _ _ _ = False + +data OMElemKey + = OMDefiniteElemKey {omLabel :: Term, omValue :: Term, omDic :: CtEvidence} + | OMDynamicElemKey {omLabel :: Term, omValue :: Term, omDic :: CtEvidence} + +type KnownNats = M.Map Term CtEvidence + +instance Semigroup OMElemKey where + l@OMDefiniteElemKey {} <> _ = l + OMDynamicElemKey {} <> r@OMDefiniteElemKey {} = r + l@OMDynamicElemKey {} <> OMDynamicElemKey {} = l + +decompOMMember :: + KnownNats -> Kind -> Kind -> Term -> Constr -> CtEvidence -> Maybe OMElemKey +decompOMMember + kns + k + v + xs + ( EqType + NomEq + (LookupWithIndexOM k' v' l ys) + (PromotedJust _ (PromotedTuple _ _ value n)) + ) + _ + | Just dic <- M.lookup n kns + , xs == ys + , k `eqType` k' + , eqType v v' = + Just $ OMDefiniteElemKey l value dic +decompOMMember _ k v xs (MemberOM _ k' v' l ys) dic + | xs == ys && k `eqType` k' && eqType v v' = + Just $ OMDynamicElemKey l (Lookup'OM k' v' l ys) dic +decompOMMember _ _ _ _ _ _ = Nothing + +buildMemDic :: + SymbolTable -> Term -> Term -> CtEvidence -> CoreExpr +buildMemDic stbl x xs ctev = + let k = typeKind $ fromTerm stbl x + memTy = fromConstr stbl (Member True k x xs) + in ctEvExpr ctev `Cast` trustMe' "walkMemPath" (ctEvPred ctev) memTy + +buildMemOMDic :: + SymbolTable -> Kind -> Kind -> Term -> Term -> CtEvidence -> CoreExpr +buildMemOMDic stbl key val x xs ctev = + let memTy = fromConstr stbl (MemberOM True key val x xs) + in ctEvExpr ctev `Cast` trustMe' "buildMemOMDic" (ctEvPred ctev) memTy diff --git a/elgenerics-known/src/Data/TypeLevel/List/Solver/Free.hs b/elgenerics-known/src/Data/TypeLevel/List/Solver/Free.hs new file mode 100644 index 0000000..8355660 --- /dev/null +++ b/elgenerics-known/src/Data/TypeLevel/List/Solver/Free.hs @@ -0,0 +1,329 @@ +{-# LANGUAGE CPP #-} +{-# LANGUAGE DerivingStrategies #-} +{-# LANGUAGE GADTs #-} +{-# LANGUAGE LambdaCase #-} +{-# LANGUAGE TypeFamilies #-} +{-# LANGUAGE ViewPatterns #-} + +module Data.TypeLevel.List.Solver.Free where + +import Control.Applicative +import Control.Arrow +import Control.Lens (uses, view, (%=), (%~), (<&>), (^?), _1, _2, _Just) +import Control.Monad +import Control.Monad.IO.Class +import Control.Monad.Primitive +import Control.Monad.Trans.Class +import Control.Monad.Trans.Maybe +import Control.Monad.Trans.State.Strict +import qualified Data.DList as DL +import Data.IORef +import Data.Map (Map) +import qualified Data.Map as M +import qualified Data.Set as Set +import Data.TypeLevel.List.Solver.Reduce +import Data.TypeLevel.List.Solver.Syntax +import Data.TypeLevel.List.Solver.Utils +import GHC.Stack +import GHC.TcPluginM.Extra +import GHC.TcPluginM.Orphans () +#if MIN_VERSION_ghc(9,0,1) +import GHC.Tc.Types.Constraint +import GHC.Core.FamInstEnv (normaliseType) +import GHC.Plugins + ( Expr (..), + PredType, + TcTyVar, + Type, + eqType, + ) +import GHC.Tc.Plugin hiding (newWanted) +import GHC.Tc.Types +import GHC.Tc.Types.Evidence +import GHC.Tc.Utils.TcType (TcPredType) +#else +import Constraint +import FamInstEnv (normaliseType) +import GhcPlugins + ( Expr (..), + PredType, + TcTyVar, + Type, + eqType, + ) +import TcEvidence +import TcPluginM hiding (newWanted) +import TcRnTypes +import TcType (TcPredType) +#endif + +type Goal = Ct + +type Givens = Map Constr CtEvidence + +type Witness = EvTerm + +data Dictionary = Dictionary + { dictExpr :: EvExpr + , dictPred :: PredType + , dictLoc :: CtLoc + } + +data SolverF a where + CurrentGoal :: SolverF (Maybe Goal) + Givens :: SolverF Givens + Require :: Constr -> SolverF Dictionary + SymbolTable :: SolverF SymbolTable + ToWitness :: Dictionary -> SolverF Witness + LiftTcPluginM :: TcPluginM a -> SolverF a + +data Free f a where + Pure :: a -> Free f a + Fail :: Free f a + Choice :: Free f a -> Free f a -> Free f a + Bind :: f b -> (b -> Free f a) -> Free f a + +instance Functor (Free f) where + fmap _ Fail = Fail + fmap f (Choice ma mb) = Choice (f <$> ma) (f <$> mb) + fmap f (Pure a) = Pure $ f a + fmap f (Bind fb fba) = + Bind fb $ Pure . f <=< fba + +instance Applicative (Free f) where + pure = Pure + (<*>) = ap + +instance Monad (Free f) where +#if defined(__GLASGOW_HASKELL__) && __GLASGOW_HASKELL__ < 808 + fail = const Fail +#endif + Pure a >>= f = f a + Fail >>= _ = Fail + Choice l r >>= f = Choice (f =<< l) (f =<< r) + Bind fa g >>= f = Bind fa (g >=> f) + +instance MonadFail (Free f) where + fail = const Fail + +instance Alternative (Free f) where + empty = Fail + Fail <|> r = r + l <|> Fail = l + l <|> r = Choice l r + +instance MonadPlus (Free f) where + mzero = Fail + mplus = (<|>) + +interp :: + (Monad m, Alternative m) => + (forall x. f x -> m x) -> + Free f a -> + m a +interp trans = go + where + go (Pure a) = return a + go Fail = empty + go (Choice l r) = go l <|> go r + go (Bind fa g) = go . g =<< trans fa + +tryInterp :: + (Monad m) => + (forall x. f x -> m x) -> + Free f a -> + m (Maybe a) +tryInterp trans = runMaybeT . interp (lift . trans) + +embed :: f a -> Free f a +embed = flip Bind return + +require :: Constr -> Solver Dictionary +require = Solver . embed . Require + +getSymbolTable :: Solver SymbolTable +getSymbolTable = Solver $ embed SymbolTable + +getCurrentGoal :: Solver (Maybe Goal) +getCurrentGoal = Solver $ embed CurrentGoal + +toWitness :: Dictionary -> Solver Witness +toWitness = Solver . embed . ToWitness + +getGivens :: Solver Givens +getGivens = Solver $ embed Givens + +liftTcPluginM :: TcPluginM a -> Solver a +liftTcPluginM = Solver . embed . LiftTcPluginM + +newtype Solver a = Solver {runSolver :: Free SolverF a} + deriving newtype (Functor, Applicative, MonadPlus, Alternative, MonadFail, Monad) + +type EvidenceDic = Map WType CtEvidence + +type Normalisation = Map WType (TcCoercion, Type) + +data ListSolverState = LSS + { reduction :: IORef (Set.Set (Term, Term)) + , symTbl :: SymbolTable + , toBeReduced :: IORef (Set.Set (WithCtLoc Constr)) + , doneRef :: IORef (Set.Set (WithCtLoc Constr)) + , eqDicRef :: IORef EvidenceDic + , normDic :: IORef Normalisation + } + +runSolveMode :: + HasCallStack => + [(TcTyVar, Type)] -> + SymbolTable -> + TcRef EvidenceDic -> + IORef Normalisation -> + [Ct] -> -- Givens + Ct -> -- Goal + Solver a -> + TcPluginM (Maybe (a, [Ct])) +runSolveMode subs stbl evDicRef normRefs gs goal0 (Solver act) = do + givens <- buildGivenDic stbl normRefs gs + let goal = substCt subs goal0 + evDic <- tcPluginIO $ readIORef evDicRef + let go :: SolverF a -> StateT (EvidenceDic, DL.DList Ct) (MaybeT TcPluginM) a + go Givens = pure givens + go SymbolTable = pure stbl + go (Require c0) = do + let redC0 = reduceC stbl c0 + (_, redP) <- lift $ lift $ normaliseIt normRefs $ fromConstr stbl redC0 + let redC = toConstr stbl redP + origP = fromConstr stbl c0 + gsRed = M.lookup redC givens + redCands <- (gsRed <|>) <$> (uses _1 (M.lookup (WType redP))) + pf <- case redCands of + Just ev -> return ev + Nothing -> do + ev <- lift $ lift $ newWantedOrHole goal stbl redC + case redC of + EqType {} -> _1 %= M.insert (WType redP) ev + _ -> return () + _2 %= (`DL.snoc` mkNonCanonical ev) + return ev + return $ + if redP `eqType` origP + then ctEvToDictionary pf + else + Dictionary + { dictExpr = + ctEvExpr pf + `Cast` trustMe' "runSolveMode" redP origP + , dictPred = origP + , dictLoc = ctev_loc pf + } + go CurrentGoal = pure $ Just goal0 + go ToWitness {} = empty + go (LiftTcPluginM a) = lift $ lift a + mans <- + runMaybeT $ + runStateT (interp go act) (evDic, DL.empty) + <&> _2 . _2 %~ DL.toList + forM_ (mans ^? _Just . _2 . _1) $ + tcPluginIO . writeIORef evDicRef + return ((view _1 &&& view (_2 . _2)) <$> mans) + +newWantedOrHole :: Ct -> SymbolTable -> Constr -> TcPluginM CtEvidence +newWantedOrHole ct stbl eql@(EqType _ _ _) = do + let p = fromConstr stbl eql + hole <- newCoercionHole p + return $ CtWanted p (HoleDest hole) WDeriv (ctLoc ct) +newWantedOrHole ct stbl c = do + let p = fromConstr stbl c + newWanted (ctLoc ct) p + +runGenerationMode :: + SymbolTable -> + IORef Normalisation -> + Givens -> + Solver a -> + TcPluginM (Maybe a) +runGenerationMode stbl normRefs givens (Solver act) = do + let go :: SolverF a -> MaybeT TcPluginM a + go Givens = pure givens + go SymbolTable = pure stbl + go (Require c) = do + c' <- + lift $ + fmap (toConstr stbl . snd) $ + normaliseIt normRefs $ + fromConstr stbl c + Just l <- return $ M.lookup c' givens + return $ + Dictionary + { dictExpr = ctEvExpr l + , dictPred = ctEvPred l + , dictLoc = ctev_loc l + } + go CurrentGoal = empty + go ToWitness {} = empty + go (LiftTcPluginM a) = lift a + runMaybeT $ interp go act + +buildGivenDic :: + SymbolTable -> + IORef Normalisation -> + [Ct] -> + TcPluginM Givens +buildGivenDic stbl norms givens = + let subst = mkSubst' givens + subst' = map fst subst + in M.fromList + <$> mapM + ( \ct -> do + let new = substCt subst' ct + p0 = ctPred new + (_, p') <- normaliseIt norms p0 + pure + ( toConstr stbl p' + , (ctEvidence new) {ctev_pred = ctPred ct} + ) + ) + givens + +normaliseIt :: IORef Normalisation -> PredType -> TcPluginM (TcCoercion, TcPredType) +normaliseIt normRef ty = do + instEnvs <- getFamInstEnvs + tcPluginIO $ + atomicModifyIORef' normRef $ \norms -> + case M.lookup (WType ty) norms of + Just normed -> (norms, normed) + Nothing -> + let normed' = normaliseType instEnvs Nominal ty + in (M.insert (WType ty) normed' norms, normed') + +unsafeDicToWitnessM :: + HasCallStack => Dictionary -> Solver Witness +unsafeDicToWitnessM dic = do + Just ct <- getCurrentGoal + let orig = ctPred ct + targ = dictPred dic + return $ dictExpr dic `evCast` trustMe' ("unsafeDicToWitnessM: " ++ show callStack) targ orig + +unsafeDicToWitnessFor :: Either PredType Constr -> Dictionary -> Solver Witness +unsafeDicToWitnessFor ecnstr dic = do + stbl <- getSymbolTable + let orig = either id (fromConstr stbl) ecnstr + targ = dictPred dic + return $ dictExpr dic `evCast` trustMe' "unsafeDicToWitnessFor" targ orig + +instance MonadIO Solver where + liftIO = liftTcPluginM . tcPluginIO + {-# INLINE liftIO #-} + +instance PrimMonad Solver where + type PrimState Solver = RealWorld + primitive = liftTcPluginM . primitive + {-# INLINE primitive #-} + +ctEvToDictionary :: CtEvidence -> Dictionary +ctEvToDictionary ev = + Dictionary + { dictPred = ctEvPred ev + , dictExpr = ctEvExpr ev + , dictLoc = ctev_loc ev + } diff --git a/elgenerics-known/src/Data/TypeLevel/List/Solver/Generation.hs b/elgenerics-known/src/Data/TypeLevel/List/Solver/Generation.hs new file mode 100644 index 0000000..afc88c1 --- /dev/null +++ b/elgenerics-known/src/Data/TypeLevel/List/Solver/Generation.hs @@ -0,0 +1,351 @@ +{-# LANGUAGE CPP #-} +{-# LANGUAGE RecordWildCards #-} +{-# LANGUAGE ViewPatterns #-} + +module Data.TypeLevel.List.Solver.Generation where + +import Control.Applicative +import Control.Lens +import Control.Monad +import Control.Monad.ST +import Data.Coerce +import Data.DList qualified as DL +import Data.Foldable as F +import Data.Function +import Data.IORef +import Data.Map.Strict (Map) +import Data.Map.Strict qualified as M +import Data.Maybe +import Data.Monoid hiding (All, First) +import Data.Ord +import Data.Primitive +import Data.Semigroup (First (..)) +import Data.Set qualified as S +import Data.TypeLevel.List.Solver.Constraint +import Data.TypeLevel.List.Solver.Free +import Data.TypeLevel.List.Solver.Reduce +import Data.TypeLevel.List.Solver.Syntax +import Data.TypeLevel.List.Solver.Utils +import Data.UnionFind.Primitive +import GHC.TcPluginM.Extra +#if MIN_VERSION_ghc(9,0,1) +import GHC.Tc.Types.Constraint +import GHC.Plugins hiding (empty, (<>)) +import GHC.Core.Predicate +import GHC.Tc.Types.Evidence +import GHC.Tc.Plugin hiding (newGiven, newWanted) +#else +import Constraint +import GhcPlugins hiding (empty, (<>)) +import Predicate +import TcEvidence +import TcPluginM hiding (newGiven, newWanted) +#endif + +classifySubExprM :: + (Ord a, Plated a, PrimMonad m) => + (a -> m (Maybe a)) -> + MutVar (PrimState m) (Map a (Point m a)) -> + a -> + m () +classifySubExprM decomp dicRef = mapMOf_ cosmos go + where + {-# INLINE getPt #-} + getPt t = do + dic <- readMutVar dicRef + case M.lookup t dic of + Nothing -> do + v <- fresh t + modifyMutVar' dicRef $ M.insert t v + return v + Just v -> return v + go t = do + s <- decomp t + forM_ s $ \sub -> do + tPt <- getPt t + subPt <- getPt sub + union tPt subPt + +-- | /O(m*log(n/m + 1)), m <= n/ で mappend できる +newtype CatMap k v = CatMap {runCatMap :: Map k v} + deriving (Read, Show, Eq, Ord) + +instance + (Ord k, Semigroup v) => + Semigroup (CatMap k v) + where + (<>) = coerce $ M.unionWith @k @v (<>) + {-# INLINE (<>) #-} + +instance + (Ord k, Semigroup v) => + Monoid (CatMap k v) + where + mempty = CatMap M.empty + +generateDecompConstr :: + (Foldable t) => + (Term -> Solver Term) -> + (SymbolTable -> Term -> Constr) -> + t Term -> + Solver (Map Constr Ct) +generateDecompConstr decomp toC ts = do + dics <- + filter (not . null) + <$> classifyByM (optional . decomp) ts + fold . catMaybes <$> mapM (optional . shareDictsAmong toC) dics + +generateKnownTyLists :: + [Term] -> + Solver (Map Constr Ct) +generateKnownTyLists = + generateDecompConstr (fmap innerTerm . deconsKTL) $ \stbl xs -> + KnownTyList (typeKindElem $ fromTerm stbl xs) xs + +shareDictsAmong :: + (SymbolTable -> Term -> Constr) -> + [Term] -> + Solver (Map Constr Ct) +shareDictsAmong cls ts = do + stbl <- getSymbolTable + (orig, dic) <- + asum + [ (xs,) <$> require (cls stbl xs) + | xs <- ts + ] + fmap M.fromList $ + forM (filter (/= orig) ts) $ \xs -> + let p = cls stbl xs + in fmap ((p,) . mkNonCanonical) + . liftTcPluginM + . newGiven (dictLoc dic) (fromConstr stbl p) + =<< unsafeDicToWitnessFor (Right p) dic + +classifyByM :: + (Foldable t, Syntax s, PrimMonad m) => + (Term' s -> m (Maybe (Term' s))) -> + t (Term' s) -> + m [[Term' s]] +classifyByM decomp terms = do + dicRef <- newMutVar M.empty + mapM_ (classifySubExprM decomp dicRef) terms + dic <- readMutVar dicRef + fmap (M.elems . fmap DL.toList . runCatMap) $ + getAp $ + M.foldMapWithKey + ( \k pt -> + CatMap . flip M.singleton (DL.singleton k) + <$> Ap (descriptor =<< repr pt) + ) + dic + +classifyBy :: + (Foldable t, Syntax s) => + (Term' s -> Maybe (Term' s)) -> + t (Term' s) -> + [[Term' s]] +classifyBy f xs = runST $ classifyByM (return . f) xs + +data MemBuilder = BuildMem {mbList :: Term, mkWrap :: (FunType, Term)} + +instance Eq MemBuilder where + (==) = (==) `on` mbList + +instance Ord MemBuilder where + compare = comparing mbList + +instance Show MemBuilder where + showsPrec d (BuildMem p b) = + showParen (d > 10) $ + showString "BuildMem " . showsPrec 11 p . showsPrec 11 b + +type MemPath = [MemBuilder] + +walkMemPath :: + Dictionary -> Term -> MemPath -> Solver (Map Constr Dictionary) +walkMemPath dic0 x0 pth = do + fmap (foldMap $ \(_, p, r) -> M.singleton p r) $ + sequence $ + init $ + scanr go (return (x0, undefined, dic0)) pth + where + go (BuildMem lst wrapElem) mkXDic = do + (x, _, dic) <- mkXDic + stbl <- getSymbolTable + let hx = uncurry Apply wrapElem x + p = Member False (typeKind $ fromTerm stbl hx) hx lst + mem = fromConstr stbl p + dic' = castDicTo dic mem + return (hx, p, dic') + +castDicTo :: Dictionary -> PredType -> Dictionary +castDicTo dic p = + dic + { dictPred = p + , dictExpr = + dictExpr dic + `Cast` trustMe' "walkMemPath" (dictPred dic) p + } + +generateMembers :: + (Foldable t) => + t Term -> + Solver (Map Constr Ct) +generateMembers targs = do + gs <- getGivens + stbl <- getSymbolTable + let paths = buildMemPaths targs + mems = + [ (dic, x, ps) + | ((Member _ _ x xs), dic) <- + M.toList $ fmap ctEvToDictionary gs `M.union` mems' + , Just ps <- return $ M.lookup xs paths + ] + mems' = decompInjMember stbl gs + getAp $ + foldMap + ( \(dic, x, ps) -> + foldMap (Ap . (mapM dicToGivenCt <=< walkMemPath dic x)) ps + ) + mems + +dicToGivenCt :: + Dictionary -> Solver Ct +dicToGivenCt Dictionary {..} = + liftTcPluginM $ + mkNonCanonical' dictLoc + <$> newGiven dictLoc dictPred (EvExpr dictExpr) + +buildMemPaths :: (Foldable t) => t Term -> Map Term (S.Set MemPath) +buildMemPaths = runCatMap . foldMap (CatMap . buildMemPathsFor) + +buildMemPathsFor :: Term -> Map Term (S.Set MemPath) +buildMemPathsFor = runCatMap . foldMapOf cosmos go' + where + go' t = + let (xs, bcs) = go t + in CatMap $ M.singleton xs $ S.singleton bcs + go memList@(Map' b _ _ h inner) = + let (xs0, bcs) = go inner + bc = BuildMem memList (b, h) + in (xs0, bc : bcs) + go xs = (xs, []) + +generateNontrivials :: ListSolverState -> [Ct] -> TcPluginM [Ct] +generateNontrivials (LSS redRef stbl@STbl {} ref doneRef _ norms) givens = do + tcPluginTrace "LIST: Simplification started with: " $ ppr givens + (red0, toReduce) <- tcPluginIO $ do + toReduce <- readIORef ref + modifyIORef' doneRef $ S.union toReduce + (,toReduce) <$> readIORef redRef + let subs = map fst $ mkSubst' givens + redex <- + fmap (M.fromList . catMaybes) + $ mapM + ( \ct -> + let p = ctPred ct + c = toConstr stbl p + c' = reduceC stbl c + p' = fromConstr stbl c' + in if c /= c' && case c of EqType {} -> False; _ -> True + then do + ct' <- + fmap (mkNonCanonical' (ctLoc ct)) $ + newGiven (ctLoc ct) p' $ + ctEvExpr (ctEvidence ct) `evCast` trustMe' "redex" p p' + return $ Just (c', ct') + else return Nothing + ) + $ flattenGivens givens + tcPluginTrace "LIST: redex keys" $ ppr $ show $ M.keys redex + let presEqs = + S.fromList $ + [ (l, r) + | EqType NomEq l r <- map (toConstr stbl . ctPred) $ flattenGivens givens + ] + red = red0 `S.union` presEqs + eqs = + foldMap + ( \(WithCtLoc loc foo) -> + S.mapMonotonic (WithCtLoc loc) $ + deriveEquality red stbl foo + ) + $ S.union toReduce + $ S.fromList + $ filter (not . isUnknownC . value) + $ map + ( WithCtLoc + <$> ctLoc + <*> toConstr stbl + . ctPred + . substCt subs + ) + givens + tcPluginIO $ + modifyIORef' + redRef + ((`S.union` S.map value eqs) . (`S.union` presEqs)) + dervs <- forM (S.toList eqs) $ + \(WithCtLoc loc (fromTerm stbl -> l, fromTerm stbl -> r)) -> + mkNonCanonical' loc + <$> newGiven + loc + (mkPrimEqPred l r) + (evCoercion $ trustMeNominal l r) + gDic <- buildGivenDic stbl norms givens + alls <- fromMaybe [] <$> runGenerationMode stbl norms gDic decompAlls + omAlls <- fromMaybe [] <$> runGenerationMode stbl norms gDic decompOMAlls + let subterms = + map (substTerm stbl subs) $ + S.toList $ + S.unions + [ foldMap (S.fromList . F.toList . value) toReduce + , foldMap (S.fromList . F.toList) (M.keys gDic) + ] + allsDic = M.fromList [(toConstr stbl $ ctPred ct, ct) | ct <- alls] + omAllsDic = M.fromList [(toConstr stbl $ ctPred ct, ct) | ct <- omAlls] + dones <- tcPluginIO $ readIORef doneRef + let giveCs = + S.fromList + [ WithCtLoc (ctLoc ct) $ + toConstr stbl $ + ctPred ct + | ct <- flattenGivens givens + ] + knownsDic <- + fmap (fromMaybe M.empty) $ + runGenerationMode stbl norms gDic $ + generateKnownTyLists subterms + memDic <- + fmap (fromMaybe M.empty) $ + runGenerationMode stbl norms gDic $ + generateMembers subterms + let genDic0 = + M.unions + [knownsDic, allsDic, omAllsDic, memDic, redex] + exKeys = giveCs `S.union` dones + genDic = genDic0 `M.withoutKeys` S.mapMonotonic value exKeys + gens = F.toList genDic + tcPluginIO $ + modifyIORef' doneRef $ + S.union $ + S.mapMonotonic (\k -> WithCtLoc (ctLoc $ genDic M.! k) k) $ + M.keysSet genDic + tcPluginTrace "LIST: Derived constraints: " $ ppr $ dervs ++ gens + return (dervs ++ gens) + +decompInjMember :: + SymbolTable -> Givens -> Map Constr Dictionary +decompInjMember stbl givens = + maybe M.empty ((`M.withoutKeys` M.keysSet givens) . coerce . runCatMap) + . M.foldMapWithKey go + $ fmap ctEvToDictionary givens + where + go :: Constr -> Dictionary -> Maybe (CatMap Constr (First Dictionary)) + go cnstr ct = do + (w, Just Bare, k, x, xs) <- decompInnerMember (reduceC stbl cnstr) + let inner = Member w k (reduce x) (reduce xs) + p' = fromConstr stbl inner + ct' = ct `castDicTo` p' + return (CatMap $ M.singleton inner $ First ct') + <> go inner ct' diff --git a/elgenerics-known/src/Data/TypeLevel/List/Solver/Reduce.hs b/elgenerics-known/src/Data/TypeLevel/List/Solver/Reduce.hs new file mode 100644 index 0000000..90fd8e2 --- /dev/null +++ b/elgenerics-known/src/Data/TypeLevel/List/Solver/Reduce.hs @@ -0,0 +1,79 @@ +{-# LANGUAGE LambdaCase #-} +{-# LANGUAGE ViewPatterns #-} + +module Data.TypeLevel.List.Solver.Reduce where + +import Control.Lens.Plated +import Control.Monad +import Control.Monad.Trans.RWS.Strict +import Data.Set (Set) +import Data.Set qualified as Set +import Data.TypeLevel.List.Solver.Syntax + +type Equality' syntax = (Term' syntax, Term' syntax) + +type Equality = Equality' Ghc + +type Machine syntax = + RWS (Set (Term' syntax, Term' syntax)) () (Set (Equality' syntax)) + +rewritesTo :: + (Syntax syntax) => + Term' syntax -> + Term' syntax -> + Machine syntax (Maybe (Term' syntax)) +rewritesTo l r = do + there <- asks (\f -> (l, r) `Set.member` f || (r, l) `Set.member` f) + unless (there || l == r) $ + modify $ + Set.insert (l, r) + return $ Just r + +deriveEquality :: + Set (Term, Term) -> SymbolTable -> Constr -> Set Equality +deriveEquality red stbl (UnknownC ty) = deriveEqTerm red (toTerm stbl ty) +deriveEquality red _ c = foldMap (deriveEqTerm red) c + +deriveEqTerm :: Set (Term, Term) -> Term -> Set Equality +deriveEqTerm red x = fst $ execRWS (rewriteM reduceM x) red (Set.empty) + +reduce :: (Syntax syntax) => Term' syntax -> Term' syntax +reduce x = + fst $ + evalRWS + (rewriteM reduceM x) + Set.empty + Set.empty + +reduceC :: + SymbolTable -> Constr -> Constr +reduceC stbl (UnknownC ty) = + UnknownC $ fromTerm stbl $ reduce (toTerm stbl ty) +reduceC _ c = fmap reduce c + +reduceM :: (Syntax syntax) => Term' syntax -> Machine syntax (Maybe (Term' syntax)) +reduceM t@(SortByAux' k cmp _ xs) = do + reduceM xs >>= \case + Just xs' -> + rewritesTo t $ + SortByAux' k cmp (Length' k xs') xs' + Nothing -> return Nothing +reduceM t@(Length' _ (Map' _ a _ _ xs)) = do + rewritesTo t (Length' a xs) +reduceM t@(ElemAt' _ n (Map' b a _ h xs)) = do + let inner = ElemAt' a n xs + rewritesTo t $ Apply' b h inner +reduceM t@(Map' b k k' h (Take' _ n xs)) = do + rewritesTo t $ Take' k' n $ Map' b k k' h xs +reduceM t@(Map' b k k' h (Drop' _ n xs)) = do + rewritesTo t $ Drop' k' n $ Map' b k k' h xs +reduceM t@(ElemAt' _ (Index' _ x xs) ys) | xs == ys = do + rewritesTo t x +reduceM t@(AppList' k (AppList' _ xs ys) zs) = + rewritesTo t (AppList' k xs (AppList' k ys zs)) +reduceM t@(Map' b k k' h (AppList' _ xs ys)) = do + let (l, r) = (Map' b k k' h xs, Map' b k k' h ys) + rewritesTo t $ AppList' k' l r +reduceM _ = return Nothing + +-- TODO: Monotonicity diff --git a/elgenerics-known/src/Data/TypeLevel/List/Solver/Syntax.hs b/elgenerics-known/src/Data/TypeLevel/List/Solver/Syntax.hs new file mode 100644 index 0000000..445cffd --- /dev/null +++ b/elgenerics-known/src/Data/TypeLevel/List/Solver/Syntax.hs @@ -0,0 +1,737 @@ +{-# LANGUAGE CPP #-} +{-# LANGUAGE DeriveAnyClass #-} +{-# LANGUAGE DerivingStrategies #-} +{-# LANGUAGE LambdaCase #-} +{-# LANGUAGE OverloadedStrings #-} +{-# LANGUAGE PatternSynonyms #-} +{-# LANGUAGE RecordWildCards #-} +{-# LANGUAGE TypeFamilies #-} +{-# OPTIONS_GHC -Wall #-} +module Data.TypeLevel.List.Solver.Syntax + ( WType(..), FunType(..), IsWrapped, + isUnknownTerm, isUnknownC, + Syntax(..), Ghc, Debug, WithCtLoc(..), + WKind, + Constr, + Constr' + ( EqType, KnownNat, KnownTyList, SortedBy, Known, + Monotone, PreservesLength, UnknownC, Member, All, + AllOM, MemberOM, MaybeC + ), + Term, + Term' + ( .., Compare2, Map, Length, SortByAux, PromotedTuple, + Indexed, EmptyList, PromotedJust, Index, ElemAt, UnknownTerm, + Take, Drop, AppList, Apply, OMIndex, SizeOM, ToListOM, + FromMaybe, MapMaybeApp, + UnknownTyConApp, ToListAuxOM, LookupWithIndexOM, Lookup'OM + ), + (-->), (~>), listTy, + fromConstr, toConstr, fromTerm, toTerm, + deconsPred, substTerm, + SymbolTable(..), setupSymbolTable + ) where +import Control.Applicative +import Control.Lens hiding (Indexed) +import Data.Data (Data, Typeable) +import Data.Function +import Data.Maybe +import GHC.Generics +import GHC.TcPluginM.Extra +import Data.TypeLevel.List.Solver.Utils +#if MIN_VERSION_ghc(9,0,1) +import GHC.Core.Class +import GHC.Plugins hiding ((<>)) +import GHC.Builtin.Names +import GHC.Tc.Plugin hiding (newWanted) +import GHC.Core.Predicate +import GHC.Tc.Types.Constraint +import Control.Arrow ((>>>)) +#else +import Class +import GhcPlugins hiding ((<>)) +import PrelNames +import TcPluginM hiding (newWanted) +import Predicate +import Constraint +import TyCoRep (mkFunTy) +#endif + +type WKind = WType +newtype WType = WType { runWType :: Type } + deriving (Typeable, Data) +newtype WTyCon = WTyCon { runWTyCon :: TyCon } + deriving (Typeable, Data) + +instance Show WTyCon where + showsPrec d = showParen (d > 10) . showString . showSDocExplicit . ppr . runWTyCon +instance Eq WTyCon where + (==) = fmap (== EQ) . (nonDetCmpTc `on` runWTyCon) +instance Ord WTyCon where + compare = nonDetCmpTc `on` runWTyCon +instance Show WType where + showsPrec d (WType ty) = showParen (d > 10) $ + showString $ showSDocUnsafe $ ppr ty + +instance Eq WType where + (==) = eqType `on` runWType + +instance Ord WType where + compare = nonDetCmpType `on` runWType + +data FunType = Bare | Uncurry + deriving (Read, Show, Eq, Ord, Generic, Data, Typeable) +type IsWrapped = Bool +newtype WEqRel = WEqRel { runWEqRel :: EqRel } + deriving newtype (Eq, Ord) +instance Show WEqRel where + showsPrec _ = showString . showSDocUnsafe . ppr . runWEqRel + +data Constr' term + = EqType' WEqRel term term + | KnownNat term + | KnownTyList' WKind term + | SortedBy' WKind term term + | Monotone' FunType WKind WKind term term term + | PreservesLength' term + | Member' IsWrapped WKind term term + | All' WKind term term + | UnknownC' WType + | AllOM' WKind WKind term term + | MemberOM' IsWrapped WKind WKind term term + | MaybeC' WKind term term + | Known' WKind term + deriving (Eq, Ord, Show, Functor, Foldable) +type Constr = Constr' Term + +{-# COMPLETE + EqType, KnownNat, KnownTyList, SortedBy, Member, MemberOM, + Monotone, PreservesLength, All, AllOM, UnknownC, Known, MaybeC #-} +class + ( Data a, + Data (KindOf a), Eq (KindOf a), Ord (KindOf a), Show (KindOf a), + Data (TypeOf a), Eq (TypeOf a), Ord (TypeOf a), Show (TypeOf a), + Data (TyConOf a), Eq (TyConOf a), Ord (TyConOf a), Show (TyConOf a) + ) => Syntax a where + type KindOf a + type TypeOf a + type TyConOf a + +data Ghc deriving (Typeable, Data) +instance Syntax Ghc where + type KindOf Ghc = WKind + type TypeOf Ghc = WType + type TyConOf Ghc = WTyCon + +data Debug deriving (Typeable, Data) + +instance Syntax Debug where + type KindOf Debug = String + type TypeOf Debug = String + type TyConOf Debug = String + +type Term = Term' Ghc +data Term' suite + = Compare2' (KindOf suite) + | TyNat Integer + | Map' FunType (KindOf suite) (KindOf suite) (Term' suite) (Term' suite) + | Length' (KindOf suite) (Term' suite) + | SortByAux' (KindOf suite) (Term' suite) (Term' suite) (Term' suite) + | Indexed' (KindOf suite) (Term' suite) + | EmptyList' (KindOf suite) + | PromotedJust' (KindOf suite) (Term' suite) + | PromotedTuple' (KindOf suite) (KindOf suite) (Term' suite) (Term' suite) + | Index' (KindOf suite) (Term' suite) (Term' suite) + | OMIndex' (KindOf suite) (KindOf suite) (Term' suite) (Term' suite) + -- key val key (OrdMap key val) + | ElemAt' (KindOf suite) (Term' suite) (Term' suite) + | Drop' (KindOf suite) (Term' suite) (Term' suite) + | Take' (KindOf suite) (Term' suite) (Term' suite) + | AppList' (KindOf suite) (Term' suite) (Term' suite) + | UnknownTyConApp' (TyConOf suite) [(Term' suite)] + | Apply' FunType (Term' suite) (Term' suite) + | SizeOM' (KindOf suite) (KindOf suite) (Term' suite) + | ToListOM' (KindOf suite) (KindOf suite) (Term' suite) + | ToListAuxOM' (KindOf suite) (KindOf suite) (Term' suite) (Term' suite) + | LookupWithIndexOM' (KindOf suite) (KindOf suite) (Term' suite) (Term' suite) + | Lookup'OM' (KindOf suite) (KindOf suite) (Term' suite) (Term' suite) + | FromMaybe' (KindOf suite) (Term' suite) (Term' suite) + | MapMaybeApp' (KindOf suite)(KindOf suite) (Term' suite) (Term' suite) + | UnknownTerm' (TypeOf suite) + deriving (Generic) + +deriving instance Syntax a => Typeable (Term' a) +deriving instance Syntax a => Data (Term' a) +deriving instance Syntax a => Show (Term' a) +deriving instance Syntax a => Eq (Term' a) +deriving instance Syntax a => Ord (Term' a) + +deriving anyclass instance Syntax suite => Plated (Term' suite) + +{-# COMPLETE + Compare2, TyNat, Map, Length, SortByAux, + Indexed, EmptyList, PromotedJust, PromotedTuple, Index, OMIndex, ElemAt, Drop, Take, AppList, MapMaybeApp, + Apply, SizeOM, ToListAuxOM, LookupWithIndexOM, Lookup'OM, + UnknownTerm, UnknownTyConApp, FromMaybe + #-} + +pattern PromotedJust :: Kind -> Term -> Term +pattern PromotedJust k v = PromotedJust' (WType k) v + +pattern PromotedTuple :: Kind -> Kind -> Term -> Term -> Term +pattern PromotedTuple a b l r = PromotedTuple' (WType a) (WType b) l r + +pattern KnownTyList :: Kind -> Term -> Constr +pattern KnownTyList k t = KnownTyList' (WType k) t + +pattern Member :: IsWrapped -> Kind -> Term -> Term -> Constr +pattern Member b k x xs = Member' b (WType k) x xs + +pattern MemberOM :: IsWrapped -> Kind -> Kind -> Term -> Term -> Constr +pattern MemberOM b k v x xs = MemberOM' b (WType k) (WType v) x xs + +pattern All :: Kind -> Term -> Term -> Constr +pattern All k x xs = All' (WType k) x xs + +pattern AllOM :: Kind -> Kind -> Term -> Term -> Constr +pattern AllOM k k' x xs = AllOM' (WType k) (WType k') x xs + +pattern EqType :: EqRel -> Term -> Term -> Constr +pattern EqType b t u = EqType' (WEqRel b) t u + +pattern SortedBy :: Kind -> Term -> Term -> Constr +pattern SortedBy k cmp xs = SortedBy' (WType k) cmp xs + +pattern Monotone :: FunType -> Kind -> Kind -> Term -> Term -> Term -> Constr +pattern Monotone fty k k' f cmp cmp' = + Monotone' fty (WType k) (WType k') f cmp cmp' + +pattern PreservesLength :: Term -> Constr +pattern PreservesLength t = + PreservesLength' t + +pattern UnknownC :: Type -> Constr +pattern UnknownC ty = + UnknownC' (WType ty) + +pattern MaybeC :: Type -> Term -> Term -> Constr +pattern MaybeC kind c may = MaybeC' (WType kind) c may + + +pattern Known :: Type -> Term -> Constr +pattern Known kind x = Known' (WType kind) x + +pattern Compare2 :: Kind -> Term +pattern Compare2 k = Compare2' (WType k) +pattern Map :: FunType -> Kind -> Kind -> Term -> Term -> Term +pattern Map fty k k' t u = Map' fty (WType k) (WType k') t u +pattern Length :: Kind -> Term -> Term +pattern Length k x = Length' (WType k) x +pattern SortByAux :: Kind -> Term -> Term -> Term -> Term +pattern SortByAux k a b c = SortByAux' (WType k) a b c +pattern Indexed :: Kind -> Term -> Term +pattern Indexed k xs = Indexed' (WType k) xs +pattern EmptyList :: Kind -> Term +pattern EmptyList k = EmptyList' (WType k) +pattern Index :: Kind -> Term -> Term -> Term +pattern Index k x xs = Index' (WType k) x xs +pattern OMIndex :: Kind -> Kind -> Term -> Term -> Term +pattern OMIndex key val x xs = OMIndex' (WType key) (WType val) x xs +pattern ElemAt :: Kind -> Term -> Term -> Term +pattern ElemAt k n xs = ElemAt' (WType k) n xs + +pattern Drop :: Kind -> Term -> Term -> Term +pattern Drop k n xs = Drop' (WType k) n xs +pattern Take :: Kind -> Term -> Term -> Term +pattern Take k n xs = Take' (WType k) n xs +pattern AppList :: Kind -> Term -> Term -> Term +pattern AppList k xs ys = AppList' (WType k) xs ys + +pattern FromMaybe :: Kind -> Term -> Term -> Term +pattern FromMaybe k xs ys = FromMaybe' (WType k) xs ys +pattern MapMaybeApp :: Kind -> Kind -> Term -> Term -> Term +pattern MapMaybeApp k k' xs ys = MapMaybeApp' (WType k)(WType k') xs ys + +pattern UnknownTyConApp :: TyCon -> [Term] -> Term +pattern UnknownTyConApp con ts = UnknownTyConApp' (WTyCon con) ts + +pattern Apply :: FunType -> Term -> Term -> Term +pattern Apply funType l r = Apply' funType l r + +pattern UnknownTerm :: Type -> Term +pattern UnknownTerm k = UnknownTerm' (WType k) + +pattern SizeOM :: Kind -> Kind -> Term -> Term +pattern SizeOM k v dic = SizeOM' (WType k) (WType v) dic + +pattern ToListOM :: Kind -> Kind -> Term -> Term +pattern ToListOM k v dic = ToListOM' (WType k) (WType v) dic + +pattern ToListAuxOM :: Kind -> Kind -> Term -> Term -> Term +pattern ToListAuxOM k v acc dic = ToListAuxOM' (WType k) (WType v) acc dic + +pattern LookupWithIndexOM :: Kind -> Kind -> Term -> Term -> Term +pattern LookupWithIndexOM k v l dic = LookupWithIndexOM' (WType k) (WType v) l dic + +pattern Lookup'OM :: Kind -> Kind -> Term -> Term -> Term +pattern Lookup'OM k v l dic = Lookup'OM' (WType k) (WType v) l dic + +toConstr :: SymbolTable -> PredType -> Constr +toConstr stbl@STbl{..} ty = + let unk = UnknownC ty + in fromMaybe unk $ + case classifyPredType ty of + ClassPred cls ts -> buildClass (classTyCon cls) ts + EqPred rel l r -> Just $ EqType rel (toTerm stbl l) (toTerm stbl r) + _ -> uncurry buildClass =<< deconsPred ty + where + buildClass cls [n] + | cls == knownNatTyCon + = case toTerm stbl n of + Index k x xs -> + Just $ Member False k x xs + Length k xs -> + Just $ KnownTyList k xs + t -> Just $ KnownNat t + buildClass cls [x, xs] + | cls == memberTyCon = + Just $ Member True (typeKind x) (toTerm stbl x) (toTerm stbl xs) + buildClass cls [k, x] + | cls == knownTyCon = + Just $ Known k (toTerm stbl x) + buildClass cls [key, val, x, xs] + | cls == omMemberTyCon + = Just $ MemberOM True key val (toTerm stbl x) (toTerm stbl xs) + buildClass cls [k, c, xs] + | cls == allTyCon + = Just $ All k (toTerm stbl c) (toTerm stbl xs) + buildClass cls [k, c, xs] + | cls == maybeCTyCon + = Just $ MaybeC k (toTerm stbl c) (toTerm stbl xs) + buildClass cls [k, v, c, xs] + | cls == allOMTyCon + = Just $ AllOM k v (toTerm stbl c) (toTerm stbl xs) + buildClass cls [_, f] + | cls == presLenTyCon + = Just + $ PreservesLength $ toTerm stbl f + buildClass cls [k, cmp, xs] + | cls `elem` [classTyCon sortedByCls, sortedByAuxTyCon] + = Just + $ SortedBy k (toTerm stbl cmp) (toTerm stbl xs) + buildClass cls [k, k', f, cmp, cmp'] + | Just fty <- lookup cls $ monotoneDic stbl + = Just + $ Monotone fty k k' + (toTerm stbl f) + (toTerm stbl cmp) (toTerm stbl cmp') + buildClass _ _ = Nothing + +fromConstr :: SymbolTable -> Constr -> PredType +fromConstr stbl@STbl{} (EqType rel l r) = + let (a, b) = (fromTerm stbl l, fromTerm stbl r) + mk = case rel of { NomEq -> mkPrimEqPred ; ReprEq -> mkReprPrimEqPred } + in mk a b +fromConstr stbl@STbl{..} (AllOM key val constr dic) = + mkTyConApp allOMTyCon [key, val, fromTerm stbl constr, fromTerm stbl dic] +fromConstr stbl@STbl{..} (KnownNat n) = + mkTyConApp knownNatTyCon [fromTerm stbl n] +fromConstr stbl@STbl{..} (Known k x )= + mkTyConApp knownTyCon [k, fromTerm stbl x] +fromConstr stbl@STbl{..} (All k c xs) = + mkTyConApp allTyCon [k, fromTerm stbl c, fromTerm stbl xs] +fromConstr stbl (Member False k x xs) = + fromConstr stbl $ KnownNat $ Index k x xs +fromConstr stbl@STbl{..} (Member True k x xs) = + mkTyConApp memberTyCon [k, fromTerm stbl x, fromTerm stbl xs] +fromConstr stbl@STbl{..} (MemberOM _ k v x xs) = + mkTyConApp omMemberTyCon [k, v, fromTerm stbl x, fromTerm stbl xs] +fromConstr stbl@STbl{} (KnownTyList k xs) = + fromConstr stbl (KnownNat (Length k xs)) +fromConstr stbl@STbl{..} (SortedBy k cmp xs) = + mkTyConApp (classTyCon sortedByCls) + [k, fromTerm stbl cmp , fromTerm stbl xs] +fromConstr stbl@STbl{..} (Monotone fty k k' f cmp cmp') = + let con = case fty of + Bare -> monotoneTyCon + Uncurry -> monotoneAppTyCon + in mkTyConApp con + [ k, k' + , fromTerm stbl f + , fromTerm stbl cmp + , fromTerm stbl cmp' + ] +fromConstr stbl@STbl{..} (PreservesLength p) = + let x = fromTerm stbl p + in mkTyConApp presLenTyCon [typeKind x, x] +fromConstr stbl@STbl{..} (MaybeC k c may) = + mkTyConApp maybeCTyCon [k, fromTerm stbl c, fromTerm stbl may] +fromConstr _ (UnknownC ty) = ty + +toTerm :: SymbolTable -> Type -> Term +toTerm stbl@STbl{..} ty = + fromMaybe (UnknownTerm ty) $ + TyNat <$> isNumLitTy ty + <|> case splitTyConApp_maybe ty of + Just (con, [x]) + | con == compare2TyCon + -> Just $ Compare2 x + Just (con, [k]) + | con == promotedNilDataCon + -> Just $ EmptyList k + Just (con, [k, v]) + | con == promotedJustDataCon + -> Just $ PromotedJust k (toTerm stbl v) + Just (con, [k, as, bs]) + | con == appListTyCon + -> Just $ AppList k (toTerm stbl as) (toTerm stbl bs) + Just (con, [k, v, dic]) + | con == omToListTyCon + -> Just $ ToListOM k v (toTerm stbl dic) + Just (con, [k, v, acc, dic]) + | con == omToListAuxTyCon + , Just (niler, _) <- splitTyConApp_maybe acc + , niler == promotedNilDataCon + -> Just $ ToListAuxOM k v (toTerm stbl acc) (toTerm stbl dic) + Just (con, [a,b,l,r]) + | con == promotedTupleDataCon Boxed 2 + -> Just $ PromotedTuple a b (toTerm stbl l) (toTerm stbl r) + Just (con, [k, k', f, xs]) + | Just fty <- lookup con (mapDic stbl) + -> let (fr, t) = +#if MIN_VERSION_ghc(8,8,1) + case fty of + Bare -> (k', k) + Uncurry -> (k, k') +#else + case fty of + Bare -> (k, k') + Uncurry -> (k', k) +#endif + in Just $ Map fty fr t + (toTerm stbl f) $ toTerm stbl xs + | con == applyTyCon + -> Just $ Apply Uncurry (toTerm stbl f) (toTerm stbl xs) + Just (con, [k, x]) + | con == lengthTyCon + -> Just $ Length k $ + toTerm stbl x + | con == indexedTyCon + -> Just $ Indexed k $ + toTerm stbl x + Just (con, [k, cmp, n, xs]) + | con == sortByAuxTyCon + -> Just $ SortByAux k + (toTerm stbl cmp) + (toTerm stbl n) + (toTerm stbl xs) + Just (con, [k, x, xs, rest]) + | con == indexTyCon' + , Just (niler, [k']) <- splitTyConApp_maybe rest + , niler == promotedNilDataCon && k `eqType` k' + -> Just $ Index k + (toTerm stbl x) + (toTerm stbl xs) + Just (con, [k,v,l,dic]) + | con == lookupWithIdxTyCon + -> Just $ LookupWithIndexOM k v (toTerm stbl l) (toTerm stbl dic) + Just (con, [k, x, xs]) + | con == elemAtTyCon + -> Just $ ElemAt k (toTerm stbl x) (toTerm stbl xs) + Just (con, [k, x, xs]) + | con == fromMaybeTyCon + -> Just $ FromMaybe k (toTerm stbl x) (toTerm stbl xs) + Just (con, [k, k', f, xs]) + | con == mapMaybeTyCon + -> Just $ MapMaybeApp k k' (toTerm stbl f) (toTerm stbl xs) + Just (con, [k, n, xs]) + | con == dropTyCon + -> Just $ Drop k (toTerm stbl n) (toTerm stbl xs) + | con == takeTyCon + -> Just $ Take k (toTerm stbl n) (toTerm stbl xs) + Just (con, args) -> + Just $ UnknownTyConApp con $ map (toTerm stbl) args + _ -> Nothing + <|> case splitAppTy_maybe ty of + Just (l, r) -> + Just $ Apply Bare (toTerm stbl l) (toTerm stbl r) + _ -> Nothing + +fromTerm :: SymbolTable -> Term -> Type +fromTerm STbl{..} = go + where + go (Compare2 k) = mkTyConApp compare2TyCon [k] + go (TyNat n) = mkNumLitTy n + go (PromotedTuple a b l r) = + mkTyConApp (promotedTupleDataCon Boxed 2) + [a, b, go l, go r] + go (Map fty k k' f xs) = + let (con, lKind, rKind) = case fty of +#if MIN_VERSION_ghc(8,8,1) + Bare -> (mapTyCon, k', k) + Uncurry -> (mapApplyTyCon, k, k') +#else + Bare -> (mapTyCon, k, k') + Uncurry -> (mapApplyTyCon, k', k) +#endif + + in mkTyConApp con [lKind, rKind, go f, go xs] + go (Length k x) = + mkTyConApp lengthTyCon [k, go x] + go (SortByAux k cmp n xs) = + mkTyConApp sortByAuxTyCon + [k, go cmp, go n, go xs] + go (LookupWithIndexOM k v l dic) = + mkTyConApp lookupWithIdxTyCon + [k, v, go l, go dic] + go (Lookup'OM k v l dic) = + mkTyConApp omLookup'TyCon + [ k, v, go l, go dic] + go (Indexed k xs) = + mkTyConApp indexedTyCon + [k, go xs] + go (Apply Uncurry f x) = + let l = go f + r = go x + (dom, ran) = domRanKind Uncurry l +#if MIN_VERSION_ghc(8,8,1) + in mkTyConApp applyTyCon [dom, ran, l, r] +#else + in mkTyConApp applyTyCon [ran, dom, l, r] +#endif + + go (Apply Bare f x) = + mkAppTy (go f) (go x) + go (FromMaybe k def may) = + mkTyConApp fromMaybeTyCon [k, go def, go may] + go (MapMaybeApp k k' f may) = + mkTyConApp mapMaybeTyCon [k, k', go f, go may] + go (EmptyList k) = + mkTyConApp promotedNilDataCon [k] + go (PromotedJust k v) = + mkTyConApp promotedJustDataCon [k, go v] + go (ToListOM k v dic) = + mkTyConApp omToListTyCon [k, v, go dic] + go (ToListAuxOM k v acc dic) = + mkTyConApp omToListAuxTyCon [k, v, go acc, go dic] + go (OMIndex k v l xs) = + mkTyConApp omIndexTyCon [k, v, go l, go xs] + go (Index k n xs) = + mkTyConApp indexTyCon' [k, go n, go xs, mkTyConApp promotedNilDataCon [k]] + go (ElemAt k n xs) = + mkTyConApp elemAtTyCon [k, go n, go xs] + go (Drop k n xs) = + mkTyConApp dropTyCon [k, go n, go xs] + go (Take k n xs) = + mkTyConApp takeTyCon [k, go n, go xs] + go (AppList k xs ys) = + mkTyConApp appListTyCon [k, go xs, go ys] + go (SizeOM k v dic) = + mkTyConApp omSizeTyCon [k, v, go dic] + go (UnknownTyConApp con ts) = + mkTyConApp con $ map go ts + go (UnknownTerm k) = k + +monotoneDic :: SymbolTable -> [(TyCon, FunType)] +monotoneDic STbl{..} = + [ (monotoneTyCon, Bare) + , (monotoneAppTyCon, Uncurry) + ] + +mapDic :: SymbolTable -> [(TyCon, FunType)] +mapDic STbl{..} = + [ (mapTyCon, Bare) + , (mapApplyTyCon, Uncurry) + ] + +data SymbolTable = + STbl + { indexedAuxTyCon :: TyCon + , indexedTyCon :: TyCon + , lengthTyCon :: TyCon + , sortByTyCon :: TyCon + , sortByAuxTyCon :: TyCon + , sortedByCls :: Class + , sortedByAuxTyCon :: TyCon + , sOrdTyCon :: TyCon + , monotoneTyCon :: TyCon + , monotoneAppTyCon :: TyCon + , ordMapTyCon :: TyCon + , sOrdMapTyCon :: TyCon + , entryCTyCon :: TyCon + , fst1TyCon :: TyCon + , presLenTyCon :: TyCon + , mapTyCon :: TyCon + , mapApplyTyCon :: TyCon + , knownNatTyCon :: TyCon + , compare2TyCon :: TyCon + , indexTyCon' :: TyCon + , elemAtTyCon :: TyCon + , applyTyCon :: TyCon + , dropTyCon :: TyCon + , takeTyCon :: TyCon + , appListTyCon :: TyCon + , allTyCon :: TyCon + , allDicTyCon :: TyCon + , reifyDicId :: Id + , memberTyCon :: TyCon + , allOMTyCon :: TyCon + -- key val (c :: key -> val -> Constraint) dic + , omMemberTyCon :: TyCon + , omLookup'TyCon :: TyCon + , allOMDict'FunId :: Id + -- :: key val (c :: key -> val -> Constraint) + -- (dic :: OrdMap key val) (x :: key) + -- $dAllOM $dMember + , omIndexTyCon :: TyCon + -- key val (l :: key) (OrdMap key val) + , constsDictTyCon :: TyCon + , omSizeTyCon :: TyCon + , omToListTyCon :: TyCon + , omToListAuxTyCon :: TyCon + , lookupWithIdxTyCon :: TyCon + , lookupOMTyCon :: TyCon + , -- | @forall {k} {val} {l :: k} {dic :: OrdMap k val}. SOrd k => ...@ + sLookupWithIndex'FunId :: Id + , fromMaybeTyCon :: TyCon + , -- | @forall a b. (a ~> b) -> Maybe a -> Maybe b@ + mapMaybeTyCon :: TyCon + , elimFromMaybeC'FunId :: Id + , maybeCTyCon :: TyCon + , knownTyCon :: TyCon + , sApplyClass :: Class + , singTyCon :: TyCon + , -- | forall {k} {a :: k}. Known @{k} a => Sing @k @Type a + sKnownVal'FunId, elimMaybeCLookup'FunId, sFMapMaybe'FunId :: Id + } + +setupSymbolTable :: TcPluginM SymbolTable +setupSymbolTable = do + ordMod@(Module pkgId _) + <- lookupModule (mkModuleName "Data.TypeLevel.Ord") "elgenerics-known" + propMod <- lookupModule (mkModuleName "Data.TypeLevel.List.Properties") + "elgenerics-known" + let coreMod = Module pkgId $ mkModuleName "Data.TypeLevel.List.Core" + mapTyCon <- tcLookupTyCon =<< lookupName coreMod (mkTcOcc "Map") + memberTyCon <- tcLookupTyCon =<< lookupName coreMod (mkTcOcc "Member") + mapApplyTyCon <- tcLookupTyCon =<< lookupName coreMod (mkTcOcc "MapApply") + elemAtTyCon <- tcLookupTyCon =<< lookupName coreMod (mkTcOcc "ElemAt") + indexTyCon' <- tcLookupTyCon =<< lookupName coreMod (mkTcOcc "Index'") + lengthTyCon <- tcLookupTyCon =<< lookupName coreMod (mkTcOcc "Length") + knownNatTyCon <- tcLookupTyCon knownNatClassName + indexedTyCon <- tcLookupTyCon =<< lookupName coreMod (mkTcOcc "Indexed") + indexedAuxTyCon <- tcLookupTyCon =<< lookupName coreMod (mkTcOcc "IndexedAux") + sortByTyCon <- tcLookupTyCon =<< lookupName coreMod (mkTcOcc "SortBy") + sortByAuxTyCon <- tcLookupTyCon =<< lookupName coreMod (mkTcOcc "SortByAux") + compare2TyCon <- tcLookupTyCon =<< lookupName ordMod (mkTcOcc "Compare2") + sortedByCls <- tcLookupClass =<< lookupName ordMod (mkTcOcc "SortedBy") + sortedByAuxTyCon <- tcLookupTyCon =<< lookupName ordMod (mkTcOcc "SortedByAux") + + presLenTyCon <- tcLookupTyCon =<< lookupName propMod (mkTcOcc "PreservesLength") + monotoneTyCon <- tcLookupTyCon =<< lookupName propMod (mkTcOcc "Monotone") + monotoneAppTyCon <- tcLookupTyCon =<< lookupName propMod (mkTcOcc "MonotoneApply") + funMod <- lookupModule (mkModuleName "Data.TypeLevel.Function") "elgenerics-known" + applyTyCon <- tcLookupTyCon =<< lookupName funMod (mkTcOcc "Apply") + dropTyCon <- tcLookupTyCon =<< lookupName coreMod (mkTcOcc "Drop") + takeTyCon <- tcLookupTyCon =<< lookupName coreMod (mkTcOcc "Take") + appListTyCon <- tcLookupTyCon =<< lookupName coreMod (mkTcOcc "++") + cnstrMod <- lookupModule (mkModuleName "Data.Constraint.Operators") "elgenerics-known" + allTyCon <- tcLookupTyCon =<< lookupName cnstrMod (mkTcOcc "All") + allDicTyCon <- tcLookupTyCon =<< lookupName cnstrMod (mkTcOcc "AllDict") + reifyDicId <- tcLookupId =<< lookupName cnstrMod (mkVarOcc "reifyDict") + + omMod <- lookupModule (mkModuleName "Data.TypeLevel.OrdMap") "elgenerics-known" + allOMTyCon <- tcLookupTyCon =<< lookupName omMod (mkTcOcc "AllOM") + omMemberTyCon <- tcLookupTyCon =<< lookupName omMod (mkTcOcc "Member") + allOMDict'FunId <- tcLookupId =<< lookupName omMod (mkVarOcc "allOMDict'") + omIndexTyCon <- tcLookupTyCon =<< lookupName omMod (mkTcOcc "Index") + sLookupWithIndex'FunId <- tcLookupId =<< lookupName omMod (mkVarOcc "sLookupWithIndex'") + + constsDictTyCon <- + tcLookupTyCon =<< lookupName cnstrMod (mkTcOcc "CustomDict") + omLookup'TyCon <- + tcLookupTyCon =<< lookupName omMod (mkTcOcc "Lookup'") + omSizeTyCon <- + tcLookupTyCon =<< lookupName omMod (mkTcOcc "Size") + omToListTyCon <- + tcLookupTyCon =<< lookupName omMod (mkTcOcc "ToList") + omToListAuxTyCon <- + tcLookupTyCon =<< lookupName omMod (mkTcOcc "ToListAux") + lookupWithIdxTyCon <- + tcLookupTyCon =<< lookupName omMod (mkTcOcc "LookupWithIndex") + lookupOMTyCon <- + tcLookupTyCon =<< lookupName omMod (mkTcOcc "Lookup") + + elimFromMaybeC'FunId <- tcLookupId =<< lookupName cnstrMod (mkVarOcc "elimFromMaybeC'") + tyMaybeMod <- lookupModule (mkModuleName "Data.TypeLevel.Maybe") "elgenerics-known" + fromMaybeTyCon <- tcLookupTyCon=<< lookupName tyMaybeMod (mkTcOcc "FromMaybe") + let appMod = Module pkgId $ mkModuleName "Data.TypeLevel.Applicative" + mapMaybeTyCon <- tcLookupTyCon=<< lookupName appMod (mkTcOcc "MapMaybe") + sFMapMaybe'FunId <- tcLookupId =<< lookupName appMod (mkVarOcc "sFMapMaybe'") + maybeCTyCon <- tcLookupTyCon=<< lookupName cnstrMod (mkTcOcc "MaybeC") + let knownCoreMod = tyMaybeMod { GHC.Plugins.moduleName = mkModuleName "Data.TypeLevel.Known.Core" } + fst1TyCon <- tcLookupTyCon =<< lookupName knownCoreMod (mkTcOcc "Fst1") + knownTyCon <- tcLookupTyCon =<< lookupName knownCoreMod (mkTcOcc "Known") + sKnownVal'FunId <- tcLookupId =<< lookupName knownCoreMod (mkVarOcc "sKnownVal'") + let omIntMod = tyMaybeMod { GHC.Plugins.moduleName = mkModuleName "Data.TypeLevel.OrdMap.Internal" } + sOrdMapTyCon <- tcLookupTyCon =<< lookupName omIntMod (mkTcOcc "SOrdMap") + ordMapTyCon <- tcLookupTyCon =<< lookupName omIntMod (mkTcOcc "OrdMap") + singTyCon <- tcLookupTyCon =<< lookupName knownCoreMod (mkTcOcc "Sing") + sOrdTyCon <- tcLookupTyCon =<< lookupName ordMod (mkTcOcc "SOrd") + sApplyClass <- tcLookupClass =<< lookupName knownCoreMod (mkTcOcc "SApply") + entryCTyCon <- tcLookupTyCon =<< lookupName omMod (mkTcOcc "EntryC") + elimMaybeCLookup'FunId <- tcLookupId =<< lookupName omMod (mkVarOcc "elimMaybeCLookup'") + return STbl{..} + +infixr 0 -->, ~> +(-->), (~>) :: Type -> Type -> Type +#if MIN_VERSION_ghc(9,0,1) +(-->) = mkFunTy VisArg Many +#else +(-->) = mkFunTy VisArg +#endif +a ~> b = a --> b --> liftedTypeKind + +listTy :: Type -> Type -- a |-> [a] +listTy = mkTyConApp listTyCon . pure + +isUnknownC :: Constr -> Bool +isUnknownC UnknownC{} = True +isUnknownC _ = False + +isUnknownTerm :: Term -> Bool +isUnknownTerm UnknownTerm{} = True +isUnknownTerm _ = False + +splitFunTy' :: Type -> (Type, Type) +#if MIN_VERSION_ghc(9,0,1) +splitFunTy' = splitFunTy >>> \case + (_, l, r) -> (l,r) +#else +splitFunTy' = splitFunTy +#endif + + +domRanKind :: FunType -> Type -> (Kind, Kind) +domRanKind Bare = splitFunTy' . typeKind +domRanKind Uncurry = \t -> + let (dom, ranStar) = splitFunTy' $ typeKind t + in (dom, fst $ splitFunTy' ranStar) + +substTerm :: SymbolTable -> [(TcTyVar, Type)] -> Term -> Term +substTerm stbl subs = + toTerm stbl . substType subs . fromTerm stbl + +data WithCtLoc a = WithCtLoc { loc :: CtLoc, value :: a } + deriving (Foldable) + +instance Eq a => Eq (WithCtLoc a) where + (==) = (==) `on` value + (/=) = (/=) `on` value + +instance Ord a => Ord (WithCtLoc a) where + (<=) = (<=) `on` value + (>=) = (>=) `on` value + (<) = (<) `on` value + (>) = (>) `on` value + compare = compare `on` value diff --git a/elgenerics-known/src/Data/TypeLevel/List/Solver/Utils.hs b/elgenerics-known/src/Data/TypeLevel/List/Solver/Utils.hs new file mode 100644 index 0000000..b5fb5cd --- /dev/null +++ b/elgenerics-known/src/Data/TypeLevel/List/Solver/Utils.hs @@ -0,0 +1,78 @@ +{-# LANGUAGE CPP #-} + +module Data.TypeLevel.List.Solver.Utils where + +import Control.Applicative +import Control.Arrow +import Control.Lens (elemOf) +import Control.Lens.Plated +import Data.Function +import Data.Ord +#if MIN_VERSION_ghc(9,0,1) +import GHC.Core.Class +import GHC.Core.Predicate +import GHC.Tc.Plugin +import GHC.Plugins hiding ((<>)) +import GHC.Core.TyCo.Rep +import GHC.Tc.Types.Constraint +#else +import Class +import Constraint +import GhcPlugins hiding ((<>)) +import Predicate +import TcPluginM hiding (newWanted) +import TyCoRep (UnivCoProvenance (..)) +#endif + +trustMe :: Type -> Type -> Coercion +trustMe = mkUnivCo (PluginProv "Data.TypeLevel.List.Solver") Representational + +trustMe' :: String -> Type -> Type -> Coercion +trustMe' msg = + mkUnivCo + (PluginProv $ "Data.TypeLevel.List.Solver: " ++ msg) + Representational + +trustMeNominal :: Type -> Type -> Coercion +trustMeNominal = mkUnivCo (PluginProv "Data.TypeLevel.List.Solver") Nominal + +myTrace :: (Outputable a) => String -> a -> TcPluginM () +myTrace lab a = + tcPluginIO $ putStrLn $ lab <> ": " <> showSDocUnsafe (ppr a) + +typeKindElem :: Type -> Kind +typeKindElem = head . snd . splitTyConApp . typeKind + +deconsPred :: PredType -> Maybe (TyCon, [Type]) +deconsPred pd = + first classTyCon <$> getClassPredTys_maybe pd + <|> splitTyConApp_maybe pd + +showOut :: (Outputable a) => a -> String +showOut = showSDocUnsafe . ppr + +newtype SubtermOrd a = SubtermOrd {runSubtermOrd :: a} + deriving (Eq) + +instance (Eq a, Plated a) => Ord (SubtermOrd a) where + SubtermOrd x <= SubtermOrd y = elemOf cosmos x y + +(<@) :: (Eq a, Plated a) => a -> a -> Bool + +infix 4 <@ + +(<@) = (<) `on` SubtermOrd + +compareSubterm :: (Eq a, Plated a) => a -> a -> Ordering +compareSubterm = comparing SubtermOrd + +mkNonCanonical' :: + CtLoc -> CtEvidence -> Ct +mkNonCanonical' origCtl ev = + let ct_ls = ctLocSpan origCtl + ctl = ctEvLoc ev + wanted = mkNonCanonical ev + in setCtLoc wanted (setCtLocSpan ctl ct_ls) + +showSDocExplicit :: SDoc -> String +showSDocExplicit = showSDocUnsafe diff --git a/elgenerics-known/src/Data/TypeLevel/List/Unsafe.hs b/elgenerics-known/src/Data/TypeLevel/List/Unsafe.hs new file mode 100644 index 0000000..bb049b1 --- /dev/null +++ b/elgenerics-known/src/Data/TypeLevel/List/Unsafe.hs @@ -0,0 +1,40 @@ +{-# LANGUAGE AllowAmbiguousTypes #-} +{-# LANGUAGE DataKinds #-} + +module Data.TypeLevel.List.Unsafe ( + unsafeWithKnownTyListBy, + unsafeWithKnownMember, +) where + +import Data.TypeLevel.List.Core +import GHC.TypeLits +import Unsafe.Coerce + +newtype WrapLen as r + = WrapLen ((KnownNat (Length as)) => r) + +unsafeWithKnownTyListBy :: + forall as bs r. + (KnownNat (Length bs)) => + ((KnownNat (Length as)) => r) -> + r +{-# INLINE unsafeWithKnownTyListBy #-} +unsafeWithKnownTyListBy f = + let len = tyListLength @bs + in unsafeCoerce + (WrapLen @as f) + (fromIntegral len :: Natural) + +newtype WrapMem x as r + = WrapMem ((Member x as) => r) + +unsafeWithKnownMember :: + forall x as r. + Natural -> + ((Member x as) => r) -> + r +{-# INLINE unsafeWithKnownMember #-} +unsafeWithKnownMember n f = + unsafeCoerce + (WrapMem @x @as f) + n diff --git a/elgenerics-known/src/Data/TypeLevel/Maybe.hs b/elgenerics-known/src/Data/TypeLevel/Maybe.hs new file mode 100644 index 0000000..0b7ea4e --- /dev/null +++ b/elgenerics-known/src/Data/TypeLevel/Maybe.hs @@ -0,0 +1,119 @@ +{-# LANGUAGE DataKinds #-} +{-# LANGUAGE GADTs #-} +{-# LANGUAGE MagicHash #-} +{-# LANGUAGE TypeFamilies #-} + +module Data.TypeLevel.Maybe ( + type FromJust, + type FromMaybe, + type FromNothing, + type MaybeApply, + MaybeApply3, + MaybeApply2, + MaybeApply1, + type ElimMaybe, + ElimMaybe3, + ElimMaybe2, + ElimMaybe1, + type (<|>), + type (<$>), + type Just, + type Nothing, + JoinMaybe, + DeconsMaybe (..), + PMaybe (..), + withDeconsMaybe, +) where + +import Data.Constraint.Deferrable +import Data.TypeLevel.Function +import Data.TypeLevel.Known +import GHC.Base (proxy#) +import GHC.Exts (Proxy#) +import GHC.TypeLits + +type family (<$>) (f :: a -> b) (m :: Maybe a) :: Maybe b where + _ <$> 'Nothing = 'Nothing + f <$> 'Just a = 'Just (f a) + +type family (<|>) (l :: Maybe a) (r :: Maybe a) :: Maybe a where + 'Nothing <|> b = b + 'Just a <|> _ = 'Just a + +type family FromJust msg (ma :: Maybe a) :: a where + FromJust _ ('Just a) = a + FromJust m _ = TypeError m + +type Just = 'Just + +type Nothing = 'Nothing + +type family FromNothing msg (v :: b) (ma :: Maybe a) :: b where + FromNothing _ v 'Nothing = v + FromNothing m _ ('Just _) = TypeError m + +type family FromMaybe (x :: a) (ma :: Maybe a) :: a where + FromMaybe x 'Nothing = x + FromMaybe _ ('Just a) = a + +type family MaybeApply (z :: b) (f :: a ~> b) (ma :: Maybe a) :: b where + MaybeApply z _ 'Nothing = z + MaybeApply _ f ('Just a) = Apply f a + +data MaybeApply3 :: b ~> (a ~> b) ~> Maybe a ~> b + +data MaybeApply2 (z :: b) :: (a ~> b) ~> Maybe a ~> b + +data MaybeApply1 (z :: b) (f :: a ~> b) :: Maybe a ~> b + +type instance Apply MaybeApply3 z = MaybeApply2 z + +type instance Apply (MaybeApply2 z) f = MaybeApply1 z f + +type instance Apply (MaybeApply1 z f) ma = MaybeApply z f ma + +type family ElimMaybe (z :: b) (f :: a -> b) (ma :: Maybe a) :: b where + ElimMaybe z _ 'Nothing = z + ElimMaybe _ f ('Just a) = f a + +data ElimMaybe3 :: b ~> (a -> b) ~> Maybe a ~> b + +data ElimMaybe2 (z :: b) :: (a -> b) ~> Maybe a ~> b + +data ElimMaybe1 (z :: b) (f :: a -> b) :: Maybe a ~> b + +type instance Apply ElimMaybe3 z = ElimMaybe2 z + +type instance Apply (ElimMaybe2 z) f = ElimMaybe1 z f + +type instance Apply (ElimMaybe1 z f) ma = ElimMaybe z f ma + +type family JoinMaybe mma where + JoinMaybe 'Nothing = 'Nothing + JoinMaybe ('Just ma) = ma + +data PMaybe (m :: Maybe a) where + PNothing :: PMaybe 'Nothing + PJust :: Proxy# x -> PMaybe ('Just x) + +class DeconsMaybe m where + sDeconsMaybe' :: PMaybe m + +instance DeconsMaybe ('Just x) where + sDeconsMaybe' = PJust proxy# + +instance DeconsMaybe 'Nothing where + sDeconsMaybe' = PNothing + +instance Deferrable (DeconsMaybe ('Just x)) where + deferEither _ = \act -> Right act + {-# INLINE deferEither #-} + +instance Deferrable (DeconsMaybe 'Nothing) where + deferEither _ = \act -> Right act + {-# INLINE deferEither #-} + +withDeconsMaybe :: + SMaybe m -> ((DeconsMaybe m) => r) -> r +withDeconsMaybe SNothing {} act = act +withDeconsMaybe SJust {} act = act diff --git a/elgenerics-known/src/Data/TypeLevel/Monoid.hs b/elgenerics-known/src/Data/TypeLevel/Monoid.hs new file mode 100644 index 0000000..166a603 --- /dev/null +++ b/elgenerics-known/src/Data/TypeLevel/Monoid.hs @@ -0,0 +1,50 @@ +{-# LANGUAGE DataKinds #-} +{-# LANGUAGE TypeFamilies #-} + +module Data.TypeLevel.Monoid ( + PSemigroup (..), + PMonoid (..), + type (<>), + Mappend1, + Mappend2, +) where + +import Data.TypeLevel.Function +import Data.TypeLevel.List.Core +import GHC.TypeLits + +class PSemigroup a where + type Mappend (l :: a) (b :: a) :: a + +data Mappend2 :: k ~> k ~> k + +data Mappend1 (a :: k) :: k ~> k + +type instance Apply Mappend2 a = Mappend1 a + +type instance Apply (Mappend1 a) b = Mappend a b + +type a <> b = Mappend a b + +infixr 6 <> + +class (PSemigroup a) => PMonoid a where + type Mempty :: a + +instance PSemigroup [k] where + type Mappend l r = l ++ r + +instance PMonoid [k] where + type Mempty = '[] + +instance PSemigroup Symbol where + type Mappend l r = AppendSymbol l r + +instance PMonoid Symbol where + type Mempty = "" + +instance PSemigroup ErrorMessage where + type Mappend l r = l ':<>: r + +instance PMonoid ErrorMessage where + type Mempty = 'Text "" diff --git a/elgenerics-known/src/Data/TypeLevel/Nat.hs b/elgenerics-known/src/Data/TypeLevel/Nat.hs new file mode 100644 index 0000000..071ffb4 --- /dev/null +++ b/elgenerics-known/src/Data/TypeLevel/Nat.hs @@ -0,0 +1,220 @@ +{-# LANGUAGE AllowAmbiguousTypes #-} +{-# LANGUAGE DataKinds #-} +{-# LANGUAGE MagicHash #-} +{-# LANGUAGE TemplateHaskell #-} +{-# LANGUAGE TypeFamilies #-} +{-# LANGUAGE UndecidableInstances #-} +{-# LANGUAGE ViewPatterns #-} + +module Data.TypeLevel.Nat ( + (%+), + (%-), + (%<=?), + withKnownNat, + withKnownNatLeq, + ShowNat, + ShowDigit, + deferNatLeq, + deferNatLeqWith, + caseNatLeq, + tnat, + module TN, +) where + +import Control.Arrow ((&&&)) +import Control.Monad +import Data.Map qualified as M +import Data.Maybe (fromMaybe) +import Data.Proxy +import Data.Type.Equality +import Data.TypeLevel.Known +import Data.TypeLevel.Ord.Internal +import GHC.Exts (proxy#) +import GHC.TypeLits +import GHC.TypeLits qualified as TL +import GHC.TypeNats as TN +import Language.Haskell.TH (ExpQ, PatQ, integerL, litP, mkName, numTyLit, varT, viewP) +import Language.Haskell.TH.Lib (TypeQ, caseE, litT, match, normalB, wildP) +import Language.Haskell.TH.Quote (QuasiQuoter (..)) +import Text.Read (readMaybe) +import Unsafe.Coerce + +newtype WrapN a b = WrapN ((KnownNat a) => Proxy a -> b) + +withKnownNat :: + forall a. + Word -> + (forall n. (KnownNat (n :: Nat)) => Proxy n -> a) -> + a +{-# INLINE withKnownNat #-} +withKnownNat i act = unsafeCoerce (WrapN act) (fromIntegral i :: Natural) Proxy + +withKnownNatLeq :: + forall ub a. + (KnownNat ub) => + Proxy ub -> + Word -> + (forall n. (KnownNat (n :: Nat), n <= ub) => Proxy n -> a) -> + Maybe a +{-# INLINE withKnownNatLeq #-} +withKnownNatLeq _ i act = do + let i' = fromIntegral i :: Natural + guard $ i' <= TN.natVal (Proxy @ub) + pure $ + withKnownNat i $ \p@(Proxy :: Proxy k) -> + gcastWith (unsafeCoerce (Refl @()) :: (k <=? ub) :~: 'True) $ + act p + +type family ShowDigit (n :: Nat) :: Symbol where + ShowDigit 0 = "0" + ShowDigit 1 = "1" + ShowDigit 2 = "2" + ShowDigit 3 = "3" + ShowDigit 4 = "4" + ShowDigit 5 = "5" + ShowDigit 6 = "6" + ShowDigit 7 = "7" + ShowDigit 8 = "8" + ShowDigit 9 = "9" + +type ShowNat n = ShowNatAux 'False "" n + +type family ShowNatAux (showZero :: Bool) (heads :: Symbol) (n :: Nat) :: Symbol where + ShowNatAux 'True hd 0 = hd `AppendSymbol` "0" + ShowNatAux _ s n = + CaseOrdering + (CmpNat n 10) + (ShowDigit n `AppendSymbol` s) + (ShowNatAux 'True (ShowDigit (n `Mod` 10) `AppendSymbol` s) (n `Div` 10)) + (ShowNatAux 'True (ShowDigit (n `Mod` 10) `AppendSymbol` s) (n `Div` 10)) + +infixl 6 %+ + +(%+) :: SNat n -> SNat m -> SNat (n + m) +l %+ r = + unsafeCoerce @Natural $ + demote l + demote r + +infixl 6 %- + +(%-) :: SNat n -> SNat m -> SNat (n - m) +l %- r = + unsafeCoerce $ + demote l - demote r + +(%<=?) :: SNat n -> SNat m -> SBool (n <=? m) +n %<=? m = + if demote n <= demote m + then unsafeCoerce STrue + else unsafeCoerce SFalse + +infix 4 %<=? + +{- | Special deferring operator for builtin type-level ordering. + + See also: 'deferNatLeqWith' +-} +deferNatLeq :: + forall n m x. + (KnownNat n, KnownNat m) => + ((n <= m) => x) -> + Either String x +deferNatLeq = + deferNatLeqWith @n @m $ + ( "Type level inequality unsatisfied: " + <> show (TN.natVal @n Proxy) + <> " <= " + <> show (TN.natVal @n Proxy) + ) + +{- | Special deferring operator for builtin type-level ordering, + with failure error message. + + See also: 'deferNatLeqWith' +-} +deferNatLeqWith :: + forall n m x. + (KnownNat n, KnownNat m) => + -- | Error message + String -> + ((n <= m) => x) -> + Either String x +deferNatLeqWith errMsg act = + case sKnownVal' @n %<=? sKnownVal' @m of + STrue -> Right act + SFalse -> Left errMsg + +tnat :: QuasiQuoter +tnat = + QuasiQuoter + { quoteExp = \n -> + [|sKnownVal' @($(parseNat n))|] + , quotePat = \n -> + let (theView, expectedP) = concreteNat n + in viewP + [| + $theView + &&& ( ( \(_ :: SNat m) -> + unsafeCoerce (Equal @() @()) :: + Equality m $(parseNat n) + ) :: + forall m. SNat m -> Equality m $(parseNat n) + ) + &&& ( ( \(_ :: SNat m) -> + unsafeCoerce (Equal @() @()) :: + Equality $(parseNat n) m + ) :: + forall m. SNat m -> Equality $(parseNat n) m + ) + |] + [p|($expectedP, (Equal, Equal))|] + , quoteDec = error "No definition for type natural" + , quoteType = parseNat + } + where + concreteNat :: String -> (ExpQ, PatQ) + concreteNat inp = + case readMaybe inp of + Just n -> + ( [|TL.natVal|] + , litP $ integerL n + ) + Nothing -> + ([|(TL.natVal' @($(varT $ mkName inp)) ==)|], [p|True|]) + parseNat :: String -> TypeQ + parseNat inp = + case readMaybe @Natural inp of + Just n -> litT $ numTyLit $ fromIntegral n + Nothing -> [t|($(varT $ mkName inp) :: Nat)|] + +caseNatLeq :: Natural -> TypeQ -> ExpQ -> ExpQ +caseNatLeq ub ty = flip (caseNatLeqWith ub ty) [] + +caseNatLeqWith :: Natural -> TypeQ -> ExpQ -> [(Natural, ExpQ)] -> ExpQ +caseNatLeqWith ub ty def cases = do + when (any ((> ub) . fst) cases) $ do + fail $ "Indices must be <= " <> show ub <> ", but got: " <> show (map fst cases) + when (maybe False ((> ub) . fst) $ M.lookupMax dic) $ + fail $ + "Case out of range: " <> show (fst <$> M.lookupMax dic) + [| + let a = () :: (KnownNat $ty, $ty <= $(litT $ numTyLit $ fromIntegral ub)) => () + in a `seq` $body + |] + where + dic = M.fromList cases + body :: ExpQ + body = + caseE [|TL.natVal' @($ty) proxy#|] $ + map mkMatch [0 .. ub] + ++ [match wildP (normalB [|error "caseNatLeqWith: Bug in GHC!"|]) []] + mkMatch n = + let reslE = fromMaybe def $ M.lookup n dic + concNTy = litT $ numTyLit $ toInteger n + bodyE = + [| + gcastWith + (unsafeCoerce (Refl :: () :~: ()) :: $ty :~: $concNTy) + $(reslE) + |] + in match (litP $ integerL $ toInteger n) (normalB bodyE) [] diff --git a/elgenerics-known/src/Data/TypeLevel/Normalise/Plugin.hs b/elgenerics-known/src/Data/TypeLevel/Normalise/Plugin.hs new file mode 100644 index 0000000..3392c79 --- /dev/null +++ b/elgenerics-known/src/Data/TypeLevel/Normalise/Plugin.hs @@ -0,0 +1,137 @@ +{-# LANGUAGE CPP #-} +{-# LANGUAGE RecordWildCards #-} +{-# LANGUAGE TypeFamilies #-} +{-# LANGUAGE ViewPatterns #-} + +module Data.TypeLevel.Normalise.Plugin (plugin, Normalise) where + +import Data.Generics (everywhereM, mkM) +#if MIN_VERSION_ghc(9,0,1) +#if MIN_VERSION_ghc(9,2,0) +import GHC.Unit.Finder +import GHC.Tc.Solver +#else +import GHC.Driver.Finder (findPluginModule) +#endif +import GHC.Hs.Decls +import GHC.Hs.Extension +import GHC.Hs.Type +import GHC.Plugins +import GHC.Iface.Env (lookupOrig) +import GHC.Tc.Utils.Env +import GHC.Tc.Gen.HsType +import GHC.Tc.Utils.Monad +import GHC.Tc.Utils.Zonk (zonkTcTypeToType) +import GHC.Tc.Instance.Family +import GHC.Core.FamInstEnv (normaliseType) +#else +import FamInst (tcGetFamInstEnvs) +import FamInstEnv (normaliseType) +import Finder (findPluginModule) +import GHC.Hs.Decls +import GHC.Hs.Extension +import GHC.Hs.Types +import GhcPlugins +import IfaceEnv (lookupOrig) +import TcEnv +import TcHsSyn +import TcHsType +import TcRnMonad +#endif + +type family Normalise (a :: k) :: k where + Normalise a = a + +{- | @'Normalise' ty@ の形の型の @ty@ 部分の型族を可能な限り展開した形にする + 型検査器プラグイン。ワイルドカードは未対応(面倒なので)。 + + * Normalise シノニムで包まれた型族の適用を可能な限り展開する + * 他モジュールで定義されたものしか扱えない限定あり + * 簡約が可能な制約があれば、簡約してメモ化 + * あんまり効果なさそう + * 型検査通過後、簡約可能な型シノニムを可能な限り展開する + 更に型レベルの計算の重複を削減出来る +-} +plugin :: Plugin +plugin = + defaultPlugin + { pluginRecompile = purePlugin + , renamedResultAction = reducer + , typeCheckResultAction = \flags -> + if "specified-only" `elem` flags + then const pure + else const reduceTcGbl + } + +reduceTcGbl :: + TcGblEnv -> TcM TcGblEnv +reduceTcGbl env = do + tcs <- mapM reduceTyCon $ tcg_tcs env + pure env {tcg_tcs = tcs} + +reduceTyCon :: TyCon -> TcM TyCon +reduceTyCon tyCon + | Just rhs <- synTyConRhs_maybe tyCon + , not $ tyConResKind tyCon `eqType` constraintKind = + do + rhs' <- reduceType rhs + let binders = tyConBinders tyCon + if rhs `eqType` rhs' + then pure tyCon + else do + let tyCon' = + mkSynonymTyCon + (tyConName tyCon) + binders + (tyConResKind tyCon) + (tyConRoles tyCon) + rhs' + (isTauTyCon tyCon) + (isFamFreeTyCon tyCon) + (isForgetfulSynTyCon tyCon) + traceRn "Normed: " $ ppr (tyCon, tyCon') + pure tyCon' + | otherwise = pure tyCon + +reducer :: [CommandLineOption] -> TcGblEnv -> HsGroup GhcRn -> TcM (TcGblEnv, HsGroup GhcRn) +reducer _ gblEnv grp = do + env <- getTopEnv + Found _ ovlMod <- + liftIO $ findPluginModule env $ mkModuleName "Data.TypeLevel.Normalise.Plugin" + normName <- lookupOrig ovlMod (mkTcOcc "Normalise") + setGblEnv gblEnv $ + (gblEnv,) <$> everywhereM (mkM $ rewriteNormalise normName) grp + +rewriteNormalise :: Name -> TyClDecl GhcRn -> TcM (TyClDecl GhcRn) +rewriteNormalise + norm + sdecl@SynDecl {tcdTyVars = HsQTvs _ exps} = do + tys <- mapM (\(L _ a) -> resolveTyVarBndr a) exps + tcExtendTyVarEnv tys $ everywhereM (mkM $ rewriteHsTy norm) sdecl +rewriteNormalise norm dcl = everywhereM (mkM $ rewriteHsTy norm) dcl + +resolveTyVarBndr :: HsTyVarBndr a GhcRn -> TcM TyVar +resolveTyVarBndr (UserTyVar _ _ (L _ n)) = do + pure $ mkTyVar n liftedTypeKind +resolveTyVarBndr (KindedTyVar _ _ (L _ n) lk) = do + kind <- tcLHsKindSig (GhciCtxt False) lk + pure $ mkTyVar n kind +#if !MIN_VERSION_ghc(9,0,1) +resolveTyVarBndr (XTyVarBndr vacuous) = noExtCon vacuous +#endif + +rewriteHsTy :: Name -> HsType GhcRn -> TcM (HsType GhcRn) +rewriteHsTy norm (HsAppTy _ (L _ (HsTyVar _ NotPromoted (L _ nm))) rhs) + | nm == norm = fmap XHsType . reduceType =<< fromLHsType rhs +rewriteHsTy _ ty = pure ty + +fromLHsType :: LHsType GhcRn -> TcM Type +fromLHsType ty = do + -- Copied partially from @tcRnType@ + (ty', _) <- pushTcLevelM_ $ solveEqualities "fromLHsType" $ tcInferLHsTypeKind ty + zonkTcTypeToType ty' + +reduceType :: Type -> TcM Type +reduceType ty = do + envs <- tcGetFamInstEnvs + pure $ snd $ normaliseType envs Nominal ty diff --git a/elgenerics-known/src/Data/TypeLevel/Ord.hs b/elgenerics-known/src/Data/TypeLevel/Ord.hs new file mode 100644 index 0000000..14d6b00 --- /dev/null +++ b/elgenerics-known/src/Data/TypeLevel/Ord.hs @@ -0,0 +1,274 @@ +{-# LANGUAGE DataKinds #-} +{-# LANGUAGE ExplicitNamespaces #-} +{-# LANGUAGE GADTs #-} +{-# LANGUAGE LambdaCase #-} +{-# LANGUAGE TypeFamilies #-} +{-# LANGUAGE UndecidableInstances #-} +{-# LANGUAGE UndecidableSuperClasses #-} +{-# OPTIONS_GHC -Wno-orphans #-} + +module Data.TypeLevel.Ord ( + Ordering (..), + type LT, + type EQ, + type GT, + Compare2, + Compare1, + Max, + Min, + Comparing, + Comparing1, + Comparing2, + Comparing3, + Comparing4, + POrd (..), + SOrd (..), + sCaseOrdering, + SortedBy, + Sorted, + Merge, + sLex, + Lex, + Lex2, + Lex1, + CaseOrdering, +) where + +import Data.Kind +import Data.TypeLevel.Bool +import Data.TypeLevel.Function +import Data.TypeLevel.Known +import Data.TypeLevel.Monoid +import Data.TypeLevel.Nat +import Data.TypeLevel.Ord.Internal +import Data.TypeLevel.Typeable +import Data.Void (Void) +import GHC.TypeLits as TL +import Unsafe.Coerce (unsafeCoerce) + +type family Lex (l :: Ordering) (r :: Ordering) :: Ordering where + Lex LT _ = LT + Lex EQ r = r + Lex GT _ = GT + +data Lex2 :: Ordering ~> Ordering ~> Ordering + +data Lex1 (l :: Ordering) :: Ordering ~> Ordering + +type instance Apply Lex2 l = Lex1 l + +type instance Apply (Lex1 l) r = Lex l r + +type Max n m = CaseOrdering (Compare n m) m m n + +type Min n m = CaseOrdering (Compare n m) n n m + +instance PSemigroup Ordering where + type Mappend l r = Lex l r + +instance PMonoid Ordering where + type Mempty = EQ + +class POrd a where + type Compare (l :: a) (r :: a) :: Ordering + +data Compare2 :: k ~> k ~> Ordering + +data Compare1 (a :: k) :: k ~> Ordering + +type instance Apply Compare2 a = Compare1 a + +type instance Apply (Compare1 a) b = Compare a b + +type family CmpList l r where + CmpList '[] '[] = EQ + CmpList '[] (_ ': _) = LT + CmpList (_ ': _) '[] = GT + CmpList (a ': as) (b ': bs) = Compare a b <> CmpList as bs + +instance (POrd a) => POrd [a] where + type Compare l r = CmpList l r + +instance POrd Nat where + type Compare a b = CmpNat a b + +instance POrd Symbol where + type Compare a b = CmpSymbol a b + +type family CmpMaybe l r where + CmpMaybe 'Nothing 'Nothing = EQ + CmpMaybe 'Nothing ('Just _) = LT + CmpMaybe ('Just _) 'Nothing = GT + CmpMaybe ('Just l) ('Just r) = Compare l r + +instance (POrd a) => POrd (Maybe a) where + type Compare l r = CmpMaybe l r + +instance POrd PTypeRep where + type Compare l r = CmpTypeRep l r + +instance POrd Type where + type Compare l r = Compare (TypeRepOf l) (TypeRepOf r) + +class (SortedByAux cmp as) => SortedBy cmp as + +instance (SortedByAux cmp as) => SortedBy cmp as + +type family + SortedByAux + (cmp :: k ~> k ~> Ordering) + (ks :: [k]) :: + Constraint + where + SortedByAux _ '[] = () + SortedByAux _ '[x] = () + SortedByAux cmp (a ': b ': as) = + CaseOrdering + (Apply (Apply cmp a) b) + (SortedByAux cmp (b ': as)) + (SortedByAux cmp (b ': as)) + (Throw ('Text "List not sorted: " ':<>: 'ShowType (a ': b ': as))) + +type Sorted xs = SortedBy Compare2 xs + +type family Throw m where + Throw m = TypeError m + +instance (POrd a, POrd b) => POrd (a, b) where + type Compare l r = CmpTuple l r + +type family CmpTuple (l :: (a, b)) (r :: (a, b)) :: Ordering where + CmpTuple '(a, b) '(c, d) = Compare a c `Lex` Compare b d + +type Comparing cmp f x y = (Apply (Apply cmp (Apply f x)) (Apply f y) :: Ordering) + +data Comparing4 :: (k' ~> k' ~> Ordering) ~> (k ~> k') ~> (k ~> k ~> Ordering) + +data Comparing3 (cmp :: k' ~> k' ~> Ordering) :: (k ~> k') ~> (k ~> k ~> Ordering) + +data Comparing2 (cmp :: k' ~> k' ~> Ordering) (map :: (k ~> k')) :: (k ~> k ~> Ordering) + +data Comparing1 (cmp :: k' ~> k' ~> Ordering) (map :: (k ~> k')) (x :: k) :: (k ~> Ordering) + +type instance Apply Comparing4 cmp = Comparing3 cmp + +type instance Apply (Comparing3 cmp) f = Comparing2 cmp f + +type instance Apply (Comparing2 cmp f) x = Comparing1 cmp f x + +type instance Apply (Comparing1 cmp f x) y = Comparing cmp f x y + +type family Merge xs ys where + Merge '[] ys = ys + Merge xs '[] = xs + Merge (x ': xs) (y ': ys) = + MergeAux (Compare x y) x y xs ys + +type family MergeAux cmp x y xs ys where + MergeAux 'LT x y xs ys = x ': Merge xs (y ': ys) + MergeAux 'EQ x y xs ys = x ': Merge xs ys + MergeAux 'GT x y xs ys = y ': Merge (x ': xs) ys + +class SOrd k where + sCompare :: Sing (l :: k) -> Sing (r :: k) -> Sing (Compare l r) + +instance SOrd Nat where + {-# INLINE sCompare #-} + sCompare (n :: SNat n) (m :: SNat m) = + case compare (knownNatVal n) (knownNatVal m) of + LT -> unsafeCoerce SLT + EQ -> unsafeCoerce SEQ + GT -> unsafeCoerce SGT + +instance SOrd Symbol where + {-# INLINE sCompare #-} + sCompare (n :: SSymbol n) (m :: SSymbol m) = + case compare (knownSymbolVal n) (knownSymbolVal m) of + LT -> unsafeCoerce SLT + EQ -> unsafeCoerce SEQ + GT -> unsafeCoerce SGT + +instance (SOrd k) => SOrd [k] where + {-# INLINE sCompare #-} + sCompare SNil SNil = SEQ + sCompare SNil (:%) {} = SLT + sCompare (:%) {} SNil = SGT + sCompare (x :% xs) (y :% ys) = + sCompare x y `sLex` sCompare xs ys + +instance (SOrd k, SOrd k') => SOrd (k, k') where + sCompare (SPair a b) (SPair a' b') = + sCompare a a' `sLex` sCompare b b' + {-# INLINE sCompare #-} + +instance SOrd PTypeRep where + sCompare l r = + case sTestEquality l r of + Equal -> SEQ + NonEqual -> case (l, r) of + (STySym s, STySym t) -> sCompare s t + (STySym _, STyNat {}) -> SLT + (STySym _, SCon {}) -> SLT + (STySym _, STyApp {}) -> SLT + (STySym _, STyFun {}) -> SLT + (STyNat n, STyNat m) -> sCompare n m + (STyNat {}, STySym {}) -> SGT + (STyNat {}, SCon {}) -> SLT + (STyNat {}, STyApp {}) -> SLT + (STyNat {}, STyFun {}) -> SLT + (SCon a b c, SCon x y z) -> + sCompare a x + `sLex` sCompare b y + `sLex` sCompare c z + (SCon {}, STySym {}) -> SGT + (SCon {}, STyNat {}) -> SGT + (SCon {}, STyApp {}) -> SLT + (SCon {}, STyFun {}) -> SLT + (STyApp f x, STyApp g y) -> + sCompare f g `sLex` sCompare x y + (STyApp {}, STyFun {}) -> SLT + (STyApp {}, STySym {}) -> SGT + (STyApp {}, STyNat {}) -> SGT + (STyApp {}, SCon {}) -> SGT + (STyFun a b, STyFun a' b') -> + sCompare a a' `sLex` sCompare b b' + (STyFun {}, STySym {}) -> SGT + (STyFun {}, STyNat {}) -> SGT + (STyFun {}, SCon {}) -> SGT + (STyFun {}, STyApp {}) -> SGT + +instance SOrd Type where + sCompare l r = + sTypeRepOf l `sCompare` sTypeRepOf r + +infixr 9 `sLex` + +sLex :: Sing l -> Sing (q :: Ordering) -> Sing (l `Lex` q) +sLex SLT _ = SLT +sLex SEQ r = r +sLex SGT _ = SGT + +sCaseOrdering :: + SOrdering ord -> + Sing lt -> + Sing eq -> + Sing gt -> + Sing (CaseOrdering ord lt eq gt) +{-# INLINE sCaseOrdering #-} +sCaseOrdering SLT lt _ _ = lt +sCaseOrdering SEQ _ eq _ = eq +sCaseOrdering SGT _ _ gt = gt + +instance POrd Void where + type Compare b b' = CmpVoid b b' + +type family CmpVoid (bo :: Void) (bot' :: Void) :: Ordering where + +instance SOrd Void where + sCompare = \case {} + +instance POrd Bool where + type Compare a b = CmpBool a b + +instance SOrd Bool where + sCompare = sCmpBool diff --git a/elgenerics-known/src/Data/TypeLevel/Ord/Internal.hs b/elgenerics-known/src/Data/TypeLevel/Ord/Internal.hs new file mode 100644 index 0000000..2a3a461 --- /dev/null +++ b/elgenerics-known/src/Data/TypeLevel/Ord/Internal.hs @@ -0,0 +1,12 @@ +{-# LANGUAGE DataKinds #-} +{-# LANGUAGE ExplicitNamespaces #-} +{-# LANGUAGE TypeFamilies #-} +{-# LANGUAGE UndecidableInstances #-} +{-# OPTIONS_GHC -Wno-orphans #-} + +module Data.TypeLevel.Ord.Internal where + +type family CaseOrdering (ord :: Ordering) lt eq gt where + CaseOrdering 'LT lt _ _ = lt + CaseOrdering 'EQ _ eq _ = eq + CaseOrdering 'GT _ _ gt = gt diff --git a/elgenerics-known/src/Data/TypeLevel/OrdMap.hs b/elgenerics-known/src/Data/TypeLevel/OrdMap.hs new file mode 100644 index 0000000..8396456 --- /dev/null +++ b/elgenerics-known/src/Data/TypeLevel/OrdMap.hs @@ -0,0 +1,2634 @@ +{-# LANGUAGE AllowAmbiguousTypes #-} +{-# LANGUAGE DataKinds #-} +{-# LANGUAGE DerivingStrategies #-} +{-# LANGUAGE DerivingVia #-} +{-# LANGUAGE GADTs #-} +{-# LANGUAGE LambdaCase #-} +{-# LANGUAGE PartialTypeSignatures #-} +{-# LANGUAGE TemplateHaskell #-} +{-# LANGUAGE TypeFamilies #-} +{-# LANGUAGE UndecidableInstances #-} +{-# LANGUAGE UndecidableSuperClasses #-} +{-# LANGUAGE ViewPatterns #-} +{-# OPTIONS_GHC -Wall -Wno-orphans -Wno-partial-type-signatures #-} +{-# OPTIONS_GHC -fprint-explicit-kinds -fprint-explicit-foralls #-} + +module Data.TypeLevel.OrdMap ( + OrdMap, + type Branch, + type Leaf, + ToList, + FromList, + FromAscList, + UnsafeFromAscList, + sFromList, + sToList, + UnsafeFromAscListOfSize, + Member, + NotMember, + Singleton, + sSingleton, + Empty, + sEmpty, + type Null, + sNull, + Insert, + sInsert, + Index, + IndexM, + Equivalent, + Equivalent', + sEquivalent, + Equivalence (..), + SEquivalence (..), + AlignOM, + sAlignOM, + Split, + sSplit, + Join, + sJoin, + ThenEqv, + sThenEqv, + Disjoint, + sDisjoint, + Disjointness (..), + SDisjointness (..), + MergePerm, + sMergePerm, + Size, + sSize, + FieldAt, + FieldAtM, + SField (..), + BothC, + FieldC, + Color, + SColor (..), + B, + R, + RankT, + SRankT (..), + EntryAtM, + EntryAt, + Delete, + Intersect, + Merge, + sMerge, + LabelAtM, + LabelAt, + sFMapOM, + MapApplyWithKey, + MapWithKey, + MapKeysMonotonic, + MapApplyKeysMonotonic, + LookupWithIndex, + Lookup, + Lookup', + Field (..), + type (:::), + ConstField, + ConstField1, + ConstFields, + ConstFields1, + Label, + Entry, + sLabel, + sEntry, + Labels, + Entries, + Label', + Entry', + sLabels, + sEntries, + ConstMap, + sConstMap, + ConstList, + sConstList, + toConstListMembership, + fromConstListMembership, + withAllConstMap, + sortAllDict, + SortableList, + SortableLabels, + SortPermutation, + sortPermutation, + sSortPermutation, + Sortedness (..), + LabelSorted, + memberToList, + fieldAtToList, + withToListMember, + elimMemberToList, + allOMIntro, + allOMDictIntro, + deferAllOMWith, + sortAllFieldC, + unsortMembership, + withOrdMapMember, + indexFieldAt, + elemAtFieldDistrib, + elimConstField, + withLabelsMember, + withUnsortedMember, + withUnsortedMember', + withLabelIndex, + + -- * Debug Type operators + BlackCountInvariant, + RedRedInvariant, + ValidRBTree, + Paths, + BlackCounts, + SOrdMap (), + sLookupWithIndex, + sLookupWithIndex', + OMMembership (), + AllOM (..), + omMembership, + SomeOMMember (..), + DeferrableFor2, + omMembership', + allOMDict', + CustomDict (..), + LabelC, + EntryC, + foldMapOrdMap, + foldMapOrdMapC, + foldMapOrdMap', + foldMapOrdMapC', + foldrMOrdMap, + foldrMOrdMapC, + foldrOrdMap, + foldrOrdMapC, + foldlMOrdMap', + foldlMOrdMapC', + foldlOrdMap', + foldlOrdMapC', + fromLabelListMember, + allOMToListAll, + elimAllOM, + allOMToAllFieldCDict, + elimFieldCons, + toSomeColor, + colorVal, + sColorVal, + elimMaybeCLookup', + + -- * Unsafe operations + unsafeWithOrdMapMember, +) where + +import Control.Category.Monoid +import Data.Constraint +import Data.Constraint.Deferrable +import Data.Constraint.Operators +import Data.Functor ((<&>)) +import Data.Kind (Type) +import Data.Maybe (fromJust) +import Data.Monoid (Endo (..)) +import Data.Proxy +import Data.These +import Data.Type.Equality +import Data.TypeLevel.Applicative as App hiding (Empty) +import Data.TypeLevel.Function +import Data.TypeLevel.Known +import Data.TypeLevel.List hiding (Index, Member, natVal) +import Data.TypeLevel.List qualified as List +import Data.TypeLevel.List.Overloaded qualified as List +import Data.TypeLevel.List.Unsafe (unsafeWithKnownMember) +import Data.TypeLevel.Maybe hiding (type (<$>), type (<|>)) +import Data.TypeLevel.Ord hiding (Merge) +import Data.TypeLevel.OrdMap.Internal +import Data.Vector qualified as V +import Data.Vector.Unboxed qualified as U +import GHC.Generics hiding (R) +import GHC.TypeLits hiding (natVal) +import GHC.TypeNats (natVal) +import Type.Reflection +import Unsafe.Coerce + +data Equivalence k v + = IsEquivalent + | SizeMismatch Nat Nat + | MustBeEmpty (OrdMap k v) + | KeyNotFound k v (OrdMap k v) + | ValueMismatch k v v (OrdMap k v, v, OrdMap k v) + +defineSingletons ''Equivalence +deriveShowSing ''Equivalence +deriveKnown ''Equivalence +deriveSTestEquality ''Equivalence + +infix 9 :::, :%:: + +data Field l k = l ::: k + deriving (Read, Show, Eq, Ord, Typeable, Generic) + +data SField (f :: Field l k) where + (:%::) :: Sing l -> Sing k -> SField (l '::: k) + +deriving instance + (ShowSing l, ShowSing k) => + Show (SField (fld :: Field l k)) + +type instance Sing = SField + +instance (Known l, Known k) => Known (l ::: k) where + sKnownVal' = sKnownVal' @l :%:: sKnownVal' @k + +instance (HasSing l, HasSing k) => HasSing (Field l k) where + type Demote (Field l k) = Field (Demote l) (Demote k) + promote (l ::: k) = + case (promote l, promote k) of + (MkSomeSing sl, MkSomeSing sk) -> MkSomeSing $ sl :%:: sk + demote (sl :%:: sk) = demote sl ::: demote sk + +instance (SingTypeable l, SingTypeable r) => SingTypeable (Field l r) where + singTypeRep (l :%:: r) = + withSingTypeable l $ withSingTypeable r typeRep + +instance + (STestEquality l, STestEquality k) => + STestEquality (Field l k) + where + sTestEquality = \(l :%:: k) (l' :%:: k') -> + case (sTestEquality l l', sTestEquality k k') of + (Equal, Equal) -> Equal + (NonEqual, _) -> unsafeCoerce $ NonEqual @0 @1 + (_, NonEqual) -> unsafeCoerce $ NonEqual @0 @1 + +type (:::) = '(:::) + +type Entries xs = MapApply Entry' (ToList xs) + +type Labels xs = MapApply Label' (ToList xs) + +type family Entry (a :: Field l k) :: k where + Entry (_ ::: x) = x + +data Entry' :: Field l k ~> k + +type instance Apply Entry' a = Entry a + +type family FMapApply f a where + FMapApply f 'Leaf = 'Leaf + FMapApply f ('Branch c n rk l k v r) = + 'Branch c n rk (FMapApply f l) k (Apply f v) (FMapApply f r) + +instance PFunctor (OrdMap k) where + type (<$>) f dic = FMapApply f dic + +type family Label (a :: Field l k) :: l where + Label (label ::: _) = label + +data Label' :: Field l k ~> l + +type instance Apply Label' a = Label a + +type family Rank (dic :: OrdMap k v) :: RankT where + Rank Leaf = MkRankT 1 + Rank (Branch _ _ rk _ _ _ _) = rk + +type family Size (dic :: OrdMap k v) :: SizeT where + Size 'Leaf = 0 + Size ('Branch _ n _ _ _ _ _) = n + +type Leaf = 'Leaf + +type Branch = 'Branch + +type Empty = 'Leaf + +sEmpty :: SOrdMap Empty +sEmpty = SLeaf + +type family Null (dic :: OrdMap k v) where + Null 'Leaf = 'True + Null _ = 'False + +sNull :: SOrdMap dic -> SBool (Null dic) +sNull SLeaf = STrue +sNull SBranch {} = SFalse + +type Singleton k v = 'Branch 'B 1 (MkRankT 2) Leaf k v Leaf + +type NotMember x xs = + FromNothing + ( 'Text "Key " + ':<>: 'ShowType x + ':<>: 'Text " must not be present in " + ':<>: 'ShowType (ToList xs) + ) + (() :: Constraint) + (LookupWithIndex x xs) + +type Lookup' :: + forall k v. + k -> + OrdMap k v -> + v +type Lookup' k dic = + FromJust + ( 'Text "Key `" + ':<>: 'ShowType k + ':<>: 'Text " doesn't exist in " + ':<>: 'ShowType (ToList dic) + ) + (Lookup k dic) + +type Equivalent l r = (FromEquivalence (Equivalent' l r) :: Constraint) + +type family FromEquivalence (eqv :: Equivalence k v) :: Constraint where + FromEquivalence 'IsEquivalent = () + FromEquivalence ('MustBeEmpty tr) = + TypeError ('Text "OrdMap should be empty, but got: " ':$$: 'ShowType tr) + FromEquivalence ('SizeMismatch n m) = + TypeError + ( 'Text "Given OrdMaps must have the same size, but got: " + ':<>: 'ShowType '(n, m) + ) + FromEquivalence ('KeyNotFound k v tr') = + TypeError + ( 'Text "A tree must have a key-value pair" + ':<>: 'ShowType '(k, v) + ':$$: 'Text ", but given: " + ':<>: 'ShowType tr' + ) + FromEquivalence ('ValueMismatch k v v' tr') = + TypeError + ( 'Text "A key `" + ':<>: 'ShowType k + ':<>: 'Text "' has different associated value:" + ':$$: 'Text "\texpected: " + ':<>: 'ShowType v + ':$$: 'Text "\t but got: " + ':<>: 'ShowType v' + ':$$: 'Text "\tin sub(tree): " + ':<>: 'ShowType tr' + ) + +type family + Equivalent'_ (p :: Bool) (l :: OrdMap k v) (r :: OrdMap k v) :: + Equivalence k v + where + Equivalent'_ 'True _ _ = 'IsEquivalent + Equivalent'_ 'False 'Leaf tr = 'MustBeEmpty tr + Equivalent'_ 'False tr 'Leaf = 'MustBeEmpty tr + Equivalent'_ 'False (Branch _ n _ l k v r) r' = + EquivAux (n === Size r') n (Size r') r' (Split k r') l k v r + +type Equivalent' l r = Equivalent'_ (l === r) l r + +-- Equivalent' l' (Branch _ n _ l k v r) = +-- EquivAux (n == Size l') n (Size l') l' (Split k l') l k v r + +(%==) :: (STestEquality k) => Sing (a :: k) -> Sing b -> SBool (a == b) +l %== b = case sTestEquality l b of + Equal -> STrue + NonEqual -> SFalse + +sEquivalent :: + (SOrd key, STestEquality key, STestEquality val) => + SOrdMap (l :: OrdMap key val) -> + SOrdMap r -> + SEquivalence (Equivalent' l r) +sEquivalent l0 r0 = + case sTestEquality l0 r0 of + Equal -> SIsEquivalent + NonEqual -> + case (l0, r0) of + (SLeaf, r@SBranch {}) -> SMustBeEmpty r + (r@SBranch {}, SLeaf) -> SMustBeEmpty r + (SBranch _ n _ l k v r, r'@SBranch {}) -> + let nr' = sSize r' + in sEquivAux (n %=== nr') n nr' r' (sSplit k r') l k v r + +type family ThenEqv eqv eqv' where + ThenEqv 'IsEquivalent eqv' = eqv' + ThenEqv err _ = err + +infixr 1 `ThenEqv`, `sThenEqv` + +sThenEqv :: SEquivalence eq -> SEquivalence eq' -> Sing (eq `ThenEqv` eq') +sThenEqv SIsEquivalent s = s +sThenEqv emp@SMustBeEmpty {} _ = emp +sThenEqv emp@SSizeMismatch {} _ = emp +sThenEqv emp@SValueMismatch {} _ = emp +sThenEqv emp@SKeyNotFound {} _ = emp + +type family EquivAux p n m tr' trpl l k v r where + EquivAux 'True _ _ tr' '(_, 'Nothing, _) _ k v _ = + 'KeyNotFound k v tr' + EquivAux 'True _ _ tr '(l', 'Just '(_, v'), r') l k v r = + ChkEqual (v == v') l' r' k v v' + `ThenEqv` Equivalent' l' l + `ThenEqv` Equivalent' r' r + EquivAux 'False n m _ _ _ _ _ _ = 'SizeMismatch n m + +sEquivAux :: + (SOrd key, STestEquality key, STestEquality val) => + SBool p -> + SNat n -> + SNat m -> + SOrdMap tr' -> + STriple trpl -> + SOrdMap l -> + Sing (k :: key) -> + Sing (v :: val) -> + SOrdMap r -> + Sing (EquivAux p n m tr' trpl l k v r) +sEquivAux STrue _ _ tr' (SMkTriple l' sroot r') l k v r = + case sroot of + SNothing -> SKeyNotFound k v tr' + (SJust (SPair _ v')) -> + sChkEqual (v %== v') l' r' k v v' + `sThenEqv` sEquivalent l' l + `sThenEqv` sEquivalent r' r +sEquivAux SFalse n m _ _ _ _ _ _ = + SSizeMismatch n m + +sChkEqual :: + SBool b -> + SOrdMap l -> + SOrdMap r -> + Sing k -> + Sing v -> + Sing v' -> + SEquivalence (ChkEqual b l r k v v') +sChkEqual STrue _ _ _ _ _ = SIsEquivalent +sChkEqual SFalse l r k v v' = SValueMismatch k v v' (SMkTriple l v' r) + +type family ChkEqual p l r k v v' where + ChkEqual 'True _ _ _ _ _ = 'IsEquivalent + ChkEqual 'False l r k v v' = 'ValueMismatch k v v' '(l, v', r) + +type LookupWithIndex' k dic = + FromJust + ( 'Text "Key `" + ':<>: 'ShowType k + ':<>: 'Text " doesn't exist in " + ':<>: 'ShowType (ToList dic) + ) + (LookupWithIndex k dic) + +type Lookup :: forall k v. k -> OrdMap k v -> Maybe v +type Lookup (k :: key) (dic :: OrdMap key val) = + Fst1 <$> LookupWithIndex k dic + +type IndexM (k :: key) (dic :: OrdMap key val) = + Snd1 <$> LookupWithIndex k dic + +type Index k dic = Snd (LookupWithIndex' k dic) + +type LookupWithIndex :: forall k v. k -> OrdMap k v -> Maybe (v, Nat) +type family LookupWithIndex (k :: key) (dic :: OrdMap key val) where + LookupWithIndex k Leaf = 'Nothing + -- GHC の型レベル言語は正格なので、CaseOrdering を用いると、 + -- 不要な節まで計算され効率が落ちる可能性がある。 + -- そのため LookupCase を定義し、展開が行われないようにしている + LookupWithIndex k (Branch _ _ _ l k' v r) = + LookupCase + 0 + k + (Compare k k') + l + v + r + +class (KnownNat (Index k dic)) => Member (k :: key) (dic :: OrdMap key val) + +instance (KnownNat (Index k dic)) => Member k dic + +instance + (ShowSing k, ShowSing v) => + Show (SOrdMap (dic :: OrdMap k v)) + where + showsPrec d smap = + showParen (d > 10) $ + showString "FromAscList " . shows (sToList smap) + +instance + ( SOrd key + , Known (k :: key) + , Known (dic :: OrdMap key val) + , ShowSing key + , ShowSing val + ) => + Deferrable (Member k dic) + where + deferEither _ f = + case sLookupWithIndex (sKnownVal' @k) (sKnownVal' @dic) of + SNothing -> + Left $ + "Type-level OrdMap" + ++ show (sKnownVal' @dic) + ++ "doesn't have a field " + ++ show (sKnownVal' @k) + SJust (SPair _ (snat :: SNat n)) -> + withKnown' snat $ toKnownNat @n $ Right f + +-- GHC の型レベル言語は正格なので、CaseOrdering を用いると、 +-- 不要な節まで計算され効率が落ちる可能性がある。 +-- そのため LookupCase を定義し、展開が行われないようにしている +type family LookupCase offset key ord dic val dic' where + LookupCase n _ 'EQ l val _ = 'Just '(val, n + Size l) + LookupCase _ k 'LT 'Leaf _ _ = 'Nothing + LookupCase n k 'LT ('Branch _ _ _ l k' v' r) _ _ = + LookupCase n k (Compare k k') l v' r + LookupCase n k 'GT _ _ 'Leaf = 'Nothing + LookupCase n k 'GT l _ ('Branch _ _ _ l' k' v' r') = + LookupCase (n + Size l + 1) k (Compare k k') l' v' r' + +-- | @'FieldAt' i@ returns the @i@-th minimum number, or result in type error. +type FieldAt i dic = + FromJust + ( 'Text "Index out of bounds: (#" + ':<>: 'ShowType i + ':<>: 'Text ", " + ':<>: 'ShowType (Size dic) + ':<>: 'Text ") " + ':<>: 'ShowType (ToList dic) + ':<>: 'Text "." + ) + (FieldAtM i dic) + +type EntryAt k dic = Entry (FieldAt k dic) + +type EntryAtM k dic = Entry' <$> FieldAtM k dic + +type LabelAt k dic = Label (FieldAt k dic) + +type LabelAtM k dic = Label' <$> FieldAtM k dic + +type family FieldAtM (i :: Nat) (dic :: OrdMap k v) :: Maybe (Field k v) where + FieldAtM i 'Leaf = 'Nothing + FieldAtM i ('Branch _ n _ l k v r) = + FieldAtAux i (Compare i n) (Compare i (Size l)) l k v r + +type family FieldAtAux i iCmpN iCmpL l k v r where + FieldAtAux i 'LT 'EQ _ k v _ = 'Just (k ::: v) + FieldAtAux i 'LT 'LT ('Branch _ n' _ l' k' v' r') _ _ _ = + FieldAtAux i (Compare i n') (Compare i (Size l')) l' k' v' r' + FieldAtAux i 'LT 'GT l _ _ r = + FieldAtM (i - Size l - 1) r + FieldAtAux _ _ _ _ _ _ _ = 'Nothing + +type ToList dic = ToListAux '[] dic + +sToList :: SOrdMap dic -> SList (ToList dic) +sToList = sToListAux SNil + +sToListAux :: SList acc -> SOrdMap dic -> SList (ToListAux acc dic) +sToListAux acc SLeaf = acc +sToListAux acc (SBranch _ _ _ l k v r) = + sToListAux ((k :%:: v) :% sToListAux acc r) l + +type family ToListAux acc (dic :: OrdMap key val) where + ToListAux acc 'Leaf = acc + ToListAux acc ('Branch _ _ _ l k v r) = + ToListAux ((k ::: v) ': ToListAux acc r) l + +type Insert k v dic = + Merge dic (Singleton k v) + +sInsert :: + (SOrd key) => + Sing (k :: key) -> + Sing v -> + SOrdMap dic -> + SOrdMap (Insert k v dic) +sInsert k v dic = sMerge dic (sSingleton k v) + +sSingleton :: Sing k -> Sing v -> SOrdMap (Singleton k v) +sSingleton k v = + SBranch sKnownVal' sKnownVal' sKnownVal' SLeaf k v SLeaf + +type family Merge (l :: OrdMap k v) (r :: OrdMap k v) :: OrdMap k v where + Merge 'Leaf dic = dic + Merge dic 'Leaf = dic + Merge ('Branch c n rk l' k' v' r') r = + MergeAux (Split k' r) l' k' v' r' + +sMerge :: + (SOrd k) => + SOrdMap (l :: OrdMap k v) -> + SOrdMap (r :: OrdMap k v) -> + SOrdMap (Merge l r) +sMerge SLeaf dic = dic +sMerge dic SLeaf = dic +sMerge (SBranch _ _ _ l' k' v' r') r@SBranch {} = + sMergeAux (sSplit k' r) l' k' v' r' + +sMergeAux :: + (SOrd key) => + STriple tpl -> + SOrdMap l -> + Sing (k :: key) -> + Sing v -> + SOrdMap r -> + Sing (MergeAux tpl l k v r) +sMergeAux (SMkTriple lt SNothing gt) l k v r = + sJoin (sMerge l lt) k v (sMerge r gt) +sMergeAux (SMkTriple lt (SJust (SPair k v)) gt) l _ _ r = + sJoin (sMerge l lt) k v (sMerge r gt) + +type family MergeAux tpl l k v r where + MergeAux '(lt, 'Nothing, gt) l k v r = + Join (Merge l lt) k v (Merge r gt) + MergeAux '(lt, 'Just '(k, v), gt) l _ _ r = + Join (Merge l lt) k v (Merge r gt) + +type family + Split (k :: key) (dic :: OrdMap key val) :: + (OrdMap key val, Maybe (key, val), OrdMap key val) + where + Split k 'Leaf = '( 'Leaf, 'Nothing, 'Leaf) + Split k ('Branch c n rk l k' v' r) = + SplitAux k (Compare k k') c n rk l k' v' r + +sSplit :: + (SOrd key) => + Sing (k :: key) -> + SOrdMap dic -> + STriple (Split k dic) +sSplit _ SLeaf = SMkTriple SLeaf SNothing SLeaf +sSplit k (SBranch c n rk l k' v' r) = + sSplitAux k (sCompare k k') c n rk l k' v' r + +type family SplitAux k cmp c n rk l k' v' r where + SplitAux k 'EQ c n rk l k' v' r = '(l, 'Just '(k', v'), r) + SplitAux k 'LT c n rk l k' v' r = + SplitAuxLT (Split k l) k' v' r + SplitAux k 'GT c n rk l k' v' r = + SplitAuxGT l k' v' (Split k r) + +sSplitAux :: + (SOrd key) => + Sing (k :: key) -> + SOrdering cmp -> + Sing c -> + SNat n -> + SRankT rk -> + SOrdMap l -> + Sing k' -> + Sing v' -> + SOrdMap r -> + STriple (SplitAux k cmp c n rk l k' v' r) +sSplitAux _ SEQ _ _ _ l k v r = SMkTriple l (SJust $ SPair k v) r +sSplitAux k SLT _ _ _ l k' v' r = sSplitAuxLT (sSplit k l) k' v' r +sSplitAux k SGT _ _ _ l k' v' r = sSplitAuxGT l k' v' (sSplit k r) + +type family SplitAuxLT trpl k v r where + SplitAuxLT '(l2, mv, r2) k v r = '(l2, mv, Join r2 k v r) + +sSplitAuxLT :: + STriple trpl -> + Sing k -> + Sing v -> + SOrdMap r -> + STriple (SplitAuxLT trpl k v r) +sSplitAuxLT (SMkTriple l2 mv r2) k v r = + SMkTriple l2 mv $ sJoin r2 k v r + +type family SplitAuxGT l k v trpl where + SplitAuxGT l k v '(l2, mv, r2) = '(Join l k v l2, mv, r2) + +sSplitAuxGT :: + SOrdMap l -> + Sing k -> + Sing v -> + STriple trpl -> + STriple (SplitAuxGT l k v trpl) +sSplitAuxGT l k v (SMkTriple l2 mv r2) = + SMkTriple (sJoin l k v l2) mv r2 + +sRotateL :: SOrdMap dic -> SOrdMap (RotateL dic) +sRotateL + ( SBranch + SB + h1 + rk1 + a + k1 + v1 + ( SBranch + SR + _ + _ + b + k2 + v2 + (SBranch SR h3 _ c k3 v3 d) + ) + ) = + SBranch + SR + h1 + rk1 + ( SBranch + SB + (sSize a %+ sSize b %+ sKnownVal') + rk1 + a + k1 + v1 + b + ) + k2 + v2 + ( SBranch + SB + h3 + rk1 + c + k3 + v3 + d + ) +sRotateL i = unsafeCoerce i + +type family RotateL dic where + RotateL + ( Branch + 'B + h1 + rk1 + a + k1 + v1 + ( Branch + 'R + h2 + rk2 + b + k2 + v2 + (Branch 'R h3 rk3 c k3 v3 d) + ) + ) = + Branch + 'R + h1 + rk1 + ( Branch + 'B + (Size a + Size b + 1) + rk1 + a + k1 + v1 + b + ) + k2 + v2 + ( Branch + 'B + h3 + rk1 + c + k3 + v3 + d + ) + RotateL dic = dic + +sRotateR :: SOrdMap dic -> SOrdMap (RotateR dic) +sRotateR + ( SBranch + SB + h1 + rk1 + ( SBranch + SR + _ + _ + (SBranch SR h3 _ a k1 v1 b) + k2 + v2 + c + ) + k3 + v3 + d + ) = + SBranch + SR + h1 + rk1 + ( SBranch + SB + h3 + rk1 + a + k1 + v1 + b + ) + k2 + v2 + ( SBranch + SB + (sSize c %+ sSize d %+ sKnownVal') + rk1 + c + k3 + v3 + d + ) +sRotateR dic = unsafeCoerce dic + +type family RotateR dic where + RotateR + ( Branch + 'B + h1 + rk1 + ( Branch + 'R + h2 + rk2 + (Branch 'R h3 rk3 a k1 v1 b) + k2 + v2 + c + ) + k3 + v3 + d + ) = + Branch + 'R + h1 + rk1 + ( Branch + 'B + h3 + rk1 + a + k1 + v1 + b + ) + k2 + v2 + ( Branch + 'B + (Size c + Size d + 1) + rk1 + c + k3 + v3 + d + ) + RotateR dic = dic + +sJoin :: + SOrdMap l -> + Sing k -> + Sing v -> + SOrdMap r -> + SOrdMap (Join l k v r) +sJoin l k v r = + sBlacken $ + sJoinAux + (sCompare (sRank l) (sRank r)) + l + k + v + r + +type family + Join (l :: OrdMap key val) (k :: key) (v :: val) (r :: OrdMap key val) :: + OrdMap key val + where + Join l k v r = + Blacken + ( JoinAux + (Compare (Rank l) (Rank r)) + l + k + v + r + ) + +sJoinAux :: + SOrdering a -> + SOrdMap l -> + Sing k -> + Sing v -> + SOrdMap r -> + SOrdMap (JoinAux a l k v r) +sJoinAux SGT l k v r = sJoinAuxLeft (sRank r) l k v r +sJoinAux SLT l k v r = sJoinAuxRight (sRank l) l k v r +sJoinAux SEQ l k v r = + SBranch + SR + (sSize l %+ sSize r %+ sKnownVal') + (sRank l) + l + k + v + r + +sRank :: SOrdMap dic -> SRankT (Rank dic) +sRank SLeaf = sKnownVal' +sRank (SBranch _ _ r _ _ _ _) = r + +type family JoinAux a l k v r where + JoinAux 'GT l k v r = + JoinAuxLeft (Rank r) l k v r + JoinAux 'LT l k v r = + JoinAuxRight (Rank l) l k v r + JoinAux EQ l k v r = + Branch 'R (Size l + Size r + 1) (Rank l) l k v r + +sJoinAuxLeft :: + SRankT targRk -> + SOrdMap l -> + Sing k -> + Sing v -> + SOrdMap r -> + SOrdMap (JoinAuxLeft targRk l k v r) +sJoinAuxLeft + targRk + (SBranch SB n rk' l' k' v' r') + k + v + r = + case sTestEquality targRk rk' of + Equal -> + SBranch + SR + (sSize r %+ n %+ sKnownVal') + targRk + (SBranch SB n targRk l' k' v' r') + k + v + r + NonEqual -> + unsafeCoerce $ -- trust me + sRotateL + ( SBranch + SB + (n %+ sSize r %+ sKnownVal' @1) + rk' + l' + k' + v' + (sJoinAuxLeft targRk r' k v r) + ) +sJoinAuxLeft + targRk + (SBranch SR n rk' l' k' v' r') + k + v + r = + SBranch + SR + (n %+ sSize r %+ sKnownVal') + rk' + l' + k' + v' + (sJoinAuxLeft targRk r' k v r) +sJoinAuxLeft (SMkRankT rk) SLeaf k v r = + case sTestEquality rk $ sKnownVal' @1 of + Equal -> + SBranch + SR + (sSize r %+ sKnownVal') + (SMkRankT sKnownVal') + SLeaf + k + v + r + NonEqual -> error "sJoinAuxLeft: Impossible clause!" + +type family JoinAuxLeft targRk l k v r where + JoinAuxLeft + targRk + (Branch 'B n targRk l' k' v' r') + k + v + r = + Branch + 'R + (Size r + n + 1) + targRk + (Branch 'B n targRk l' k' v' r') + k + v + r + JoinAuxLeft + targRk + (Branch 'B n rk' l' k' v' r') + k + v + r = + RotateL + ( Branch + 'B + (n + Size r + 1) + rk' + l' + k' + v' + (JoinAuxLeft targRk r' k v r) + ) + JoinAuxLeft + targRk + (Branch 'R n rk' l' k' v' r') + k + v + r = + ( Branch + 'R + (n + Size r + 1) + rk' + l' + k' + v' + (JoinAuxLeft targRk r' k v r) + ) + JoinAuxLeft (MkRankT 1) 'Leaf k v r = + Branch + 'R + (Size r + 1) + (MkRankT 1) + 'Leaf + k + v + r + +type family JoinAuxRight targRk l k v r where + JoinAuxRight + targRk + l + k + v + (Branch 'B n targRk l' k' v' r') = + Branch + 'R + (Size l + n + 1) + targRk + l + k + v + (Branch 'B n targRk l' k' v' r') + JoinAuxRight + targRk + l + k + v + (Branch 'B n rk' l' k' v' r') = + RotateR + ( Branch + 'B + (n + Size l + 1) + rk' + (JoinAuxRight targRk l k v l') + k' + v' + r' + ) + JoinAuxRight + targRk + l + k + v + (Branch 'R n rk' l' k' v' r') = + ( Branch + 'R + (n + Size l + 1) + rk' + (JoinAuxRight targRk l k v l') + k' + v' + r' + ) + JoinAuxRight (MkRankT 1) l k v 'Leaf = + Branch + 'R + (Size l + 1) + (MkRankT 1) + l + k + v + 'Leaf + +sJoinAuxRight :: + SRankT targRk -> + SOrdMap l -> + Sing (k :: key) -> + Sing v -> + SOrdMap r -> + SOrdMap (JoinAuxRight targRk l k v r) +sJoinAuxRight targRk l k v (SBranch SB n rk' l' k' v' r') = + case sTestEquality targRk rk' of + Equal -> + SBranch + SR + (sSize l %+ n %+ sKnownVal') + targRk + l + k + v + (SBranch SB n targRk l' k' v' r') + NonEqual -> + unsafeCoerce $ + sRotateR $ + SBranch + SB + (n %+ sSize l %+ sKnownVal' @1) + rk' + (sJoinAuxRight targRk l k v l') + k' + v' + r' +sJoinAuxRight targRk l k v (SBranch SR n rk' l' k' v' r') = + SBranch + SR + (n %+ sSize l %+ sKnownVal') + rk' + (sJoinAuxRight targRk l k v l') + k' + v' + r' +sJoinAuxRight (SMkRankT sn) l k v SLeaf = + case sTestEquality sn (sKnownVal' @1) of + Equal -> + SBranch + SR + (sSize l %+ sKnownVal') + sKnownVal' + l + k + v + SLeaf + NonEqual -> error "sJoinAuxRight: IMPOSSIBLE!" + +type family Intersect l r where + Intersect 'Leaf _ = 'Leaf + Intersect _ 'Leaf = 'Leaf + Intersect (Branch _ _ _ l k v r) r' = + IntersectAux (Split k r') l r + +type family IntersectAux trpl l r where + IntersectAux '(lt, 'Just '(k, v), gt) l r = + Join (Intersect l lt) k v (Intersect r gt) + IntersectAux '(lt, 'Nothing, gt) l r = + Merge (Intersect l lt) (Intersect r gt) + +type Delete k dic = DeleteAux (Split k dic) dic + +type family DeleteAux tpl dic where + DeleteAux '(_, 'Nothing, _) dic = dic + DeleteAux '(l, _, r) _ = Merge l r + +type family Blacken dic where + Blacken ('Branch 'R n rk l k v r) = 'Branch 'B n (SuccRank rk) l k v r + Blacken t = t + +sSuccRank :: SRankT r -> SRankT (SuccRank r) +sSuccRank (SMkRankT r) = SMkRankT (r %+ sKnownVal') + +sBlacken :: SOrdMap dic -> SOrdMap (Blacken dic) +sBlacken (SBranch SR n rk l k v r) = + SBranch SB n (sSuccRank rk) l k v r +sBlacken (SBranch SB n rk l k v r) = + SBranch SB n rk l k v r +sBlacken SLeaf = SLeaf + +type family SuccRank rk where + SuccRank ('MkRankT rk) = MkRankT (rk + 1) + +sFromList :: (SOrd key) => SList (dic :: [Field key val]) -> SOrdMap (FromList dic) +sFromList SNil = sEmpty +sFromList ((k :%:: v) :% SNil) = sSingleton k v +sFromList ((k :%:: v) :% kvs@(:%) {}) = + sInsert k v $ sFromList kvs + +type family FromList xs where + FromList '[] = 'Leaf + FromList '[k ::: v] = Singleton k v + FromList ((k ::: v) ': kvs) = + Insert k v (FromList kvs) + +type family MapApplyWithKey (f :: k ~> v ~> v') dic where + MapApplyWithKey _ Leaf = Leaf + MapApplyWithKey f (Branch c n rk l k v r) = + Branch + c + n + rk + (MapApplyWithKey f l) + k + (Apply (Apply f k) v) + (MapApplyWithKey f r) + +type family MapWithKey (f :: k -> v -> v') dic where + MapWithKey _ Leaf = Leaf + MapWithKey f (Branch c n rk l k v r) = + Branch + c + n + rk + (MapWithKey f l) + k + (f k v) + (MapWithKey f r) + +type family MapWithIndex (f :: Nat -> v -> v') dic where + MapWithIndex _ Leaf = Leaf + MapWithIndex f (Branch c n rk l k v r) = + Branch c n rk (MapWithIndex f l) k (f (Size l) v) (MapWithIndex f r) + +type family MapApplyWithIndex (f :: Nat ~> v ~> v') dic where + MapApplyWithIndex _ Leaf = Leaf + MapApplyWithIndex f (Branch c n rk l k v r) = + Branch + c + n + rk + (MapApplyWithIndex f l) + k + (Apply (Apply f (Size l)) v) + (MapApplyWithIndex f r) + +type family + MapKeysMonotonic + (f :: k -> k') + (dic :: OrdMap k v) :: + OrdMap k' v + where + MapKeysMonotonic _ Leaf = Leaf + MapKeysMonotonic f (Branch c n rk l k v r) = + Branch c n rk (MapKeysMonotonic f l) (f k) v (MapKeysMonotonic f r) + +type family + MapApplyKeysMonotonic + (f :: k ~> k') + (dic :: OrdMap k v) :: + OrdMap k' v + where + MapApplyKeysMonotonic _ Leaf = Leaf + MapApplyKeysMonotonic f (Branch c n rk l k v r) = + Branch + c + n + rk + (MapApplyKeysMonotonic f l) + (Apply f k) + v + (MapApplyKeysMonotonic f r) + +sSwapField :: + SList xs -> SList (MapApply (Uncurry (:::) .: Swap1) xs) +sSwapField SNil = SNil +sSwapField (SPair x y :% xs) = + (y :%:: x) :% sSwapField xs + +sSortPermutation :: + (SOrd key) => + SList (dic :: [Field key val]) -> + SList (SortPermutation dic) +sSortPermutation = + sEntries . sFromList . sSwapField . sIndexed . sLabels' + +type SortPermutation (xs :: [Field k v]) = + Entries + ( FromList + ( MapApply + (Uncurry (:::) .: Swap1) + (Indexed (MapApply Label' xs)) + ) + ) + +type SortableLabels xs = + Known (SortPermutation xs) + +type SortableList xs = + Known (SortPermutation (ConstFields '() xs)) + +sortPermutation :: + forall ps. + (SortableLabels ps) => + U.Vector Int +sortPermutation = + U.fromList $ + map fromIntegral $ + knownVal' @(SortPermutation ps) + +unsortMembership :: + forall l v ps r. + ( SortableLabels ps + , LookupWithIndex l (FromList ps) + ~ 'Just '(v, Index l (FromList ps)) + , Member l (FromList ps) + ) => + ( (List.Member (l ::: v) ps) => + r + ) -> + r +unsortMembership f = + let pos = fromIntegral $ natVal @(Index l (FromList ps)) Proxy + in unsafeWithKnownMember + @(l ::: v) + @ps + (fromIntegral $ perm U.! pos) + f + where + perm = sortPermutation @ps + +withUnsortedMember :: + forall ps r. + (SortableLabels ps) => + (forall l. (Member l (FromList ps)) => Proxy l -> r) -> + ( forall fld. + (List.Member fld ps) => + Proxy fld -> + r + ) +withUnsortedMember f = \(_ :: Proxy l) -> + let pos = fromIntegral $ position @l @ps + in unsafeWithOrdMapMember + @(Label l) + @(FromList ps) + (fromIntegral $ fromJust $ U.elemIndex pos perm) + $ f (Proxy @(Label l)) + where + perm = sortPermutation @ps + +withUnsortedMember' :: + forall l ps r. + (SortableLabels ps, List.Member l ps) => + ((Member (Label l) (FromList ps)) => r) -> + r +withUnsortedMember' = + let pos = fromIntegral $ natVal @(List.Index l ps) Proxy + in unsafeWithOrdMapMember + @(Label l) + @(FromList ps) + (fromIntegral $ fromJust $ U.elemIndex pos perm) + where + perm = sortPermutation @ps + +withLabelIndex :: + forall ps f. + (forall l. (List.Member l (Labels (FromList ps))) => Proxy l -> f l) -> + ( forall l. + (Member l (FromList ps)) => + Proxy l -> + f l + ) +withLabelIndex f = \(_ :: Proxy l) -> + let pos = fromIntegral $ List.natVal @(Index l (FromList ps)) Proxy + in unsafeWithKnownMember + @l + @(Labels (FromList ps)) + pos + $ f (Proxy @l) + +data ReadTree = Nought | Single | Br ReadTree ReadTree + deriving (Typeable, Generic) + +type family BuildReadTree n :: ReadTree where + BuildReadTree 0 = 'Nought + BuildReadTree 1 = 'Single + BuildReadTree n = BuildReadTreeAux n ((n - 1) `Div` 2) + +type family BuildReadTreeAux n q where + BuildReadTreeAux n q = + 'Br (BuildReadTree (n - 1 - q)) (BuildReadTree q) + +type family + ReadMap d m (tr :: ReadTree) (xs :: [Field k v]) :: + (OrdMap k v, [Field k v]) + where + ReadMap _ _ 'Nought xs = '( 'Leaf, xs) + ReadMap d d 'Single ((k ::: v) ': xs) = + '( 'Branch 'R 1 (MkRankT 1) 'Leaf k v 'Leaf, xs) + ReadMap _ _ 'Single ((k ::: v) ': xs) = + '( 'Branch 'B 1 (MkRankT 2) 'Leaf k v 'Leaf, xs) + ReadMap d k ('Br l r) xs = BrAuxL d k (ReadMap d (k + 1) l xs) r + +type family BrAuxL d k tpl r where + BrAuxL d m '(l, (k ::: v) ': xs) r = + BrAuxR d m l k v (ReadMap d (m + 1) r xs) + +type family BrAuxR d m l k v tpl where + BrAuxR d d l k v '(r, xs) = + '( 'Branch 'R (Size l + Size r + 1) (Rank l) l k v r, xs) + BrAuxR d m l k v '(r, xs) = + '( 'Branch 'B (Size l + Size r + 1) (SuccRank (Rank l)) l k v r, xs) + +{- | 長さやソート済か検査せずにソート済と仮定して木を作る + + /c.f./ 'FromList', 'UnsafeFromAscList', 'FromAscList'. +-} +type UnsafeFromAscListOfSize n xs = + Fst (ReadMap (Log2 (n + 1)) 0 (BuildReadTree n) xs) + +{- | ソート済でラベルの重複を持たないリストから 'OrdMap' を作る。 + 重複を持たないか・ソート済みかは検査しない。 + インタフェースが頻繁に変わりうる場合は 'FromAscList' を使うとよい。 + + /c.f./ 'FromList', 'UnsafeFromAscListOFSize', 'FromAscList'. +-} +type UnsafeFromAscList xs = UnsafeFromAscListOfSize (Length xs) xs + +{- | ソート済のリストから 'OrdMap' を作る。ソート済でない場合はエラーとする。 + ソート済だと確信が持て、そのラベルの集合の並び順を書き換える頻度が少ないと思われる場合、 + 'UnsafeFromAscList' を使うと定数倍コンパイルが速くなる。 + + /c.f./ 'FromList', 'UnsafeFromAscList', 'FromAscList'. +-} +type FromAscList xs = FromAscListAux (LabelSorted xs) xs + +type family FromAscListAux sorted xs where + FromAscListAux 'IsSorted xs = UnsafeFromAscList xs + FromAscListAux ('UnsortedOn orig n l r) _ = + TypeError + ( 'Text "Unsorted fields given to FromAscList: the " + ':<>: 'ShowType n + ':<>: 'Text "th field: " + ':$$: 'Text "\t" + ':<>: 'ShowType l + ':$$: 'Text "is strictly larger than successing field: " + ':$$: 'Text "\t" + ':<>: 'ShowType r + ':$$: 'Text "in a given list of fields:" + ':$$: 'Text "\t" + ':<>: 'ShowType orig + ) + FromAscListAux ('DuplicatedLabel orig n l v v') _ = + TypeError + ( 'Text "A field `" + ':<>: 'ShowType l + ':<>: 'Text "' is duplicated in the given list at index " + ':<>: 'ShowType n + ':<>: 'Text "." + ':$$: 'Text "Associated with:" + ':$$: 'ShowType n + ':<>: 'Text ":\t" + ':<>: 'ShowType v + ':$$: 'ShowType (n + 1) + ':<>: 'Text ":\t" + ':<>: 'ShowType v' + ':$$: 'Text "In the given list of fields:" + ':$$: 'Text "\t" + ':<>: 'ShowType orig + ) + +type instance List.PElement (OrdMap k v) = Field k v + +instance List.PIsList (OrdMap k v) where + type FromList xs = FromList xs + type Cons kvs xs = Insert (Label kvs) (Entry kvs) xs + type Empty = Empty + +memberToList :: + forall fld recs. + Index (Label fld) recs + :~: List.Index fld (ToList recs) +memberToList = unsafeCoerce $ Refl @() + +indexFieldAt :: + ((k + 1) <= Size recs) => + Index (LabelAt k recs) recs :~: k +indexFieldAt = unsafeCoerce $ Refl @() + +withOrdMapMember :: + forall l recs r. + (Member l recs) => + ((List.Member (l ::: Lookup' l recs) (ToList recs)) => r) -> + r +withOrdMapMember = + unsafeWithKnownMember + @(l ::: Lookup' l recs) + @(ToList recs) + (List.natVal $ Proxy @(Index l recs)) + +elimMemberToList :: + (List.Member l (ToList recs)) => + Lookup' (Label l) recs :~: Entry l +elimMemberToList = unsafeCoerce $ Refl @() + +withToListMember :: + forall l recs p. + (List.Member l (ToList recs)) => + ( ( LookupWithIndex (Label l) recs + ~ 'Just '(Entry l, List.Index l (ToList recs)) + ) => + p + ) -> + p +withToListMember act = + gcastWith + ( unsafeCoerce $ Refl @() :: + LookupWithIndex (Label l) recs + :~: 'Just '(Entry l, List.Index l (ToList recs)) + ) + act + +fieldAtToList :: + forall k recs. + FieldAt k recs + :~: List.ElemAt k (ToList recs) +fieldAtToList = unsafeCoerce $ Refl @() + +elemAtFieldDistrib :: + ElemAt k (ToList dic) :~: (LabelAt k dic ::: EntryAt k dic) +elemAtFieldDistrib = unsafeCoerce $ Refl @() + +data Succ :: Nat ~> Nat + +type instance Apply Succ n = n + 1 + +type BlackCounts dic = + MapApply + (Length1 .: Matches1 B .: MapApply1 Fst1) + (Paths dic) + +type BlackCountInvariant dic = ChkAllEq (BlackCounts dic) + +type family RedRedInvariant dic :: Constraint where + RedRedInvariant 'Leaf = () + RedRedInvariant ('Branch 'R _ _ (Branch 'R _ _ _ _ _ _) _ _ _) = + TypeError ('Text "No Red-Red invariant failed") + RedRedInvariant ('Branch 'R _ _ _ _ _ (Branch 'R _ _ _ _ _ _)) = + TypeError ('Text "No Red-Red invariant failed") + RedRedInvariant ('Branch _ _ _ l _ _ r) = + (RedRedInvariant l, RedRedInvariant r) + +type ValidRBTree dic = + (RedRedInvariant dic, BlackCountInvariant dic, RootIsBlack dic, LabelSorted (ToList dic) ~ 'IsSorted) + +type Paths dic = PathsAux dic + +type family PathsAux (dic :: OrdMap k v) :: [[(Color, Maybe (k, v))]] where + PathsAux 'Leaf = '[ '[ '( 'B, Nothing)]] + PathsAux ('Branch c _ _ l k v r) = + MapApply (Cons1 '(c, 'Just '(k, v))) (Paths l ++ Paths r) + +data Cons1 (x :: k) :: [k] ~> [k] + +type instance Apply (Cons1 x) xs = x ': xs + +type family RootIsBlack a :: Constraint where + RootIsBlack 'Leaf = () + RootIsBlack (Branch 'B _ _ _ _ _ _) = () + RootIsBlack (Branch 'R _ _ _ _ _ _) = + TypeError ('Text "Root is not black!") + +type family ChkAllEq a :: Constraint where + ChkAllEq '[] = () + ChkAllEq '[x] = () + ChkAllEq (x ': x ': xs) = ChkAllEq (x ': xs) + ChkAllEq (x ': y ': xs) = + TypeError + ('Text "Nonequal elements: " ':<>: 'ShowType '(x, y)) + +type ConstField e l = l ::: e + +data ConstField1 (e :: v) :: k ~> Field k v + +type instance Apply (ConstField1 v) k = ConstField v k + +type ConstFields v fs = MapApply (ConstField1 v) fs + +data ConstFields1 (e :: v) :: [k] ~> [Field k v] + +type instance Apply (ConstFields1 v) ks = ConstFields v ks + +unsafeWithOrdMapMember :: + forall l xs r. + Word -> + ((Member l xs) => r) -> + r +unsafeWithOrdMapMember pos act = + let nat = fromIntegral pos :: Natural + in unsafeCoerce (WithOMMem @l @xs @r act) nat + +newtype WithOMMem l xs r + = WithOMMem ((Member l xs) => r) + +elimConstField :: + forall l a xs. + (Member l (FromList (ConstFields a xs))) => + Lookup' l (FromList (ConstFields a xs)) :~: a +elimConstField = unsafeCoerce $ Refl @() + +withLabelsMember :: + forall l qs r. + (Member l qs) => + ((List.Member l (Labels qs)) => r) -> + r +withLabelsMember = + unsafeWithKnownMember + @l + @(Labels qs) + (List.natVal $ Proxy @(Index l qs)) + +data Sortedness l v + = IsSorted + | UnsortedOn [Field l v] Nat (Field l v) (Field l v) + | DuplicatedLabel [Field l v] Nat l v v + +type LabelSorted dic = LabelSorted' 0 dic dic + +type family + LabelSorted' + n + (orig :: [Field l v]) + (flds :: [Field l v]) :: + Sortedness l v + where + LabelSorted' _ _ '[] = 'IsSorted + LabelSorted' _ _ '[x] = 'IsSorted + LabelSorted' n orig ((a ::: av) ': (b ::: bv) ': as) = + CaseOrdering + (Compare a b) + (LabelSorted' (n + 1) orig ((b ::: bv) ': as)) + ('DuplicatedLabel orig n a av bv) + ('UnsortedOn orig n (a ::: av) (b ::: bv)) + +sLookupWithIndex :: + (SOrd k) => Sing (lab :: k) -> SOrdMap dic -> SMaybe (LookupWithIndex lab dic) +sLookupWithIndex _ SLeaf = SNothing +sLookupWithIndex k (SBranch _ _ _ l k' v r) = + sLookupCase (sKnownVal' :: SNat 0) k (sCompare k k') l v r + +-- | A variant of 'sLookupWithIndex' with all the kinds explicitly qunatified. +sLookupWithIndex' :: + forall k v (lab :: k) (dic :: OrdMap k v). + (SOrd k) => + Sing (lab :: k) -> + Sing dic -> + Sing (LookupWithIndex lab dic) +sLookupWithIndex' = sLookupWithIndex + +sSize :: SOrdMap dic -> SNat (Size dic) +sSize SLeaf = sKnownVal' @0 +sSize (SBranch _ n _ _ _ _ _) = n + +sLookupCase :: + (SOrd k) => + SNat offset -> + Sing (key :: k) -> + SOrdering ord -> + SOrdMap dic -> + Sing val -> + SOrdMap dic' -> + Sing (LookupCase offset key ord dic val dic') +sLookupCase n _ SEQ l val _ = + SJust $ + val `SPair` (n %+ sSize l) +sLookupCase _ _ SLT SLeaf _ _ = SNothing +sLookupCase n k SLT (SBranch _ _ _ l k' v' r) _ _ = + sLookupCase n k (sCompare k k') l v' r +sLookupCase _ _ SGT _ _ SLeaf = SNothing +sLookupCase n k SGT l _ (SBranch _ _ _ l' k' v' r') = + sLookupCase + (n %+ sSize l %+ sKnownVal' @1) + k + (sCompare k k') + l' + v' + r' + +sLabel :: SField f -> Sing (Label f) +sLabel (l :%:: _) = l + +sEntry :: SField f -> Sing (Entry f) +sEntry (_ :%:: v) = v + +sLabels :: + SOrdMap dic -> SList (Labels dic) +sLabels = sLabels' . sToList + +sLabels' :: SList fs -> SList (MapApply Label' fs) +sLabels' = go + where + go :: SList (flds :: [Field l k]) -> SList (MapApply Label' flds) + go SNil = SNil + go (x :% xs) = sLabel x :% go xs + +sEntries :: + SOrdMap dic -> SList (Entries dic) +sEntries = go . sToList + where + go :: SList (flds :: [Field l k]) -> SList (MapApply Entry' flds) + go SNil = SNil + go (x :% xs) = sEntry x :% go xs + +type ConstList fs = ConstFields '() fs + +type ConstMap fs = FromList (ConstList fs) + +toConstListMembership :: + forall l ps. + (List.Member l ps) => + Membership (l ::: '()) (ConstList ps) +toConstListMembership = + unsafeCoerce $ membership @l @ps + +fromConstListMembership :: + forall l ps. + (List.Member (l ::: '()) (ConstList ps)) => + Membership l ps +fromConstListMembership = + unsafeCoerce $ membership @(l ::: '()) @(ConstList ps) + +sConstList :: + SList xs -> SList (ConstFields '() xs) +sConstList SNil = SNil +sConstList (x :% xs) = (x :%:: sKnownVal') :% sConstList xs + +sConstMap :: (SOrd k) => SList (xs :: [k]) -> SOrdMap (ConstMap xs) +sConstMap = sFromList . sConstList + +data Disjointness k = IsDisjoint | OverlappingKey k + +deriveAllKnown True ''Disjointness + +_ovl :: (KnownDisjointness d) => pxy d -> SDisjointness d +_ovl = sDisjointnessVal + +_f :: (HasSing k, Known d) => pxy (d :: Disjointness k) -> Disjointness (Demote k) +_f = disjointnessVal + +_fg :: (HasSing k) => Disjointness (Demote k) -> SomeSing (Disjointness k) +_fg = toSomeDisjointness + +type family Disjoint' (ls :: OrdMap k v) (rs :: OrdMap k v) :: Disjointness k where + Disjoint' 'Leaf _ = IsDisjoint + Disjoint' _ 'Leaf = IsDisjoint + Disjoint' l' (Branch _ _ _ l k _ r) = + DisjointAux (Split k l') l k r + +type family DisjointAux trpl l k r where + DisjointAux '(l', 'Nothing, r') l k r = + Disjoint' l' l `ChoiceDisj` Disjoint' r' r + DisjointAux '(l', 'Just _, _) _ k _ = OverlappingKey k + +type Disjoint ls rs = Disjoint' ls rs ~ IsDisjoint + +type family ChoiceDisj f g where + ChoiceDisj IsDisjoint r = r + ChoiceDisj (OverlappingKey k) _ = OverlappingKey k + +sDisjoint :: + (SOrd k) => + SOrdMap (l :: OrdMap k v) -> + SOrdMap r -> + SDisjointness (Disjoint' l r) +sDisjoint SLeaf _ = SIsDisjoint +sDisjoint _ SLeaf = SIsDisjoint +sDisjoint l'@SBranch {} (SBranch _ _ _ l k _ r) = + case sSplit k l' of + SMkTriple l'' SNothing r'' -> + sDisjoint l'' l `sChoiceDisj` sDisjoint r'' r + SMkTriple _ SJust {} _ -> + SOverlappingKey k + +sChoiceDisj :: SDisjointness s -> SDisjointness r -> SDisjointness (ChoiceDisj s r) +sChoiceDisj SIsDisjoint r = r +sChoiceDisj s@SOverlappingKey {} _ = s + +type family EnumFromLess f n m acc where + EnumFromLess f n n acc = acc + EnumFromLess f n m acc = f n ': EnumFromLess f (n + 1) m acc + +sEnumFromLess :: + forall lr n m xs. + (forall a. Sing a -> SEither (lr a)) -> + SNat n -> + SNat m -> + SList xs -> + SList (EnumFromLess lr n m xs) +sEnumFromLess eithCons n m xs = go n + where + go :: SNat k -> SList (EnumFromLess lr k m xs) + go k = + case sTestEquality k m of + Equal -> xs + NonEqual -> unsafeCoerce $ eithCons k :% go (k %+ sKnownVal' @1) + +sMergePerm :: + (SOrd k) => + SOrdMap (l :: OrdMap k v) -> + SOrdMap (r :: OrdMap k v) -> + SList (MergePerm l r) +sMergePerm = sMergePerm' (sKnownVal' @0) (sKnownVal' @0) SNil + +type MergePerm l r = MergePerm' 0 0 '[] l r + +type family + MergePerm' + (n :: Nat) + (m :: Nat) + (cont :: [Either Nat Nat]) + (l :: OrdMap k v) + (r :: OrdMap k v) :: + [Either Nat Nat] + where + MergePerm' _ _ acc 'Leaf 'Leaf = acc + MergePerm' _ m acc 'Leaf r = EnumFromLess Right m (m + Size r) acc + MergePerm' n _ acc l 'Leaf = EnumFromLess Left n (n + Size l) acc + MergePerm' n m acc (Branch _ _ _ l k _ r) r' = + MergePermAux n m acc (Split k r') l k r + +sMergePerm' :: + (SOrd key) => + SNat n -> + SNat m -> + SList count -> + SOrdMap (l :: OrdMap key val) -> + SOrdMap r -> + SList (MergePerm' n m count l r) +sMergePerm' _ _ acc SLeaf SLeaf = acc +sMergePerm' _ m acc SLeaf r@SBranch {} = + sEnumFromLess SRight m (m %+ sSize r) acc +sMergePerm' n _ acc l@SBranch {} SLeaf = + sEnumFromLess SLeft n (n %+ sSize l) acc +sMergePerm' n m acc (SBranch _ _ _ l k _ r) r'@SBranch {} = + sMergePermAux n m acc (sSplit k r') l k r + +sMergePermAux :: + (SOrd key) => + SNat n -> + SNat m -> + SList acc -> + STriple view -> + SOrdMap (l :: OrdMap key val) -> + Sing k -> + SOrdMap (r :: OrdMap key val) -> + SList (MergePermAux n m acc view l k r) +sMergePermAux n m acc (SMkTriple l' SNothing r') l _ r = + sMergePerm' + n + m + ( SLeft (n %+ sSize l) + :% sMergePerm' + ((n %+ sKnownVal' @1) %+ sSize l) + (m %+ sSize l') + acc + r + r' + ) + l + l' +sMergePermAux n m acc (SMkTriple l' SJust {} r') l _ r = + sMergePerm' + n + m + ( SRight (m %+ sSize l') + :% sMergePerm' + (n %+ sKnownVal' @1 %+ sSize l) + (m %+ sKnownVal' @1 %+ sSize l') + acc + r + r' + ) + l + l' + +type family MergePermAux n m acc view l k r where + MergePermAux n m acc '(l', 'Nothing, r') l k r = + MergePerm' + n + m + ('Left (n + Size l) ': MergePerm' ((n + 1) + Size l) (m + Size l') acc r r') + l + l' + MergePermAux n m acc '(l', 'Just _, r') l k r = + MergePerm' + n + m + ('Right (m + Size l') ': MergePerm' (n + 1 + Size l) (m + 1 + Size l') acc r r') + l + l' + +type family + AllOM' (c :: k -> v -> Constraint) (dic :: OrdMap k v) :: + Constraint + where + AllOM' c 'Leaf = () + AllOM' c ('Branch _ _ _ l k v r) = + (AllOM c l, c k v, AllOM c r) + +data SomeOMMember dic where + MkSomeOMMember :: OMMembership k dic -> SomeOMMember dic + +class + (KnownNat (Size dic), Known dic, AllOM' c dic) => + AllOM c dic + where + allOMDict :: + OMMembership k dic -> + Dict (c k (Lookup' k dic)) + +instance AllOM c Leaf where + allOMDict = error "allOMDict: Membership for empty OrdMap!" + +instance + ( AllOM c l + , KnownNat (Size l) + , KnownNat n + , AllOM c r + , c k v + , Known l + , Known r + , Known k + , Known rk + , Known v + , Known col + ) => + (AllOM c (Branch col n rk l k v r)) + where + allOMDict (OMMembership i :: OMMembership k' _) = + let lSize = natVal @(Size l) Proxy + in case compare i lSize of + LT -> unsafeCoerce $ allOMDict @c @l (OMMembership i :: OMMembership k' l) + EQ -> unsafeCoerce (Dict @(c k v)) + GT -> + unsafeCoerce $ + allOMDict @c @r + (OMMembership (i - lSize - 1) :: OMMembership k' r) + +class (Deferrable (c x y)) => DeferrableFor2 c x y + +instance (Deferrable (c x y)) => DeferrableFor2 c x y + +instance + (Known dic, AllOM (DeferrableFor2 c) dic) => + Deferrable (AllOM c dic) + where + deferEither _ = \f -> + go (sKnownVal' @dic) + <&> \Dict -> f + where + go :: + (AllOM (DeferrableFor2 c) ys) => + SOrdMap ys -> + Either String (Dict (AllOM c ys)) + go SLeaf = Right Dict + go (SBranch c s rk l (k :: Sing k) (v :: Sing v) r) = + withKnown' c $ + withKnownNat' s $ + withKnown' rk $ + withKnown' k $ + withKnown' v $ + do + Dict <- deferEither_ @(c k v) @(Dict (c k v)) $ Dict @(c k v) + Dict <- go l + Dict <- go r + pure Dict + +foldMapOrdMapC :: + forall c dic w. + (Monoid w, AllOM c dic) => + ( forall k v n. + ( Known k + , Known v + , LookupWithIndex k dic ~ 'Just '(v, n) + , KnownNat n + , c k v + ) => + Proxy k -> + Proxy v -> + Proxy n -> + w + ) -> + w +foldMapOrdMapC f = go 0 $ sKnownVal' @dic + where + go :: forall xs. (AllOM c xs) => Natural -> SOrdMap xs -> w + go _ SLeaf = mempty + go !off (SBranch _ _ _ l (k :: Sing k) (v :: Sing v) r) = + withKnown' k $ + withKnown' v $ + let lSize = demote (sSize l) + off + in case promote @Nat lSize of + MkSomeSing (sn :: SNat n) -> + withKnownNat' sn + $ gcastWith + ( unsafeCoerce (Refl @()) :: + LookupWithIndex k dic :~: 'Just '(v, n) + ) + $ go off l + <> f (Proxy @k) (Proxy @v) (Proxy @n) + <> go (lSize + 1) r + +foldMapOrdMap :: + forall dic w. + (Monoid w, Known dic) => + ( forall k v n. + ( Known k + , Known v + , LookupWithIndex k dic ~ 'Just '(v, n) + , KnownNat n + ) => + Proxy k -> + Proxy v -> + Proxy n -> + w + ) -> + w +{-# INLINE foldMapOrdMap #-} +foldMapOrdMap = foldMapOrdMapAux @_ @_ @dic + +foldMapOrdMapAux :: + forall key val (dic :: OrdMap key val) w. + (Monoid w, Known dic) => + ( forall k v n. + (Known k, Known v, LookupWithIndex k dic ~ 'Just '(v, n), KnownNat n) => + Proxy k -> + Proxy v -> + Proxy n -> + w + ) -> + w +foldMapOrdMapAux f = go 0 $ sKnownVal' @dic + where + go :: forall (xs :: OrdMap key val). Natural -> SOrdMap xs -> w + go _ SLeaf = mempty + go !off (SBranch _ _ _ (l :: SOrdMap l) (k :: Sing k) (v :: Sing v) r) = + let lSize = demote (sSize l) + off + in case promote @Nat lSize of + MkSomeSing (sn :: SNat n) -> + withKnown' k + $ withKnown' v + $ withKnownNat' sn + $ gcastWith + ( unsafeCoerce (Refl @()) :: + LookupWithIndex k dic :~: 'Just '(v, n) + ) + $ go off l + <> f (Proxy @k) (Proxy @v) (Proxy @n) + <> go (lSize + 1) r + +foldMapOrdMapC' :: + forall c dic w. + (Monoid w, AllOM c dic) => + ( forall k v n. + ( Known k + , Known v + , LookupWithIndex k dic ~ 'Just '(v, n) + , KnownNat n + , c k v + ) => + Proxy k -> + Proxy v -> + Proxy n -> + w + ) -> + w +foldMapOrdMapC' f = go 0 $ sKnownVal' @dic + where + go :: forall xs. (AllOM c xs) => Natural -> SOrdMap xs -> w + go _ SLeaf = mempty + go !off (SBranch _ _ _ l (k :: Sing k) (v :: Sing v) r) = + withKnown' k $ + withKnown' v $ + let lSize = demote (sSize l) + off + in case promote @Nat lSize of + MkSomeSing (sn :: SNat n) -> + withKnownNat' sn + $ gcastWith + ( unsafeCoerce (Refl @()) :: + LookupWithIndex k dic :~: 'Just '(v, n) + ) + $ let !ml = go off l + !mid = f (Proxy @k) (Proxy @v) (Proxy @n) + !mlmid = ml <> mid + !mr = go (lSize + 1) r + in mlmid <> mr + +foldMapOrdMap' :: + forall dic w. + (Monoid w, Known dic) => + ( forall k v n. + ( Known k + , Known v + , LookupWithIndex k dic ~ 'Just '(v, n) + , KnownNat n + ) => + Proxy k -> + Proxy v -> + Proxy n -> + w + ) -> + w +{-# INLINE foldMapOrdMap' #-} +foldMapOrdMap' = foldMapOrdMap'_ @_ @_ @dic + +foldMapOrdMap'_ :: + forall key val (dic :: OrdMap key val) w. + (Monoid w, Known dic) => + ( forall k v n. + ( Known k + , Known v + , LookupWithIndex k dic ~ 'Just '(v, n) + , KnownNat n + ) => + Proxy k -> + Proxy v -> + Proxy n -> + w + ) -> + w +foldMapOrdMap'_ f = go 0 $ sKnownVal' @dic + where + go :: forall (xs :: OrdMap key val). Natural -> SOrdMap xs -> w + go _ SLeaf = mempty + go !off (SBranch _ _ _ l (k :: Sing k) (v :: Sing v) r) = + withKnown' k $ + withKnown' v $ + let lSize = demote (sSize l) + off + in case promote @Nat lSize of + MkSomeSing (sn :: SNat n) -> + withKnownNat' sn + $ gcastWith + ( unsafeCoerce (Refl @()) :: + LookupWithIndex k dic :~: 'Just '(v, n) + ) + $ let !ml = go off l + !mid = f (Proxy @k) (Proxy @v) (Proxy @n) + !mlmid = ml <> mid + !mr = go (lSize + 1) r + in mlmid <> mr + +foldrMOrdMap :: + forall dic m b. + (Monad m, Known dic) => + ( forall k v n. + ( Known k + , Known v + , LookupWithIndex k dic ~ 'Just '(v, n) + , KnownNat n + ) => + Proxy k -> + Proxy v -> + Proxy n -> + b -> + m b + ) -> + b -> + m b +foldrMOrdMap = \f -> + appEndoM $ + foldMapOrdMap @dic (\pk pv pn -> EndoM $ f pk pv pn) + +foldrMOrdMapC :: + forall c dic m b. + (AllOM c dic, Monad m) => + ( forall k v n. + ( Known k + , Known v + , LookupWithIndex k dic ~ 'Just '(v, n) + , KnownNat n + , c k v + ) => + Proxy k -> + Proxy v -> + Proxy n -> + b -> + m b + ) -> + b -> + m b +foldrMOrdMapC = \f -> + appEndoM $ + foldMapOrdMapC @c @dic (\pk pv pn -> EndoM $ f pk pv pn) + +foldrOrdMap :: + forall dic b. + (Known dic) => + ( forall k v n. + ( Known k + , Known v + , LookupWithIndex k dic ~ 'Just '(v, n) + , KnownNat n + ) => + Proxy k -> + Proxy v -> + Proxy n -> + b -> + b + ) -> + b -> + b +foldrOrdMap = \f -> + appEndo $ + foldMapOrdMap @dic (\pk pv pn -> Endo $ f pk pv pn) + +foldrOrdMapC :: + forall c dic b. + (AllOM c dic) => + ( forall k v n. + ( Known k + , Known v + , LookupWithIndex k dic ~ 'Just '(v, n) + , KnownNat n + , c k v + ) => + Proxy k -> + Proxy v -> + Proxy n -> + b -> + b + ) -> + b -> + b +foldrOrdMapC = \f -> + appEndo $ + foldMapOrdMapC @c @dic (\pk pv pn -> Endo $ f pk pv pn) + +foldlMOrdMapC' :: + forall c dic m b. + (AllOM c dic, Monad m) => + ( forall k v n. + ( Known k + , Known v + , LookupWithIndex k dic ~ 'Just '(v, n) + , KnownNat n + , c k v + ) => + Proxy k -> + Proxy v -> + Proxy n -> + b -> + m b + ) -> + b -> + m b +foldlMOrdMapC' f = + foldrOrdMapC @c @dic + (\pk pv pn k z -> (k $!) =<< f pk pv pn z) + return + +foldlMOrdMap' :: + forall dic m b. + (Known dic, Monad m) => + ( forall k v n. + ( Known k + , Known v + , LookupWithIndex k dic ~ 'Just '(v, n) + , KnownNat n + ) => + Proxy k -> + Proxy v -> + Proxy n -> + b -> + m b + ) -> + b -> + m b +foldlMOrdMap' f = + foldrOrdMap @dic + (\pk pv pn k z -> (k $!) =<< f pk pv pn z) + return + +foldlOrdMapC' :: + forall c dic m b. + (AllOM c dic, Monad m) => + ( forall k v n. + ( Known k + , Known v + , LookupWithIndex k dic ~ 'Just '(v, n) + , KnownNat n + , c k v + ) => + Proxy k -> + Proxy v -> + Proxy n -> + b -> + b + ) -> + b -> + b +foldlOrdMapC' f = + foldrOrdMapC @c @dic + (\pk pv pn k z -> k $! f pk pv pn z) + id + +foldlOrdMap' :: + forall dic m b. + (Known dic, Monad m) => + ( forall k v n. + ( Known k + , Known v + , LookupWithIndex k dic ~ 'Just '(v, n) + , KnownNat n + ) => + Proxy k -> + Proxy v -> + Proxy n -> + b -> + b + ) -> + b -> + b +foldlOrdMap' f = + foldrOrdMap @dic + (\pk pv pn k z -> k $! f pk pv pn z) + id + +class (c a, d b) => BothC c d a b + +instance (c a, d b) => BothC c d a b + +omMembership :: forall l dic. (Member l dic) => OMMembership l dic +omMembership = OMMembership $ natVal @(Index l dic) Proxy + +{- | A variant of 'omMembership' with all the + type- and kind-variables are explicitly quantified; + for use with internal or type-checker plugin issues. +-} +omMembership' :: + forall key val (l :: key) (dic :: OrdMap key val). + (Member l dic) => + OMMembership l dic +{-# INLINE omMembership' #-} +omMembership' = omMembership + +-- | 'omMembership''-analogue of 'allOMDict'. +allOMDict' :: + forall + key + val + (c :: key -> val -> Constraint) + (dic :: OrdMap key val) + (l :: key). + (AllOM c dic, Member l dic) => + CustomDict (c l (Lookup' l dic)) +{-# INLINE allOMDict' #-} +allOMDict' = + withDict (allOMDict @c @dic (omMembership @l @dic)) $ + CDict @(c l (Lookup' l dic)) + +fromLabelListMember :: + forall l dic. + (List.Member l (Labels dic)) => + OMMembership l dic +fromLabelListMember = + unsafeCoerce $ + membership @l @(Labels dic) + +class + (c (Label f) (Entry f)) => + FieldC c (f :: Field k v) + +instance + (c k v) => + FieldC c (k ::: v) + +{-# INLINE elimAllOM #-} +elimAllOM :: + forall c dic k r. + (AllOM c dic) => + OMMembership k dic -> + ((c k (Lookup' k dic)) => r) -> + r +elimAllOM el = withDict (allOMDict @c el) + +allOMToAllFieldCDict :: + forall + key + val + (c :: key -> val -> Constraint) + (dic :: OrdMap key val). + (AllOM c dic, KnownTyList (ToList dic)) => + CustomDict (All (FieldC c) (ToList dic)) +allOMToAllFieldCDict = allOMToListAll @_ @_ @c @dic CDict + +allOMToListAll :: + forall key val (c :: key -> val -> Constraint) dic r. + ( AllOM c (dic :: OrdMap key val) + , KnownTyList (ToList dic) + ) => + ((All (FieldC c) (ToList dic)) => r) -> + r +allOMToListAll = withAllFromMember @(FieldC c) @(ToList dic) $ + \(_ :: Proxy fld) -> + gcastWith (elimFieldCons @fld) $ + withToListMember @fld @dic $ + elimAllOM @c @dic @(Label fld) + omMembership + (Dict :: Dict (FieldC c fld)) + +elimFieldCons :: + l :~: (Label l ::: Entry l) +elimFieldCons = unsafeCoerce $ Refl @() + +type EntryC :: forall (k :: Type) (v :: Type). (v -> Constraint) -> k -> v -> Constraint + +-- | To be used with 'foldMapRecC', 'traverseRecC' etc. +class (c v) => EntryC c l v + +instance (c v) => EntryC c l v + +-- | To be used with 'foldMapRecC', 'traverseRecC' etc. +class (c l) => LabelC c l v + +instance (c l) => LabelC c l v + +withAllConstMap :: + forall k c (xs :: [k]) r. + (SOrd k, All c xs, Known xs, SortableList xs) => + ((AllOM (LabelC c) (ConstMap xs)) => r) -> + r +withAllConstMap = withDict (sortAllDict @_ @c @xs) + +sortAllDict :: + forall l c xs. + (SOrd l) => + (All c (xs :: [l]), Known xs, SortableList xs) => + Dict (AllOM (LabelC c) (ConstMap xs)) +sortAllDict = + let sl = sConstMap $ sKnownVal' @xs + in go 0 sl + where + dicts = V.fromList $ sortedDicts @c @xs + go :: Int -> SOrdMap dic -> Dict (AllOM (LabelC c) dic) + go _ SLeaf = Dict + go !n (SBranch col m rk l (k :: Sing lab) v r) = + withKnownNat' m $ + withKnown' col $ + withKnown' rk $ + withKnown' l $ + withKnown' r $ + withKnown' k $ + withKnown' v $ + let !cur = fromIntegral (demote $ sSize l) + n + in case dicts V.! cur of + ElemDict _ _ (unsafeCoerce @_ @(Dict (c lab)) -> Dict) -> + case (go n l, go (cur + 1) r) of + (Dict, Dict) -> Dict + +sortedDicts :: + forall c xs. + (SortableList xs, All c xs) => + [ElemDict c xs] +sortedDicts = unsafeCoerce dicts + where + dicts = + V.toList $ + V.unsafeBackpermute dicts0 $ + V.convert sortPerms + dicts0 = V.fromList $ genDicts @c @xs + sortPerms = sortPermutation @(ConstList xs) + +allOMIntro :: + forall c dic r. + (Known dic) => + ( forall l v n. + ( LookupWithIndex l dic ~ 'Just '(v, n) + , KnownNat n + , Known l + , Known v + ) => + Proxy l -> + Proxy v -> + Proxy n -> + Dict (c l v) + ) -> + ((AllOM c dic) => r) -> + r +allOMIntro f = withDict (allOMDictIntro @c @dic f) + +allOMDictIntro :: + forall c dic. + (Known dic) => + ( forall l v n. + ( LookupWithIndex l dic ~ 'Just '(v, n) + , KnownNat n + , Known l + , Known v + ) => + Proxy l -> + Proxy v -> + Proxy n -> + Dict (c l v) + ) -> + Dict (AllOM c dic) +allOMDictIntro iter = go 0 $ sKnownVal' @dic + where + go :: Natural -> Sing xs -> Dict (AllOM c xs) + go _ SLeaf = Dict + go offset (SBranch col siz rk l (k :: Sing l) (v :: Sing v) r) = + withKnownNat' siz $ + withKnown' col $ + withKnown' rk $ + withKnown' k $ + withKnown' v $ + withDict (go offset l) $ + withDict (go (offset + demote (sSize l) + 1) r) $ + case promote $ offset + demote (sSize l) of + MkSomeSing (sn :: SNat n) -> + withKnownNat' sn + $ gcastWith + ( unsafeCoerce $ Refl @() :: + LookupWithIndex l dic :~: 'Just '(v, n) + ) + $ withDict + (iter (Proxy @l) (Proxy @v) (Proxy @n)) + Dict + +deferAllOMWith :: + forall c dic r. + (Known dic) => + ( forall l v n. + ( LookupWithIndex l dic ~ 'Just '(v, n) + , KnownNat n + , Known l + , Known v + ) => + Proxy l -> + Proxy v -> + Proxy n -> + Either String (Dict (c l v)) + ) -> + ((AllOM c dic) => r) -> + Either String r +deferAllOMWith iter act = + allOMIntro @(DeferrableFor2 c) @dic + ( \(l :: Proxy l) (v :: Proxy v) n -> + deferWith @(c l v) + ( ReifiedDeferrable $ \_ k -> do + Dict <- iter l v n + pure k + ) + Dict + ) + $ deferEither_ + @(AllOM c dic) + act + +sortAllFieldC :: + forall key val c dic r. + ( All (FieldC c) (dic :: [Field key val]) + , SortableLabels dic + , SOrd key + , Known dic + ) => + ((AllOM c (FromList dic)) => r) -> + r +sortAllFieldC = \act -> + withKnown' (sFromList $ sKnownVal' @dic) $ + allOMIntro @c @(FromList dic) @r + ( \(_ :: Proxy l) (_ :: Proxy v) (_ :: Proxy n) -> + unsortMembership @l @v @dic $ + elimByAll @(FieldC c) @(l ::: v) @dic + (Dict :: Dict (c l v)) + ) + act + +type family + AlignOM + (dic :: OrdMap key val) + (dic' :: OrdMap key val') :: + OrdMap key (These val val') + where + AlignOM 'Leaf 'Leaf = 'Leaf + AlignOM 'Leaf r = Con 'That <$> r + AlignOM l 'Leaf = Con 'This <$> l + AlignOM ('Branch c n rk l0 k v r0) r = AlignOMAux (Split k r) l0 k v r0 + +type family AlignOMAux splt l k v r where + AlignOMAux '(l1, 'Nothing, r1) l k v r = + Join (AlignOM l l1) k ('This v) (AlignOM r r1) + AlignOMAux '(l1, 'Just '(_, v'), r1) l k v r = + Join (AlignOM l l1) k ('These v v') (AlignOM r r1) + +sFMapOM :: (forall x. Sing x -> Sing (f x)) -> SOrdMap dic -> SOrdMap (Con f <$> dic) +sFMapOM _ SLeaf = SLeaf +sFMapOM sf (SBranch c n rk l k v r) = + SBranch c n rk (sFMapOM sf l) k (sf v) (sFMapOM sf r) + +sAlignOM :: + (SOrd key) => + SOrdMap (dic :: OrdMap key val) -> + SOrdMap (dic' :: OrdMap key val') -> + SOrdMap (AlignOM dic dic') +sAlignOM SLeaf SLeaf = SLeaf +sAlignOM SLeaf r@SBranch {} = sFMapOM SThat r +sAlignOM l@SBranch {} SLeaf = sFMapOM SThis l +sAlignOM (SBranch _ _ _ l k v r) r'@SBranch {} = + case sSplit k r' of + SMkTriple l1 SNothing r1 -> + sJoin (sAlignOM l l1) k (SThis v) (sAlignOM r r1) + SMkTriple l1 (SJust (SPair _ v')) r1 -> + sJoin (sAlignOM l l1) k (SThese v v') (sAlignOM r r1) + +elimMaybeCLookup' :: + forall k v (c :: v -> Constraint) (label :: k) (dic :: OrdMap k v). + (SOrd k, Known label, AllOM (EntryC c) dic) => + CustomDict (MaybeC c (Lookup label dic)) +elimMaybeCLookup' = + case sLookupWithIndex (sKnownVal' @label) (sKnownVal' @dic) of + SNothing -> CDict + SJust (SPair _ n) -> + withKnownNat' n $ elimAllOM @(EntryC c) @dic @label omMembership CDict diff --git a/elgenerics-known/src/Data/TypeLevel/OrdMap/Internal.hs b/elgenerics-known/src/Data/TypeLevel/OrdMap/Internal.hs new file mode 100644 index 0000000..48514ce --- /dev/null +++ b/elgenerics-known/src/Data/TypeLevel/OrdMap/Internal.hs @@ -0,0 +1,72 @@ +{-# LANGUAGE AllowAmbiguousTypes #-} +{-# LANGUAGE DataKinds #-} +{-# LANGUAGE DerivingStrategies #-} +{-# LANGUAGE DerivingVia #-} +{-# LANGUAGE GADTs #-} +{-# LANGUAGE TemplateHaskell #-} +{-# LANGUAGE TypeFamilies #-} +{-# LANGUAGE UndecidableInstances #-} +{-# LANGUAGE ViewPatterns #-} +{-# OPTIONS_GHC -Wall #-} + +module Data.TypeLevel.OrdMap.Internal where + +import Data.Type.Equality +import Data.TypeLevel.Known +import Data.TypeLevel.Ord +import GHC.Generics +import GHC.TypeLits +import Type.Reflection +import Unsafe.Coerce + +data Color = R | B deriving (Read, Show, Eq, Ord, Typeable) + +deriveAllKnown True ''Color + +type SizeT = Nat + +newtype RankT = MkRankT Nat + +data SRankT (n :: RankT) where + SMkRankT :: SNat n -> SRankT (MkRankT n) + +type family CmpRankT2 a b where + CmpRankT2 ('MkRankT l) ('MkRankT r) = Compare l r + +instance POrd RankT where + type Compare a b = CmpRankT2 a b + +instance SOrd RankT where + sCompare (SMkRankT l) (SMkRankT r) = sCompare l r + +type instance Sing = SRankT + +deriving instance Show (SRankT n) + +type MkRankT = 'MkRankT + +deriveSingTypeable ''RankT + +instance (KnownNat n) => Known (MkRankT n) where + sKnownVal' = + case unsafeCoerce (Equal @0 @0) :: Equality n n of + Equal -> SMkRankT $ sKnownVal' @n + +deriving via WrapSing instance TestEquality SRankT + +instance STestEquality RankT where + sTestEquality = \(SMkRankT l) (SMkRankT r) -> + case sTestEquality l r of + Equal -> Equal + NonEqual -> unsafeCoerce $ NonEqual @0 @1 + +-- | (型レベル)平衡二分探索木。赤黒木として実装している。 +data OrdMap k v = Leaf | Branch Color SizeT RankT (OrdMap k v) k v (OrdMap k v) + deriving (Typeable, Generic) + +defineSingletons ''OrdMap +deriveKnown ''OrdMap +deriveSTestEquality ''OrdMap +deriveSingTypeable ''OrdMap + +newtype OMMembership k dic = OMMembership Natural diff --git a/elgenerics-known/src/Data/TypeLevel/Tuple.hs b/elgenerics-known/src/Data/TypeLevel/Tuple.hs new file mode 100644 index 0000000..d125b5c --- /dev/null +++ b/elgenerics-known/src/Data/TypeLevel/Tuple.hs @@ -0,0 +1,21 @@ +{-# LANGUAGE DataKinds #-} +{-# LANGUAGE TypeFamilies #-} +{-# LANGUAGE UndecidableInstances #-} + +module Data.TypeLevel.Tuple ( + Snd, + Snd1, + Fst, + Fst1, + First, + First2, + First1, + Second, + Second2, + Second1, + Uncurry, + Swap, + Swap1, +) where + +import Data.TypeLevel.Known.Core diff --git a/elgenerics-known/src/Data/TypeLevel/Typeable.hs b/elgenerics-known/src/Data/TypeLevel/Typeable.hs new file mode 100644 index 0000000..052aca6 --- /dev/null +++ b/elgenerics-known/src/Data/TypeLevel/Typeable.hs @@ -0,0 +1,229 @@ +{-# LANGUAGE CPP #-} +{-# LANGUAGE DataKinds #-} +{-# LANGUAGE GADTs #-} +{-# LANGUAGE RecordWildCards #-} +{-# LANGUAGE TemplateHaskell #-} +{-# LANGUAGE TypeFamilies #-} +{-# LANGUAGE UndecidableInstances #-} + +module Data.TypeLevel.Typeable ( + PTypeRep (..), + TypeRepOf, + CmpTypeRep, + ShowTypeRep, + deriveTypeRep, + sTypeRepOf, + SPTypeRep (..), + DynDCon, +) where + +import Control.Monad +import Data.Foldable +import Data.Int +import Data.Kind +import Data.Maybe +import Data.Sequence qualified as Seq +import Data.Type.Equality +import Data.TypeLevel.Known +import Data.TypeLevel.Monoid +import Data.TypeLevel.Nat +import Data.Word +import GHC.Generics +import GHC.TypeLits +import Language.Haskell.TH hiding (Type) +import Language.Haskell.TH.Desugar +import TH.ReifySimple +import Type.Reflection hiding (Con) +import Type.Reflection qualified as TyRep +import Unsafe.Coerce (unsafeCoerce) + +data PTypeRep + = TySym Symbol + | TyNat Nat + | Con Symbol Symbol Symbol + | TyApp PTypeRep PTypeRep + | TyFun PTypeRep PTypeRep + deriving (Typeable) + +defineSingletons ''PTypeRep +deriveKnown ''PTypeRep +deriveShowSing ''PTypeRep +deriveSTestEquality ''PTypeRep + +type PrimOrRep :: forall k. k -> Type -> Type +type family PrimOrRep (a :: k) :: Type -> Type where + PrimOrRep Natural = D1 ('MetaData "Natural" "GHC.Num.Natural" "ghc-bignum" 'False) V1 + PrimOrRep Symbol = D1 ('MetaData "Symbol" "GHC.Types" "ghc-prim" 'False) V1 + PrimOrRep Int = D1 ('MetaData "Int" "GHC.Types" "ghc-prim" 'False) V1 + PrimOrRep Word = D1 ('MetaData "Word" "GHC.Types" "ghc-prim" 'False) V1 + PrimOrRep Float = D1 ('MetaData "Float" "GHC.Types" "ghc-prim" 'False) V1 + PrimOrRep Double = D1 ('MetaData "Double" "GHC.Types" "ghc-prim" 'False) V1 + PrimOrRep Char = D1 ('MetaData "Char" "GHC.Types" "ghc-prim" 'False) V1 + PrimOrRep Word8 = D1 ('MetaData "Word8" "GHC.Word" "base" 'False) V1 + PrimOrRep Word16 = D1 ('MetaData "Word16" "GHC.Word" "base" 'False) V1 + PrimOrRep Word32 = D1 ('MetaData "Word32" "GHC.Word" "base" 'False) V1 + PrimOrRep Word64 = D1 ('MetaData "Word64" "GHC.Word" "base" 'False) V1 + PrimOrRep Int8 = D1 ('MetaData "Int8" "GHC.Int" "base" 'False) V1 + PrimOrRep Int16 = D1 ('MetaData "Int16" "GHC.Int" "base" 'False) V1 + PrimOrRep Int32 = D1 ('MetaData "Int32" "GHC.Int" "base" 'False) V1 + PrimOrRep Int64 = D1 ('MetaData "Int64" "GHC.Int" "base" 'False) V1 + PrimOrRep Integer = + D1 ('MetaData "Integer" "GHC.Integer.Type" "integer-gmp" 'False) V1 + PrimOrRep a = Rep a + PrimOrRep (a :: k) = DynDCon k a + +type family DynDCon k (a :: k) :: Type -> Type + +deriveTypeRep :: + Name -> DecsQ +deriveTypeRep name = do + DataType {} <- reifyDataType name + Just (DTyConI (DDataD newOrData _ _ _tyVars _mKind cons _) _) <- + dsReify name + fmap (sweeten . concat) $ + forM cons $ \dcon@(DCon _ _ dcName _ _) -> do + let (params, retType) = dconParamRetType dcon + body <- desugar =<< buildDynDCon newOrData dcon + loop dcName Seq.empty params retType body [] + where + loop dcName args params retType body acc = + let dsig = foldr (\l r -> (DAppT DArrowT l) `DAppT` r) retType params + applied = foldl' DAppT (DConT dcName) args + dsyn = + DTySynInstD $ + DTySynEqn + Nothing + (DConT ''DynDCon `DAppT` dsig `DAppT` applied) + body + in case params of + [] -> pure $ dsyn : acc + (p : ps) -> do + v <- newName "v" + let p' = DVarT v `DSigT` p + loop dcName (args Seq.|> p') ps retType body (dsyn : acc) + +dconParamRetType :: + DCon -> ([DType], DType) +dconParamRetType (DCon _ _ _ flds retTy) = do + (decodeConFields flds, retTy) + +decodeConFields :: DConFields -> [DType] +decodeConFields (DNormalC _ bTys) = map snd bTys +decodeConFields (DRecC vbtys) = + map (\(_, _, ty) -> ty) vbtys + +buildDynDCon :: + NewOrData -> DCon -> TypeQ +buildDynDCon newOr (DCon _ _ dcName _ _) = do + let modName = fromMaybe "" $ nameModule dcName + pkgName = fromMaybe "" $ namePackage dcName + isNew = case newOr of + Newtype -> [t|'True|] + Data -> [t|'False|] + [t| + D1 + ( 'MetaData + $(litT $ strTyLit $ nameBase dcName) + $(litT $ strTyLit $ modName) + $(litT $ strTyLit $ pkgName) + $(isNew) + ) + V1 + |] + +type TypeRepOf :: k -> PTypeRep +type family TypeRepOf (a :: k) :: PTypeRep where + TypeRepOf (n :: Nat) = 'TyNat n + TypeRepOf (sym :: Symbol) = 'TySym sym + TypeRepOf a = TypeRepOfAux (ToCon (PrimOrRep a)) a + +type TypeRepOfAux :: PTypeRep -> k -> PTypeRep +type family TypeRepOfAux (rep :: PTypeRep) (a :: k) :: PTypeRep where + TypeRepOfAux _ (a -> b) = 'TyFun (TypeRepOf a) (TypeRepOf b) + TypeRepOfAux rep (f a) = 'TyApp (TypeRepOfAux rep f) (TypeRepOf a) + TypeRepOfAux rep _ = rep + +type family ToCon (f :: k -> Type) :: PTypeRep where + ToCon (D1 ('MetaData l m p 'False) _) = 'Con l m p + +type CmpTypeRep l r = CmpTypeRepAux (l == r) l r + +type family + CmpTypeRepAux (p :: Bool) (l :: PTypeRep) (r :: PTypeRep) :: + Ordering + where + CmpTypeRepAux 'True t t = 'EQ + CmpTypeRepAux 'False ('TySym l) ('TySym r) = CmpSymbol l r + CmpTypeRepAux 'False ('TySym _) _ = 'LT + CmpTypeRepAux 'False ('TyNat _) ('TySym _) = 'GT + CmpTypeRepAux 'False ('TyNat l) ('TyNat r) = CmpNat l r + CmpTypeRepAux 'False ('TyNat _) _ = 'LT + CmpTypeRepAux 'False ('Con _ _ _) ('TySym _) = 'GT + CmpTypeRepAux 'False ('Con _ _ _) ('TyNat _) = 'GT + CmpTypeRepAux 'False ('Con l1 l2 l3) ('Con r1 r2 r3) = + CmpSymbol l1 r1 <> CmpSymbol l2 r2 <> CmpSymbol l3 r3 + CmpTypeRepAux 'False ('Con _ _ _) _ = 'LT + CmpTypeRepAux 'False ('TyApp _ _) ('TySym _) = 'GT + CmpTypeRepAux 'False ('TyApp _ _) ('TyNat _) = 'GT + CmpTypeRepAux 'False ('TyApp _ _) ('Con _ _ _) = 'GT + CmpTypeRepAux 'False ('TyApp l1 l2) ('TyApp r1 r2) = + CmpTypeRepAux (l1 == r1) l1 r1 <> CmpTypeRepAux (l2 == r2) l2 r2 + CmpTypeRepAux 'False ('TyApp _ _) ('TyFun _ _) = 'LT + CmpTypeRepAux 'False ('TyApp _ _) _ = 'GT + CmpTypeRepAux 'False ('TyFun l r) ('TyFun l' r') = + CmpTypeRepAux (l == l') l l' <> CmpTypeRepAux (r == r') r r' + CmpTypeRepAux 'False ('TyFun l r) _ = 'GT + +type ShowTypeRep a = ShowTypeRepAux 'False a + +type family ShowTypeRepAux (b :: Bool) (tyRep :: PTypeRep) :: Symbol where + ShowTypeRepAux _ ('TyNat n) = ShowNat n + ShowTypeRepAux _ ('TySym n) = n + ShowTypeRepAux _ ('Con l _ _) = l + ShowTypeRepAux 'False ('TyApp l r) = + ShowTypeRepAux 'False l <> " " <> ShowTypeRepAux 'True r + ShowTypeRepAux 'True ('TyApp l r) = + "(" <> ShowTypeRepAux 'False l <> " " <> ShowTypeRepAux 'True r <> ")" + ShowTypeRepAux 'True ('TyFun l r) = + "(" <> ShowTypeRepAux 'False ('TyFun l r) <> ")" + ShowTypeRepAux 'False ('TyFun l r) = + ShowTypeRepAux 'True l <> " -> " <> ShowTypeRepAux 'False r + +sTypeRepOf :: Sing (a :: Type) -> Sing (TypeRepOf a) +sTypeRepOf rep = withKnown' rep $ liftTypeRep rep + +liftTypeRep :: + forall k a. + (Typeable k) => + TypeRep (a :: k) -> + Sing (TypeRepOf a) +liftTypeRep rep = + let tCon = TyRep.typeRepTyCon rep + in case testEquality (typeRep @Nat) (typeRep @k) of + Just Refl -> case promote @Nat (read $ tyConName tCon) of + MkSomeSing sn -> STyNat $ unsafeCoerce sn + Nothing -> + case testEquality (typeRep @Symbol) (typeRep @k) of + Just Refl -> + case promote @Symbol $ read $ tyConName tCon of + MkSomeSing ssymb -> STySym $ unsafeCoerce ssymb + Nothing -> + case rep of + TyRep.App l r -> + TyRep.withTypeable (typeRepKind l) $ + TyRep.withTypeable (typeRepKind r) $ + unsafeCoerce $ + STyApp (liftTypeRep l) (liftTypeRep r) + TyRep.Con con -> + case ( promote $ tyConName con + , promote $ tyConModule con + , promote $ tyConPackage con + ) of + (MkSomeSing l, MkSomeSing m, MkSomeSing n) -> + unsafeCoerce $ + SCon l m n + TyRep.Fun l r -> + TyRep.withTypeable (typeRepKind l) $ + TyRep.withTypeable (typeRepKind r) $ + unsafeCoerce $ + STyFun (liftTypeRep l) (liftTypeRep r) diff --git a/elgenerics-known/src/Data/UnionFind/Primitive.hs b/elgenerics-known/src/Data/UnionFind/Primitive.hs new file mode 100644 index 0000000..32bca2c --- /dev/null +++ b/elgenerics-known/src/Data/UnionFind/Primitive.hs @@ -0,0 +1,53 @@ +{-# LANGUAGE DerivingStrategies #-} + +{- | Generic Union-Find implementation, wrapping @union-find@ package around + 'PrimMonad' interface. + If you need extra operation on representatives on 'union' you can use this module. + If you only need really fast union-find and no operations on representatives + needed, consider using "Data.UnionFind.Fast". +-} +module Data.UnionFind.Primitive ( + Point, + fresh, + repr, + union, + equivalent, + redundant, + descriptor, + setDescriptor, + modifyDescriptor, + + -- * Re-exports + PrimMonad (..), +) where + +import Control.Monad.Primitive +import Data.Function +import Data.UnionFind.ST qualified as UF + +newtype Point m a = PPoint {unPoint :: UF.Point (PrimState m) a} + deriving newtype (Eq) + +fresh :: (PrimMonad m) => a -> m (Point m a) +fresh = fmap PPoint . stToPrim . UF.fresh + +repr :: (PrimMonad m) => Point m a -> m (Point m a) +repr = fmap PPoint . stToPrim . UF.repr . unPoint + +union :: (PrimMonad m) => Point m a -> Point m a -> m () +union = fmap stToPrim <$> UF.union `on` unPoint + +equivalent :: (PrimMonad m) => Point m a -> Point m a -> m Bool +equivalent = fmap stToPrim <$> UF.equivalent `on` unPoint + +redundant :: (PrimMonad m) => Point m a -> m Bool +redundant = stToPrim . UF.redundant . unPoint + +descriptor :: (PrimMonad m) => Point m a -> m a +descriptor = stToPrim . UF.descriptor . unPoint + +setDescriptor :: (PrimMonad m) => Point m a -> a -> m () +setDescriptor = fmap stToPrim . UF.setDescriptor . unPoint + +modifyDescriptor :: (PrimMonad m) => Point m a -> (a -> a) -> m () +modifyDescriptor = fmap stToPrim . UF.modifyDescriptor . unPoint diff --git a/elgenerics-known/src/GHC/TcPluginM/Orphans.hs b/elgenerics-known/src/GHC/TcPluginM/Orphans.hs new file mode 100644 index 0000000..2622349 --- /dev/null +++ b/elgenerics-known/src/GHC/TcPluginM/Orphans.hs @@ -0,0 +1,56 @@ +{-# LANGUAGE CPP #-} +{-# LANGUAGE DerivingVia #-} +{-# LANGUAGE TypeFamilies #-} +{-# LANGUAGE UndecidableInstances #-} +{-# OPTIONS_GHC -Wno-orphans #-} + +module GHC.TcPluginM.Orphans () where + +import Control.Monad.IO.Class +import Control.Monad.Primitive +#if MIN_VERSION_ghc(9,0,1) +import GHC +import GHC.Plugins +import GHC.Tc.Plugin +import Control.Exception.Safe +import Control.Monad.Trans.State.Strict +import Control.Monad.Trans.Reader +import GHC.Utils.Error + +#else +import GHC +import Exception +import GhcPlugins +import TcPluginM +#endif + +instance MonadIO TcPluginM where + liftIO = tcPluginIO + +instance PrimMonad TcPluginM where + type PrimState TcPluginM = PrimState IO + primitive = tcPluginIO . primitive + +#if MIN_VERSION_ghc(9,0,1) +deriving via ReaderT HscEnv (StateT WarningMessages IO) + instance MonadThrow Hsc +deriving via ReaderT HscEnv (StateT WarningMessages IO) + instance MonadCatch Hsc +deriving via ReaderT HscEnv (StateT WarningMessages IO) + instance MonadMask Hsc + +#else +instance ExceptionMonad Hsc where + gcatch (Hsc f) cth = Hsc $ \a b -> + f a b `catch` \e -> + case cth e of + Hsc k -> k a b + gmask withRestore = Hsc $ \a b -> + gmask $ \restoreIO -> + case withRestore (\(Hsc g) -> Hsc $ \x y -> restoreIO $ g x y) of + Hsc k -> k a b +#endif + +instance GhcMonad Hsc where + getSession = Hsc $ \e w -> return (e, w) + setSession = const $ error "Cannot set session in Hsc" diff --git a/elgenerics-known/test/Data/Constraint/Deferrable/SolverSpec.hs b/elgenerics-known/test/Data/Constraint/Deferrable/SolverSpec.hs new file mode 100644 index 0000000..fb8562d --- /dev/null +++ b/elgenerics-known/test/Data/Constraint/Deferrable/SolverSpec.hs @@ -0,0 +1,33 @@ +{-# LANGUAGE DataKinds #-} +{-# LANGUAGE GADTs #-} + +module Data.Constraint.Deferrable.SolverSpec where + +import Data.Constraint.Deferrable.SolverSpec.Cases +import Data.Constraint.Deferrable.SolverSpec.Undeferreds +import Data.Proxy (Proxy (Proxy)) +import Helpers +import Test.Tasty (TestTree, testGroup) +import Test.Tasty.HUnit (testCase, (@?=)) + +test_DeferrableSolver :: TestTree +test_DeferrableSolver = + testGroup + "DeferrableSolver" + [ testCase "Cannot defer unavailable constraint (no instance)" $ + shouldThrowTypeError deferInaccessible + , testCase "Cannot defer constraint" $ + shouldThrowTypeError undeferrableOk + , testCase "Can defer constraint with specific overlapping instance" $ + shouldNotThrowTypeError deferrableOk + , testCase "Can defer concrete (KnownNat 42)" $ + theUnit @?= Right () + , testCase "Can choose available dictionary, KnownNat n, polymorphically" $ + deferKnownNatN (Proxy @2) @?= Right 2 + , testCase "Can defer higher-order constraints correctly: fail for absent" $ + deferDummy @5 (knn (Proxy @Dummy) (Proxy @5)) + @?= Left "No dictionary" + , testCase "Can defer higher-order constraints correctly: success if present" $ + deferDummy @1 (knn (Proxy @Dummy) (Proxy @1)) + @?= Right 1 + ] diff --git a/elgenerics-known/test/Data/Constraint/Deferrable/SolverSpec/Cases.hs b/elgenerics-known/test/Data/Constraint/Deferrable/SolverSpec/Cases.hs new file mode 100644 index 0000000..cc8472a --- /dev/null +++ b/elgenerics-known/test/Data/Constraint/Deferrable/SolverSpec/Cases.hs @@ -0,0 +1,58 @@ +{-# LANGUAGE DataKinds #-} +{-# LANGUAGE DeriveAnyClass #-} +{-# LANGUAGE DerivingStrategies #-} +{-# OPTIONS_GHC -fdefer-type-errors -Wno-deferred-type-errors #-} +{-# OPTIONS_GHC -fplugin Data.Constraint.Deferrable.Solver #-} + +module Data.Constraint.Deferrable.SolverSpec.Cases where + +import Control.DeepSeq (NFData) +import Data.Constraint.Deferrable ( + Deferrable, + deferEither_, + ) +import Data.Constraint.Deferrable.SolverSpec.Undeferreds +import Data.Proxy (Proxy (Proxy)) +import GHC.Generics (Generic) +import GHC.TypeNats (KnownNat, Nat, natVal) +import Numeric.Natural (Natural) + +data Void + deriving (Show, Generic) + deriving anyclass (NFData) + +class Inaccessible a where + inaccessible :: a -> Void + +deferInaccessible :: + Either String Void +deferInaccessible = + deferEither_ @(Inaccessible Int) $ inaccessible (42 :: Int) + +class Ok (n :: Nat) where + ok :: proxy n -> Int + +instance Ok 42 where + ok = const 42 + +deferOk :: + forall n proxy. + (Deferrable (Ok n)) => + proxy n -> + Either String Int +deferOk pn = deferEither_ @(Ok n) $ ok pn + +undeferrableOk :: Either String Int +undeferrableOk = deferOk (Proxy @0) + +deferrableOk :: Either String Int +deferrableOk = deferOk (Proxy @42) + +theUnit :: Either String () +theUnit = deferEither_ @(KnownNat 42) () + +deferKnownNatN :: forall n proxy. (KnownNat n) => proxy n -> Either String Natural +deferKnownNatN pxy = deferEither_ @(KnownNat n) $ natVal pxy + +deferDummy :: forall n r. (KnownNat n) => ((Foo Dummy n) => r) -> Either String r +deferDummy = deferEither_ @(Foo Dummy n) diff --git a/elgenerics-known/test/Data/Constraint/Deferrable/SolverSpec/Undeferreds.hs b/elgenerics-known/test/Data/Constraint/Deferrable/SolverSpec/Undeferreds.hs new file mode 100644 index 0000000..86bc24c --- /dev/null +++ b/elgenerics-known/test/Data/Constraint/Deferrable/SolverSpec/Undeferreds.hs @@ -0,0 +1,28 @@ +{-# LANGUAGE DataKinds #-} +{-# LANGUAGE GADTs #-} + +module Data.Constraint.Deferrable.SolverSpec.Undeferreds where + +import Control.Monad (join) +import Data.Constraint.Deferrable (Deferrable (..), deferEither_, (:~:) (Refl)) +import Data.Proxy (Proxy) +import Data.Type.Equality (TestEquality (testEquality)) +import Data.TypeLevel.Known (sKnownVal') +import GHC.TypeNats (KnownNat, Nat, natVal) +import Numeric.Natural (Natural) + +class Foo env (n :: Nat) where + knn :: Proxy env -> Proxy n -> Natural + +data Dummy + +instance Foo Dummy 1 where + knn = const natVal + +instance (Deferrable (KnownNat n)) => Deferrable (Foo Dummy n) where + deferEither _ r = + join $ + deferEither_ @(KnownNat n) $ + case testEquality (sKnownVal' @n) (sKnownVal' @1) of + Just Refl -> Right r + Nothing -> Left "No dictionary" diff --git a/elgenerics-known/test/Data/TypeLevel/KnownSpec.hs b/elgenerics-known/test/Data/TypeLevel/KnownSpec.hs new file mode 100644 index 0000000..6335f79 --- /dev/null +++ b/elgenerics-known/test/Data/TypeLevel/KnownSpec.hs @@ -0,0 +1,71 @@ +{-# LANGUAGE DataKinds #-} +{-# LANGUAGE GADTs #-} +{-# LANGUAGE TemplateHaskell #-} +{-# LANGUAGE TypeFamilies #-} +{-# LANGUAGE UndecidableInstances #-} +{-# OPTIONS_GHC -fdefer-type-errors #-} + +module Data.TypeLevel.KnownSpec where + +import Data.TypeLevel.Known +import GHC.TypeLits (Nat) +import Test.Tasty +import Test.Tasty.HUnit + +maybePureUnit :: (Applicative m) => SMaybe may -> m () +maybePureUnit arg = $(sCases ''Maybe [|arg|] [|pure ()|]) + +test_sCases_Maybe :: TestTree +test_sCases_Maybe = testCase "sCases on Maybe works properly" $ do + let sNot = SNothing :: SMaybe ('Nothing :: Maybe Nat) + maybePureUnit sNot + maybePureUnit $ SJust (sKnownVal' @4) + +test_sCases_Bool :: TestTree +test_sCases_Bool = testCase "sCases on Bool works properly" $ do + boolPureUnit SFalse + boolPureUnit STrue + +test_sCases_Bool_safe_depends :: TestTree +test_sCases_Bool_safe_depends = + testCase "sCases on Bool, depending on the value itself only in expression, works properly" $ do + boolDemote SFalse @?= False + boolDemote STrue @?= True + +boolPureUnit :: (Applicative m) => SBool p -> m () +boolPureUnit arg = + $(sCases ''Bool [|arg|] [|pure ()|]) + +boolDemote :: SBool p -> Bool +boolDemote arg = + $(sCases ''Bool [|arg|] [|demote arg|]) + +data Mode = Pred | Id | Succ + deriving (Show, Eq, Ord) + +deriveAllKnown True ''Mode + +class Branch (mode :: Mode) where + branch :: proxy mode -> Int -> Int + +instance Branch Pred where + branch = const pred + +instance Branch Id where + branch = const id + +instance Branch Succ where + branch = const succ + +-- We need this to avoid stage restrictions +pure [] + +applyMode :: SMode mode -> Int -> Int +applyMode mode n = + $(sCases ''Mode [|mode|] [|branch mode n|]) + +test_branching :: TestTree +test_branching = testCase "sCases handles instance resolution properly" $ do + applyMode SPred 12 @?= 11 + applyMode SId 12 @?= 12 + applyMode SSucc 12 @?= 13 diff --git a/elgenerics-known/test/Data/TypeLevel/ListSpec.hs b/elgenerics-known/test/Data/TypeLevel/ListSpec.hs new file mode 100644 index 0000000..8eab6ed --- /dev/null +++ b/elgenerics-known/test/Data/TypeLevel/ListSpec.hs @@ -0,0 +1,267 @@ +{-# LANGUAGE DataKinds #-} +{-# LANGUAGE ExplicitNamespaces #-} +{-# LANGUAGE GADTs #-} +{-# LANGUAGE LambdaCase #-} +{-# LANGUAGE ViewPatterns #-} + +module Data.TypeLevel.ListSpec where + +import Data.Constraint (withDict) +import Data.List (sortOn) +import Data.Proxy (Proxy (Proxy)) +import Data.Set (Set) +import qualified Data.Set as Set +import Data.Type.Equality ((:~:) (Refl)) +import Data.TypeLevel.Known +import Data.TypeLevel.List (All, sLength, (%++)) +import Data.TypeLevel.ListSpec.Cases +import Data.TypeLevel.ListSpec.Undeferred +import Data.TypeLevel.OrdMap (sConstList, sSortPermutation, (:::)) +import qualified Data.TypeLevel.OrdMap as OM +import qualified Data.Typeable as DT +import GHC.Generics (Generic) +import GHC.TypeLits + ( KnownSymbol, + SomeSymbol (..), + Symbol, + someSymbolVal, + ) +import GHC.TypeNats (KnownNat, Nat, natVal, type (<=)) +import Helpers +import Test.Tasty +import Test.Tasty.HUnit (testCase, (@?=)) +import Test.Tasty.QuickCheck + ( Property, + getNonNegative, + ioProperty, + tabulate, + testProperty, + (===), + ) +import Type.Reflection (SomeTypeRep, Typeable) + +test_length_map :: TestTree +test_length_map = testProperty "Length commutes with Map" $ + \(xs :: [Integer]) -> + let len = fromIntegral $ length xs + in tabulate "length" [show len] $ + case promote @[Nat] (map (fromIntegral . abs) xs) of + MkSomeSing lst -> + withKnownNat' (sLength lst) $ + mapLen lst === len + +test_illegal_length_map :: TestTree +test_illegal_length_map = + testCase "Cannot derive length illegally" $ + shouldThrowTypeError $ + illegalMapLen (Proxy @'[]) + +test_trivalSort :: TestTree +test_trivalSort = + testInspection "SortedBy respects SortBy" trivialSort + +test_illegalSorts :: TestTree +test_illegalSorts = + testGroup + "SortedBy rejects illegal SortBy" + [ expectInspectionFail "nested" nontrivialSort + , expectInspectionFail "simple" nontrivialSort2 + ] + +test_elimAllOMLookup :: TestTree +test_elimAllOMLookup = + testGroup + "Solver can eliminate AllOM + FromMaybe constraint" + [ testCase "case1" $ + elimAllOMLookup (Proxy @'True) (Proxy @(OM.FromList '[])) (Proxy @Int) + @?= "Int" + , testCase "case2" $ + elimAllOMLookup (Proxy @'True) (Proxy @(OM.FromList '[ 'True OM.::: Bool])) (Proxy @Int) + @?= "Bool" + ] + +test_showOrdMapType_Ok :: TestTree +test_showOrdMapType_Ok = + testCase "AllOM elimination takes superclass constraints into account" $ + shownOrdMap + @?= [ (DT.typeRep $ Proxy @Bool, DT.typeRep $ Proxy @1, 0) + , (DT.typeRep $ Proxy @Int, DT.typeRep $ Proxy @5, 1) + , (DT.typeRep $ Proxy @(Maybe ()), DT.typeRep $ Proxy @0, 2) + ] + +test_sortLabelType :: TestTree +test_sortLabelType = + testProperty "withAllConstMap and foldMapOrdMap propagates constraints to key" $ + \(xs0 :: Set String) -> + tabulate "size" [show $ Set.size xs0] $ + let xs = Set.toList xs0 + in ( case toKnownSymbols xs of + MkKnownSymbols slist -> + withKnown' slist $ + withKnown' (sSortPermutation $ sConstList slist) $ + sortLabelTypeable slist + === sortOn fst (zip xs [0 ..]) + ) :: + Property + +data KnownSymbols where + MkKnownSymbols :: + (All Typeable syms, All KnownSymbol syms) => + SList syms -> + KnownSymbols + +toKnownSymbols :: + [String] -> KnownSymbols +toKnownSymbols [] = MkKnownSymbols SNil +toKnownSymbols (sStr : rest) = + case someSymbolVal sStr of + SomeSymbol (_ :: Proxy symb) -> + case toKnownSymbols rest of + MkKnownSymbols syms -> + MkKnownSymbols $ sKnownVal' @symb :% syms + +test_listAssoc :: TestTree +test_listAssoc = + testCase "Solver could prove associativity of list concatenation" $ + shouldNotThrowTypeError appAssoc + +test_listFalseAssoc :: TestTree +test_listFalseAssoc = + testCase "Solver could not prove wrong associativity" $ + shouldThrowTypeError appFalseAssoc + +test_mapApply_Cons :: TestTree +test_mapApply_Cons = + testProperty "MapApply distributes over append and cons" $ + \xs (x :: Integer) ys -> + ( case ( promote @[Nat] $ map fromInteger xs + , promote @Nat (fromIntegral x) + , promote @[Nat] $ map fromInteger ys + ) of + (MkSomeSing xs', MkSomeSing nat', MkSomeSing ys') -> + case mapApplyDistrib xs' ys' nat' of + Refl -> True + ) :: + Bool + +test_False_mapApply_Cons :: TestTree +test_False_mapApply_Cons = + testCase "MapApply refutes inappropriate distribution" $ + shouldThrowTypeError $ + mapApplyFalseDistrib (Proxy @[1, 2, 3]) (Proxy @[4, 5, 6]) (Proxy @12) + +data Foo n where + TheOne :: Foo 1 + The42 :: Foo 42 + TheThree :: Foo 3 + +instance Show (Foo 1) where + showsPrec _ TheOne = showString "TheOne" + +instance Show (Foo 42) where + showsPrec _ The42 = showString "The42" + +instance Show (Foo 3) where + showsPrec _ TheThree = showString "TheThree" + +test_showMap :: TestTree +test_showMap = + testCase "Map and All commutes" $ + showMap (Proxy @'[42, 1, 3]) TheOne @?= "TheOne" + +test_typeRepList :: TestTree +test_typeRepList = + testCase "typeRepList" $ + typeRepList (Proxy @'[Int, IO Bool, String]) + @?= [ DT.typeRep (Proxy @Int) + , DT.typeRep (Proxy @(IO Bool)) + , DT.typeRep (Proxy @String) + ] + +test_typeRepList_symbols :: TestTree +test_typeRepList_symbols = testProperty "typeRepList" $ \strs -> + ( case toKnownSymbols strs of + MkKnownSymbols (symbs :: SList syms) -> + withKnownNat' (sLength symbs) $ + typeRepList (Proxy @syms) + === symsTypeRepList symbs + ) :: + Property + +symsTypeRepList :: + All Typeable syms => SList (syms :: [Symbol]) -> [SomeTypeRep] +symsTypeRepList SNil = [] +symsTypeRepList (x :% xs) = + DT.typeRep x : symsTypeRepList xs + +class GoodNat (a :: Nat) where + isGood :: Foo a -> String + +instance GoodNat 1 where + isGood = show + +instance GoodNat 3 where + isGood = show + +instance GoodNat 42 where + isGood = show + +test_myElimFromAll :: TestTree +test_myElimFromAll = + testCase "List solver can resolve All'd constraint from Member polyrmorphically" $ + withDict (myElimFromAll (Proxy @GoodNat) (Proxy @1) (Proxy @'[42, 1, 3])) $ + isGood TheOne @?= "TheOne" + +test_splitAtApply :: TestTree +test_splitAtApply = + testProperty "Can solve complex equation involving Take, Drop and Map" $ + \(x :: Maybe String) (y :: String) (xs :: [String]) -> + case (promote @(Maybe Symbol) x, promote @Symbol y, promote @[Symbol] xs) of + ( MkSomeSing (_ :: Sing ms) + , MkSomeSing (_ :: Sing sym) + , MkSomeSing (_ :: Sing xs) + ) -> + ioProperty $ + shouldNotThrowTypeError $ + splitAtApply (Proxy @ms) (Proxy @sym) (Proxy @xs) + +class GoodOver h a where + goodOver :: proxy h -> proxy' a -> String + +data Qux deriving (Typeable, Generic) + +data Bar deriving (Typeable, Generic) + +data Duz deriving (Typeable, Generic) + +type GoodDic = + OM.FromList + '[ Qux ::: 42 + , Bar ::: 4 + , Duz ::: 999 + ] + +instance GoodOver Qux 42 where + goodOver _ _ = "Qux 42" + +instance GoodOver Duz n where + goodOver _ _ = "Qux <>" + +instance (KnownNat n, n <= 5) => GoodOver Bar n where + goodOver _ = ("Bar " <>) . show . natVal + +test_trivialOM :: TestTree +test_trivialOM = + testCase "OrdMap solver can resolve All'd constraint from Member polyrmorphically" $ + withDict (trivialOM (Proxy @GoodOver) (Proxy @GoodDic) (Proxy @Qux)) $ + goodOver (Proxy @Qux) (Proxy @42) @?= "Qux 42" + +test_sAppend :: TestTree +test_sAppend = + testProperty "(%++) appends two type-level lists correctly" $ + \(map (fromInteger . getNonNegative) -> xs) + (map (fromInteger . getNonNegative) -> ys) -> + case (promote @[Nat] xs, promote @[Nat] ys) of + (MkSomeSing sxs, MkSomeSing sys) -> + let xsys = demote $ sxs %++ sys + in xsys === (xs ++ ys) diff --git a/elgenerics-known/test/Data/TypeLevel/ListSpec/Cases.hs b/elgenerics-known/test/Data/TypeLevel/ListSpec/Cases.hs new file mode 100644 index 0000000..a5f5823 --- /dev/null +++ b/elgenerics-known/test/Data/TypeLevel/ListSpec/Cases.hs @@ -0,0 +1,225 @@ +{-# LANGUAGE AllowAmbiguousTypes #-} +{-# LANGUAGE DataKinds #-} +{-# LANGUAGE MonoLocalBinds #-} +{-# LANGUAGE TemplateHaskell #-} +{-# LANGUAGE TypeFamilies #-} +{-# OPTIONS_GHC -Wno-orphans -dcore-lint #-} +{-# OPTIONS_GHC -fdefer-type-errors -Wno-deferred-type-errors #-} +{-# OPTIONS_GHC -fplugin Data.TypeLevel.List.Solver #-} + +module Data.TypeLevel.ListSpec.Cases where + +import Data.Constraint (Constraint, Dict (Dict)) +import Data.DList qualified as DL +import Data.Foldable (Foldable (toList)) +import Data.Functor.Identity +import Data.Kind (Type) +import Data.Proxy +import Data.Type.Equality ((:~:) (..)) +import Data.TypeLevel.Function +import Data.TypeLevel.Known +import Data.TypeLevel.List +import Data.TypeLevel.ListSpec.Undeferred (BothTypeable) +import Data.TypeLevel.Maybe (FromMaybe) +import Data.TypeLevel.Ord +import Data.TypeLevel.OrdMap (AllOM, EntryC, (:::)) +import Data.TypeLevel.OrdMap qualified as OM +import Data.Typeable (typeRep) +import GHC.TypeLits (KnownSymbol, symbolVal) +import Helpers +import Test.Inspection qualified as IT +import Type.Reflection (SomeTypeRep (..)) + +mapLen :: forall as proxy. (KnownTyList as) => proxy as -> Natural +mapLen _ = natVal @(Length (Map 'Just as)) Proxy + +illegalMapLen :: forall as proxy. (KnownTyList as) => proxy as -> Natural +illegalMapLen _ = natVal @(Length ('Nothing ': (Map 'Just as))) Proxy + +trivialSort_def :: + forall (as :: [Nat]) proxy. + proxy as -> + Dict (SortedBy Compare2 (MapApply Id1 (SortBy Compare2 as))) +trivialSort_def _ = + trivialSorted + (Proxy @Compare2) + (Proxy @(MapApply Id1 (SortBy Compare2 as))) + +trivialSort_def_inst :: Dict (SortedBy Compare2 (MapApply Id1 (SortBy Compare2 '[1, 2, 3]))) +trivialSort_def_inst = trivialSort_def (Proxy @'[1, 2, 3]) + +trivialSort :: IT.Result +trivialSort = $(withNoTypeError 'trivialSort_def_inst) + +data NoCompare :: Nat ~> Nat ~> Ordering + +nontrivialSort_def :: + forall (as :: [Nat]) proxy. + proxy as -> + Dict (SortedBy NoCompare (MapApply Id1 (SortBy Compare2 as))) +nontrivialSort_def _ = + trivialSorted + (Proxy @NoCompare) + (Proxy @(MapApply Id1 (SortBy Compare2 as))) + +nontrivialSort_def_inst :: Dict (SortedBy Compare2 '[1, 2, 3]) +nontrivialSort_def_inst = nontrivialSort_def (Proxy @'[1, 2, 3]) + +nontrivialSort :: IT.Result +nontrivialSort = $(withNoTypeError 'nontrivialSort_def_inst) + +nontrivialSort2_def :: + forall (as :: [Nat]) proxy. + proxy as -> + Dict (SortedBy NoCompare (SortBy Compare2 as)) +nontrivialSort2_def _ = + trivialSorted + (Proxy @NoCompare) + (Proxy @(SortBy Compare2 as)) + +nontrivialSort2_def_inst :: Dict (SortedBy Compare2 '[1, 2, 3]) +nontrivialSort2_def_inst = nontrivialSort_def (Proxy @'[1, 2, 3]) + +nontrivialSort2 :: IT.Result +nontrivialSort2 = $(withNoTypeError 'nontrivialSort2_def_inst) + +trivialSorted :: + forall cmp as proxy proxy'. + (SortedBy cmp as) => + proxy cmp -> + proxy' as -> + Dict (SortedBy cmp as) +trivialSorted _ _ = Dict + +showOrdMapType :: + forall dic proxy. + (Known dic, OM.AllOM BothTypeable dic) => + proxy dic -> + [(SomeTypeRep, SomeTypeRep, Natural)] +showOrdMapType _ = + toList @DL.DList $ + OM.foldMapOrdMap + @dic + ( \pk pl pn -> + DL.singleton + ( typeRep pk + , typeRep pl + , natVal pn + ) + ) + +type ShownDict = OM.FromList '[Int ::: 5, Bool ::: 1, Maybe () ::: 0] + +shownOrdMap :: [(SomeTypeRep, SomeTypeRep, Natural)] +shownOrdMap = showOrdMapType (Proxy @ShownDict) + +sortLabelTypeable :: + forall xs proxy. + ( Known xs + , All KnownSymbol xs + , OM.SortableList xs + ) => + proxy xs -> + [(String, Natural)] +sortLabelTypeable _ = OM.withAllConstMap @_ @KnownSymbol @xs $ + toList @DL.DList $ + OM.foldMapOrdMap @(OM.ConstMap xs) $ + \pk _ pn -> DL.singleton (symbolVal pk, natVal pn) + +appAssoc :: + (xs ++ ys) ++ zs :~: xs ++ (ys ++ zs) +appAssoc = Refl + +appFalseAssoc :: + (xs ++ ys) ++ zs :~: xs ++ (zs ++ ys) +appFalseAssoc = Refl + +mapApplyDistrib :: + proxy xs -> + proxy' ys -> + proxy'' x -> + MapApply Just1 (xs ++ (x ': ys)) + :~: (MapApply Just1 xs ++ ('Just x ': MapApply Just1 ys)) +mapApplyDistrib _ _ _ = Refl + +mapApplyFalseDistrib :: + proxy xs -> + proxy' ys -> + proxy'' x -> + MapApply Just1 (xs ++ (x ': ys)) + :~: (MapApply Just1 xs ++ ('Nothing ': MapApply Just1 ys)) +mapApplyFalseDistrib _ _ _ = Refl + +data Just1 :: k ~> Maybe k + +type instance Apply Just1 a = 'Just a + +showMap :: + forall x h xs. + (KnownTyList xs, All Show (Map h xs), Member x xs) => + Proxy xs -> + h x -> + String +showMap _ = show + +myElimFromAll :: + forall k (c :: k -> Constraint) (xs :: [k]) (x :: k). + (KnownTyList (xs :: [k]), All c xs, Member x xs) => + Proxy c -> + Proxy x -> + Proxy xs -> + Dict (c x) +myElimFromAll _ _ _ = Dict @(c x) + +data Right1 :: k ~> Either () k + +type instance Apply Right1 a = 'Right a + +splitAtApply :: + Proxy a -> + Proxy b -> + Proxy xs -> + ( Take + (Index ('Right b) (MapApply Right1 xs)) + (MapApply Just1 xs) + ++ (a : Drop (Index ('Right b) (MapApply Right1 xs) + 1) (MapApply Just1 xs)) + ) + :~: ( MapApply Just1 (Take (Index ('Right b) (MapApply Right1 xs)) xs) + ++ (a : MapApply Just1 (Drop (Index ('Right b) (MapApply Right1 xs) + 1) xs)) + ) +splitAtApply _ _ _ = Refl + +instance Monotone Identity Compare2 Compare2 + +sortedSort :: + forall xs. + (KnownTyList xs) => + Dict (SortedBy Compare2 (Map Identity (SortBy Compare2 xs))) +sortedSort = Dict + +trivialOM :: + (OM.AllOM c dic, OM.Member l dic) => + Proxy c -> + Proxy dic -> + Proxy l -> + Dict (c l (OM.Lookup' l dic)) +trivialOM _ _ _ = Dict + +class C (k :: Type) where + unC :: Proxy k -> String + +instance C Int where + unC _ = "Int" + +instance C Bool where + unC _ = "Bool" + +elimAllOMLookup :: + forall (om :: OM.OrdMap Bool Type) (def :: Type) (x :: Bool). + (AllOM (EntryC C) (om :: OM.OrdMap Bool Type), C def, Known x) => + Proxy x -> + Proxy om -> + Proxy def -> + String +elimAllOMLookup _ _ _ = + unC $ Proxy @(FromMaybe def (OM.Lookup x om)) diff --git a/elgenerics-known/test/Data/TypeLevel/ListSpec/Undeferred.hs b/elgenerics-known/test/Data/TypeLevel/ListSpec/Undeferred.hs new file mode 100644 index 0000000..01868c9 --- /dev/null +++ b/elgenerics-known/test/Data/TypeLevel/ListSpec/Undeferred.hs @@ -0,0 +1,19 @@ +{-# LANGUAGE DataKinds #-} + +module Data.TypeLevel.ListSpec.Undeferred where + +import Data.DList qualified as DL +import Data.Proxy (Proxy) +import Data.TypeLevel.List +import Data.Typeable (typeRep) +import Type.Reflection (SomeTypeRep, Typeable) + +class (Typeable l, Typeable r) => BothTypeable l r + +instance (Typeable l, Typeable r) => BothTypeable l r + +typeRepList :: + (All Typeable xs, KnownTyList xs) => + Proxy xs -> + [SomeTypeRep] +typeRepList = DL.toList . foldMapTyListC @Typeable (DL.singleton . typeRep) diff --git a/elgenerics-known/test/Data/TypeLevel/Nat/Definitions.hs b/elgenerics-known/test/Data/TypeLevel/Nat/Definitions.hs new file mode 100644 index 0000000..6380331 --- /dev/null +++ b/elgenerics-known/test/Data/TypeLevel/Nat/Definitions.hs @@ -0,0 +1,23 @@ +{-# LANGUAGE DataKinds #-} +{-# LANGUAGE ExplicitNamespaces #-} +{-# LANGUAGE GADTs #-} +{-# LANGUAGE QuasiQuotes #-} +{-# LANGUAGE ViewPatterns #-} +{-# OPTIONS_GHC -O #-} + +module Data.TypeLevel.Nat.Definitions where + +import Data.Proxy (Proxy) +import Data.TypeLevel.Known +import Data.TypeLevel.Nat (tnat) +import GHC.TypeLits (KnownNat, type (<=)) +import Numeric.Natural (Natural) + +branchTNat :: (KnownNat n, n <= 3) => Proxy n -> Natural +{-# INLINE branchTNat #-} +branchTNat (_ :: Proxy n) = case sKnownVal' @n of + [tnat|0|] -> 0 + [tnat|1|] -> 1 + [tnat|2|] -> 2 + [tnat|3|] -> 3 + _ -> error "Could not happen!" diff --git a/elgenerics-known/test/Data/TypeLevel/NatSpec.hs b/elgenerics-known/test/Data/TypeLevel/NatSpec.hs new file mode 100644 index 0000000..1098b09 --- /dev/null +++ b/elgenerics-known/test/Data/TypeLevel/NatSpec.hs @@ -0,0 +1,33 @@ +{-# LANGUAGE DataKinds #-} +{-# LANGUAGE TemplateHaskell #-} +{-# OPTIONS_GHC -O -dsuppress-all -dno-suppress-type-signatures #-} + +module Data.TypeLevel.NatSpec where + +import Data.Proxy (Proxy) +import Data.TypeLevel.Nat.Definitions +import Numeric.Natural (Natural) +import Test.Tasty (TestTree, testGroup) +import Test.Tasty.ExpectedFailure (ignoreTestBecause) +import Test.Tasty.Inspection + +branchTNat0 :: Proxy 0 -> Natural +branchTNat0 = branchTNat + +proxy0 :: Proxy 0 -> Natural +proxy0 _ = 0 + +branchTNat1 :: Proxy 1 -> Natural +branchTNat1 = branchTNat + +proxy1 :: Proxy 1 -> Natural +proxy1 _ = 1 + +test_tnat :: TestTree +test_tnat = + ignoreTestBecause "These tests fails with FAST build, even with module option -O" $ + testGroup + "tnat erases concrete" + [ $(inspectTest $ 'branchTNat0 ==- 'proxy0) + , $(inspectTest $ 'branchTNat1 ==- 'proxy1) + ] diff --git a/elgenerics-known/test/Data/TypeLevel/OrdMapSpec.hs b/elgenerics-known/test/Data/TypeLevel/OrdMapSpec.hs new file mode 100644 index 0000000..d02bfac --- /dev/null +++ b/elgenerics-known/test/Data/TypeLevel/OrdMapSpec.hs @@ -0,0 +1,167 @@ +{-# LANGUAGE AllowAmbiguousTypes #-} +{-# LANGUAGE DataKinds #-} +{-# LANGUAGE DeriveAnyClass #-} +{-# LANGUAGE DerivingStrategies #-} +{-# LANGUAGE DerivingVia #-} +{-# LANGUAGE GADTs #-} +{-# LANGUAGE LambdaCase #-} +{-# LANGUAGE OverloadedLabels #-} +{-# LANGUAGE PartialTypeSignatures #-} +{-# LANGUAGE RecordWildCards #-} +{-# LANGUAGE TypeFamilies #-} +{-# LANGUAGE UndecidableInstances #-} +{-# OPTIONS_GHC -fplugin Data.TypeLevel.List.Solver #-} + +module Data.TypeLevel.OrdMapSpec where + +import Data.Proxy +import Data.TypeLevel.OrdMap +import Data.TypeLevel.OrdMapSpec.Cases +import Data.TypeLevel.OrdMapSpec.Failures +import GHC.TypeNats +import Helpers (expectInspectionFail, testInspection) +import Test.Tasty +import Test.Tasty.HUnit +import Type.Reflection + +type TypeLabelledFields = + FromList + '[ String ::: 2 + , Int ::: 4 + , Maybe Bool ::: 3 + , () ::: 0 + , Ordering ::: 5 + ] + +infixr 9 <: + +type (<:) x xs = Insert (Label x) (Entry x) xs + +type RawTypeFields = + ( (Ordering ::: 5) + <: (Maybe Bool ::: 3) + <: (Int ::: 4) + <: (String ::: 2) + <: Singleton () 0 + ) + +test_foldMapOrdMapC :: TestTree +test_foldMapOrdMapC = + testGroup + "foldMapOrdMapC" + [ testCase "TypeLabelledFields" $ + foldMapOrdMapC @(LabelC Typeable) + @TypeLabelledFields + ( \(Proxy :: Proxy ty) _ _ -> + [show $ typeRep @ty] + ) + @?= [ show (typeRep @()) + , show (typeRep @Int) + , show (typeRep @Ordering) + , show (typeRep @(Maybe Bool)) + , show (typeRep @String) + ] + , testCase "RawTypeFields" $ + foldMapOrdMapC @(LabelC Typeable) + @RawTypeFields + ( \(Proxy :: Proxy ty) _ _ -> + [show $ typeRep @ty] + ) + @?= [ show (typeRep @()) + , show (typeRep @Int) + , show (typeRep @Ordering) + , show (typeRep @(Maybe Bool)) + , show (typeRep @String) + ] + ] + +test_foldMapOrdMap :: TestTree +test_foldMapOrdMap = + testGroup + "foldMapOrdMap" + [ testCase "TypeLabelledFields" $ + foldMapOrdMap + @TypeLabelledFields + (\_ _ n -> [natVal n]) + @?= [0 .. (4 :: Natural)] + , testCase "RawTypeFields" $ + foldMapOrdMap + @RawTypeFields + (\_ _ n -> [natVal n]) + @?= [0 .. (4 :: Natural)] + ] + +test_foldMapOrdMapC' :: TestTree +test_foldMapOrdMapC' = + testGroup + "foldMapOrdMapC'" + [ testCase "TypeLabelledFields" $ + foldMapOrdMapC' @(LabelC Typeable) + @TypeLabelledFields + ( \(Proxy :: Proxy ty) _ _ -> + [show $ typeRep @ty] + ) + @?= [ show (typeRep @()) + , show (typeRep @Int) + , show (typeRep @Ordering) + , show (typeRep @(Maybe Bool)) + , show (typeRep @String) + ] + , testCase "RawTypeFields" $ + foldMapOrdMapC' @(LabelC Typeable) + @RawTypeFields + ( \(Proxy :: Proxy ty) _ _ -> + [show $ typeRep @ty] + ) + @?= [ show (typeRep @()) + , show (typeRep @Int) + , show (typeRep @Ordering) + , show (typeRep @(Maybe Bool)) + , show (typeRep @String) + ] + ] + +test_foldMapOrdMap' :: TestTree +test_foldMapOrdMap' = + testGroup + "foldMapOrdMap'" + [ testCase "TypeLabelledFields" $ + foldMapOrdMap' + @TypeLabelledFields + (\_ _ n -> [natVal n]) + @?= [0 .. (4 :: Natural)] + , testCase "RawTypeFields" $ + foldMapOrdMap' + @RawTypeFields + (\_ _ n -> [natVal n]) + @?= [0 .. (4 :: Natural)] + ] + +test_FromAscList :: TestTree +test_FromAscList = + testGroup + "FromAscList" + [ expectInspectionFail "should reject unsorted list" unsortedFromAscList + ] + +test_FromList :: TestTree +test_FromList = + testGroup + "FromList" + [ testGroup + "should generate valid Red-Black tree" + [ testInspection "[20, 30, 40, 50, 10, 2, 0, 1]" test011 + , testInspection "[1,2,3,4,0]" test01 + , testInspection "Insert 2 [0,1]" test02 + , testInspection "Insert 2 [0]" test03 + , testInspection "[1, 0]" test04 + ] + ] + +test_ValidRBTree :: TestTree +test_ValidRBTree = + testGroup + "ValidRBTree" + [ expectInspectionFail "should reject unsorted RBTree" unsortedValidRBTree + , expectInspectionFail "should reject red-red RBTree" redRedInvalid + ] diff --git a/elgenerics-known/test/Data/TypeLevel/OrdMapSpec/Cases.hs b/elgenerics-known/test/Data/TypeLevel/OrdMapSpec/Cases.hs new file mode 100644 index 0000000..32984f8 --- /dev/null +++ b/elgenerics-known/test/Data/TypeLevel/OrdMapSpec/Cases.hs @@ -0,0 +1,72 @@ +{-# LANGUAGE DataKinds #-} +{-# LANGUAGE TemplateHaskell #-} + +module Data.TypeLevel.OrdMapSpec.Cases where + +import Data.Constraint (Dict (Dict)) +import Data.TypeLevel.OrdMap +import Helpers (withNoTypeError) +import Test.Inspection qualified as IT + +test011_def :: + Dict + ( ValidRBTree + ( FromList + '[ 20 ::: Int + , 30 ::: Int + , 40 ::: Int + , 50 ::: Int + , 10 ::: Int + , 2 ::: Int + , 0 ::: Int + , 1 ::: Int + ] + ) + ) +test011_def = Dict + +test011 :: IT.Result +test011 = $(withNoTypeError 'test011_def) + +test01_def :: + Dict + ( ValidRBTree + ( FromList + '[ 1 ::: Int + , 2 ::: Int + , 3 ::: Int + , 4 ::: Int + , 0 ::: Int + ] + ) + ) +test01_def = Dict + +test01 :: IT.Result +test01 = $(withNoTypeError 'test01_def) + +test02_def :: + Dict + ( ValidRBTree + (Insert 2 Int (FromList [0 ::: Int, 1 ::: Int])) + ) +test02_def = Dict + +test02 :: IT.Result +test02 = $(withNoTypeError 'test02_def) + +test03_def :: + Dict + ( ValidRBTree + (Insert 2 Int (FromList '[0 ::: Int])) + ) +test03_def = Dict + +test03 :: IT.Result +test03 = $(withNoTypeError 'test03_def) + +test04_def :: Dict (ValidRBTree (FromList '[1 ::: Int, 0 ::: Int])) +test04_def = Dict + +test04 :: IT.Result +test04 = $(withNoTypeError 'test04_def) diff --git a/elgenerics-known/test/Data/TypeLevel/OrdMapSpec/Failures.hs b/elgenerics-known/test/Data/TypeLevel/OrdMapSpec/Failures.hs new file mode 100644 index 0000000..3d35545 --- /dev/null +++ b/elgenerics-known/test/Data/TypeLevel/OrdMapSpec/Failures.hs @@ -0,0 +1,35 @@ +{-# LANGUAGE DataKinds #-} +{-# LANGUAGE TemplateHaskell #-} +{-# OPTIONS_GHC -fdefer-type-errors -Wno-deferred-type-errors #-} + +module Data.TypeLevel.OrdMapSpec.Failures where + +import Data.Constraint (Dict (Dict)) +import Data.TypeLevel.Known +import Data.TypeLevel.OrdMap +import Data.TypeLevel.OrdMap.Internal (MkRankT) +import Helpers (withNoTypeError) +import Test.Inspection + +unsortedValidRBTree_def :: + Dict (ValidRBTree (UnsafeFromAscList '[3 ::: Int, 42 ::: Bool, 5 ::: ()])) +unsortedValidRBTree_def = Dict + +unsortedValidRBTree :: Result +unsortedValidRBTree = + $(withNoTypeError 'unsortedValidRBTree_def) + +unsortedFromAscList_def :: + Sing (FromAscList '[3 ::: Int, 42 ::: Bool, 5 ::: ()]) +unsortedFromAscList_def = sKnownVal' + +unsortedFromAscList :: Result +unsortedFromAscList = + $(withNoTypeError 'unsortedFromAscList_def) + +redRedInvalid_def :: + Dict (ValidRBTree (Branch R 2 (MkRankT 1) (Branch R 1 (MkRankT 1) Leaf 0 Int Leaf) 1 Bool Leaf)) +redRedInvalid_def = Dict + +redRedInvalid :: Result +redRedInvalid = $(withNoTypeError 'redRedInvalid_def) diff --git a/elgenerics-known/test/Helpers.hs b/elgenerics-known/test/Helpers.hs new file mode 100644 index 0000000..c2de34c --- /dev/null +++ b/elgenerics-known/test/Helpers.hs @@ -0,0 +1,62 @@ +{-# LANGUAGE TemplateHaskell #-} + +module Helpers ( + shouldThrowTypeError, + shouldNotThrowTypeError, + testInspection, + expectInspectionFail, + withNoTypeError, +) where + +import Control.DeepSeq (NFData, force) +import Control.Exception ( + TypeError (TypeError), + evaluate, + try, + ) +import Control.Exception.Base (typeError) +import Language.Haskell.TH (ExpQ) +import Language.Haskell.TH.Syntax (Name) +import Test.Inspection (doesNotUse, inspectTest) +import Test.Inspection qualified as IT +import Test.Tasty (TestTree) +import Test.Tasty.HUnit (Assertion, assertFailure, testCase) + +shouldThrowTypeError :: (Show a, NFData a) => a -> Assertion +shouldThrowTypeError inp = do + eith <- try $ evaluate $ force inp + case eith of + Left TypeError {} -> pure () + Right a -> + assertFailure $ + "Deferred type error expected, but got a value: " + <> show a + +shouldNotThrowTypeError :: (Show a, NFData a) => a -> Assertion +shouldNotThrowTypeError inp = do + eith <- try $ evaluate $ force inp + case eith of + Left te@TypeError {} -> + assertFailure $ + "No type error expected, but got: " <> show te + Right {} -> pure () + +testInspection :: + String -> IT.Result -> TestTree +testInspection lab resl = testCase lab $ + case resl of + IT.Success {} -> pure () + IT.Failure msg -> assertFailure msg + +expectInspectionFail :: + String -> IT.Result -> TestTree +expectInspectionFail lab resl = testCase lab $ + case resl of + IT.Success msg -> + assertFailure $ + "Inspection expected to fail, but succeeded with the following msg: " + <> msg + IT.Failure {} -> pure () + +withNoTypeError :: Name -> ExpQ +withNoTypeError n = inspectTest $ n `doesNotUse` 'typeError diff --git a/elgenerics-known/test/Spec.hs b/elgenerics-known/test/Spec.hs new file mode 100644 index 0000000..327adf4 --- /dev/null +++ b/elgenerics-known/test/Spec.hs @@ -0,0 +1 @@ +{-# OPTIONS_GHC -F -pgmF tasty-discover -optF --tree-display #-} diff --git a/fourmolu.yaml b/fourmolu.yaml new file mode 100644 index 0000000..16d98c1 --- /dev/null +++ b/fourmolu.yaml @@ -0,0 +1,8 @@ +indentation: 2 +comma-style: leading +record-brace-space: true +indent-wheres: true +diff-friendly-import-export: false +respectful: false +haddock-style: multi-line +newlines-between-decls: 1