Showing preview only (1,717K chars total). Download the full file or copy to clipboard to get everything.
Repository: jwiegley/hnix
Branch: master
Commit: b2ac3b41a360
Files: 404
Total size: 1.6 MB
Directory structure:
gitextract_q_z2xg1p/
├── .fourmolu.yaml
├── .github/
│ ├── dependabot.yml
│ └── workflows/
│ ├── Cabal-Linux.yml
│ ├── HLint.yml
│ ├── On-Release-Cabal-Linux.yml
│ ├── On-Release-Nixpkgs-integration.yml
│ └── Quality.yml
├── .gitignore
├── .gitmodules
├── .hlint.yaml
├── CLAUDE.md
├── CODEOWNERS
├── ChangeLog.md
├── LICENSE.md
├── License
├── Makefile
├── ReadMe.md
├── benchmarks/
│ ├── Main.hs
│ └── ParserBench.hs
├── brittany.yaml
├── build.sh
├── cabal.project
├── data/
│ ├── let-comments-multiline.nix
│ ├── let-comments.nix
│ ├── let.nix
│ ├── nix/
│ │ ├── README.md
│ │ └── tests/
│ │ └── lang/
│ │ ├── binary-data
│ │ ├── data
│ │ ├── dir1/
│ │ │ └── a.nix
│ │ ├── dir2/
│ │ │ ├── a.nix
│ │ │ └── b.nix
│ │ ├── dir3/
│ │ │ ├── a.nix
│ │ │ ├── b.nix
│ │ │ └── c.nix
│ │ ├── dir4/
│ │ │ ├── a.nix
│ │ │ └── c.nix
│ │ ├── eval-fail-abort.nix
│ │ ├── eval-fail-assert.nix
│ │ ├── eval-fail-bad-antiquote-1.nix
│ │ ├── eval-fail-bad-antiquote-2.nix
│ │ ├── eval-fail-bad-antiquote-3.nix
│ │ ├── eval-fail-blackhole.nix
│ │ ├── eval-fail-deepseq.nix
│ │ ├── eval-fail-hashfile-missing.nix
│ │ ├── eval-fail-missing-arg.nix
│ │ ├── eval-fail-nonexist-path.nix
│ │ ├── eval-fail-path-slash.nix
│ │ ├── eval-fail-remove.nix
│ │ ├── eval-fail-scope-5.nix
│ │ ├── eval-fail-seq.nix
│ │ ├── eval-fail-substring.nix
│ │ ├── eval-fail-to-path.nix
│ │ ├── eval-fail-undeclared-arg.nix
│ │ ├── eval-okay-any-all.exp
│ │ ├── eval-okay-any-all.nix
│ │ ├── eval-okay-arithmetic.exp
│ │ ├── eval-okay-arithmetic.nix
│ │ ├── eval-okay-attrnames.exp
│ │ ├── eval-okay-attrnames.nix
│ │ ├── eval-okay-attrs.exp
│ │ ├── eval-okay-attrs.nix
│ │ ├── eval-okay-attrs2.exp
│ │ ├── eval-okay-attrs2.nix
│ │ ├── eval-okay-attrs3.exp
│ │ ├── eval-okay-attrs3.nix
│ │ ├── eval-okay-attrs4.exp
│ │ ├── eval-okay-attrs4.nix
│ │ ├── eval-okay-attrs5.exp
│ │ ├── eval-okay-attrs5.nix
│ │ ├── eval-okay-attrs6.exp
│ │ ├── eval-okay-attrs6.nix
│ │ ├── eval-okay-autoargs.exp
│ │ ├── eval-okay-autoargs.flags
│ │ ├── eval-okay-autoargs.nix
│ │ ├── eval-okay-backslash-newline-1.exp
│ │ ├── eval-okay-backslash-newline-1.nix
│ │ ├── eval-okay-backslash-newline-2.exp
│ │ ├── eval-okay-backslash-newline-2.nix
│ │ ├── eval-okay-builtins-add.exp
│ │ ├── eval-okay-builtins-add.nix
│ │ ├── eval-okay-builtins.exp
│ │ ├── eval-okay-builtins.nix
│ │ ├── eval-okay-callable-attrs.exp
│ │ ├── eval-okay-callable-attrs.nix
│ │ ├── eval-okay-catattrs.exp
│ │ ├── eval-okay-catattrs.nix
│ │ ├── eval-okay-closure.exp.xml
│ │ ├── eval-okay-closure.nix
│ │ ├── eval-okay-comments.exp
│ │ ├── eval-okay-comments.nix
│ │ ├── eval-okay-concat.exp
│ │ ├── eval-okay-concat.nix
│ │ ├── eval-okay-concatmap.exp
│ │ ├── eval-okay-concatmap.nix
│ │ ├── eval-okay-concatstringssep.exp
│ │ ├── eval-okay-concatstringssep.nix
│ │ ├── eval-okay-context-introspection.exp
│ │ ├── eval-okay-context-introspection.nix
│ │ ├── eval-okay-context.exp
│ │ ├── eval-okay-context.nix
│ │ ├── eval-okay-curpos.exp
│ │ ├── eval-okay-curpos.nix
│ │ ├── eval-okay-deepseq.exp
│ │ ├── eval-okay-deepseq.nix
│ │ ├── eval-okay-delayed-with-inherit.exp
│ │ ├── eval-okay-delayed-with-inherit.nix
│ │ ├── eval-okay-delayed-with.exp
│ │ ├── eval-okay-delayed-with.nix
│ │ ├── eval-okay-dynamic-attrs-2.exp
│ │ ├── eval-okay-dynamic-attrs-2.nix
│ │ ├── eval-okay-dynamic-attrs-bare.exp
│ │ ├── eval-okay-dynamic-attrs-bare.nix
│ │ ├── eval-okay-dynamic-attrs.exp
│ │ ├── eval-okay-dynamic-attrs.nix
│ │ ├── eval-okay-elem.exp
│ │ ├── eval-okay-elem.nix
│ │ ├── eval-okay-empty-args.exp
│ │ ├── eval-okay-empty-args.nix
│ │ ├── eval-okay-eq-derivations.exp
│ │ ├── eval-okay-eq-derivations.nix
│ │ ├── eval-okay-eq.exp.disabled
│ │ ├── eval-okay-eq.nix
│ │ ├── eval-okay-filter.exp
│ │ ├── eval-okay-filter.nix
│ │ ├── eval-okay-flatten.exp
│ │ ├── eval-okay-flatten.nix
│ │ ├── eval-okay-float.exp
│ │ ├── eval-okay-float.nix
│ │ ├── eval-okay-floor-ceil.exp
│ │ ├── eval-okay-floor-ceil.nix
│ │ ├── eval-okay-foldlStrict.exp
│ │ ├── eval-okay-foldlStrict.nix
│ │ ├── eval-okay-fromTOML.exp
│ │ ├── eval-okay-fromTOML.nix
│ │ ├── eval-okay-fromjson-escapes.exp
│ │ ├── eval-okay-fromjson-escapes.nix
│ │ ├── eval-okay-fromjson.exp
│ │ ├── eval-okay-fromjson.nix
│ │ ├── eval-okay-functionargs.exp.xml
│ │ ├── eval-okay-functionargs.nix
│ │ ├── eval-okay-getattrpos-functionargs.exp
│ │ ├── eval-okay-getattrpos-functionargs.nix
│ │ ├── eval-okay-getattrpos-undefined.exp
│ │ ├── eval-okay-getattrpos-undefined.nix
│ │ ├── eval-okay-getattrpos.exp
│ │ ├── eval-okay-getattrpos.nix
│ │ ├── eval-okay-getenv.exp
│ │ ├── eval-okay-getenv.nix
│ │ ├── eval-okay-hash.exp
│ │ ├── eval-okay-hashfile.exp
│ │ ├── eval-okay-hashfile.nix
│ │ ├── eval-okay-hashstring.exp
│ │ ├── eval-okay-hashstring.nix
│ │ ├── eval-okay-if.exp
│ │ ├── eval-okay-if.nix
│ │ ├── eval-okay-import.exp
│ │ ├── eval-okay-import.nix
│ │ ├── eval-okay-ind-string.exp
│ │ ├── eval-okay-ind-string.nix
│ │ ├── eval-okay-let.exp
│ │ ├── eval-okay-let.nix
│ │ ├── eval-okay-list.exp
│ │ ├── eval-okay-list.nix
│ │ ├── eval-okay-listtoattrs.exp
│ │ ├── eval-okay-listtoattrs.nix
│ │ ├── eval-okay-logic.exp
│ │ ├── eval-okay-logic.nix
│ │ ├── eval-okay-map.exp
│ │ ├── eval-okay-map.nix
│ │ ├── eval-okay-mapattrs.exp
│ │ ├── eval-okay-mapattrs.nix
│ │ ├── eval-okay-nested-with.exp
│ │ ├── eval-okay-nested-with.nix
│ │ ├── eval-okay-new-let.exp
│ │ ├── eval-okay-new-let.nix
│ │ ├── eval-okay-null-dynamic-attrs.exp
│ │ ├── eval-okay-null-dynamic-attrs.nix
│ │ ├── eval-okay-overrides.exp
│ │ ├── eval-okay-overrides.nix
│ │ ├── eval-okay-partition.exp
│ │ ├── eval-okay-partition.nix
│ │ ├── eval-okay-path-antiquotation.nix
│ │ ├── eval-okay-path.nix
│ │ ├── eval-okay-pathexists.exp
│ │ ├── eval-okay-pathexists.nix
│ │ ├── eval-okay-patterns.exp
│ │ ├── eval-okay-patterns.nix
│ │ ├── eval-okay-readDir.exp
│ │ ├── eval-okay-readDir.nix
│ │ ├── eval-okay-readfile.exp
│ │ ├── eval-okay-readfile.nix
│ │ ├── eval-okay-redefine-builtin.exp
│ │ ├── eval-okay-redefine-builtin.nix
│ │ ├── eval-okay-regex-match.exp
│ │ ├── eval-okay-regex-match.nix
│ │ ├── eval-okay-regex-split.exp
│ │ ├── eval-okay-regex-split.nix
│ │ ├── eval-okay-remove.exp
│ │ ├── eval-okay-remove.nix
│ │ ├── eval-okay-replacestrings.exp
│ │ ├── eval-okay-replacestrings.nix
│ │ ├── eval-okay-scope-1.exp
│ │ ├── eval-okay-scope-1.nix
│ │ ├── eval-okay-scope-2.exp
│ │ ├── eval-okay-scope-2.nix
│ │ ├── eval-okay-scope-3.exp
│ │ ├── eval-okay-scope-3.nix
│ │ ├── eval-okay-scope-4.exp
│ │ ├── eval-okay-scope-4.nix
│ │ ├── eval-okay-scope-6.exp
│ │ ├── eval-okay-scope-6.nix
│ │ ├── eval-okay-scope-7.exp
│ │ ├── eval-okay-scope-7.nix
│ │ ├── eval-okay-search-path.exp
│ │ ├── eval-okay-search-path.flags
│ │ ├── eval-okay-search-path.nix
│ │ ├── eval-okay-seq.exp
│ │ ├── eval-okay-seq.nix
│ │ ├── eval-okay-sort.exp
│ │ ├── eval-okay-sort.nix
│ │ ├── eval-okay-splitversion.exp
│ │ ├── eval-okay-splitversion.nix
│ │ ├── eval-okay-string.exp
│ │ ├── eval-okay-string.nix
│ │ ├── eval-okay-strings-as-attrs-names.exp
│ │ ├── eval-okay-strings-as-attrs-names.nix
│ │ ├── eval-okay-substring.exp
│ │ ├── eval-okay-substring.nix
│ │ ├── eval-okay-tail-call-1.exp-disabled
│ │ ├── eval-okay-tail-call-1.nix
│ │ ├── eval-okay-tojson.exp
│ │ ├── eval-okay-tojson.nix
│ │ ├── eval-okay-toxml.exp
│ │ ├── eval-okay-toxml.nix
│ │ ├── eval-okay-toxml2.exp
│ │ ├── eval-okay-toxml2.nix
│ │ ├── eval-okay-tryeval.exp
│ │ ├── eval-okay-tryeval.nix
│ │ ├── eval-okay-types.exp
│ │ ├── eval-okay-types.nix
│ │ ├── eval-okay-versions.exp
│ │ ├── eval-okay-versions.nix
│ │ ├── eval-okay-with.exp
│ │ ├── eval-okay-with.nix
│ │ ├── eval-okay-xml.exp.xml
│ │ ├── eval-okay-xml.nix
│ │ ├── imported.nix
│ │ ├── imported2.nix
│ │ ├── lib.nix
│ │ ├── parse-fail-dup-attrs-1.nix
│ │ ├── parse-fail-dup-attrs-2.nix
│ │ ├── parse-fail-dup-attrs-3.nix
│ │ ├── parse-fail-dup-attrs-4.nix
│ │ ├── parse-fail-dup-attrs-7.nix
│ │ ├── parse-fail-dup-formals.nix
│ │ ├── parse-fail-mixed-nested-attrs1.nix
│ │ ├── parse-fail-mixed-nested-attrs2.nix
│ │ ├── parse-fail-patterns-1.nix
│ │ ├── parse-fail-regression-20060610.nix
│ │ ├── parse-fail-uft8.nix
│ │ ├── parse-fail-undef-var-2.nix
│ │ ├── parse-fail-undef-var.nix
│ │ ├── parse-okay-1.nix
│ │ ├── parse-okay-crlf.nix
│ │ ├── parse-okay-dup-attrs-5.nix
│ │ ├── parse-okay-dup-attrs-6.nix
│ │ ├── parse-okay-mixed-nested-attrs-1.nix
│ │ ├── parse-okay-mixed-nested-attrs-2.nix
│ │ ├── parse-okay-mixed-nested-attrs-3.nix
│ │ ├── parse-okay-regression-20041027.nix
│ │ ├── parse-okay-regression-751.nix
│ │ ├── parse-okay-subversion.nix
│ │ ├── parse-okay-url.nix
│ │ └── readDir/
│ │ ├── bar
│ │ └── foo/
│ │ └── git-hates-directories
│ ├── nixpkgs-all-packages-pretty.nix
│ ├── nixpkgs-all-packages.nix
│ ├── simple-pretty.nix
│ └── simple.nix
├── default.nix
├── doc/
│ ├── grammar.y
│ └── lexer.l
├── flake.nix
├── hnix.cabal
├── hydra.json
├── jobsets.nix
├── lefthook.yml
├── main/
│ ├── Main.hs
│ └── Repl.hs
├── release.nix
├── shell.nix
├── src/
│ ├── Nix/
│ │ ├── Atoms.hs
│ │ ├── Builtins.hs
│ │ ├── Cache.hs
│ │ ├── Cited/
│ │ │ └── Basic.hs
│ │ ├── Cited.hs
│ │ ├── Context.hs
│ │ ├── Convert.hs
│ │ ├── Effects/
│ │ │ ├── Basic.hs
│ │ │ └── Derivation.hs
│ │ ├── Effects.hs
│ │ ├── Eval.hs
│ │ ├── Exec.hs
│ │ ├── Expr/
│ │ │ ├── Shorthands.hs
│ │ │ ├── Strings.hs
│ │ │ ├── Types/
│ │ │ │ └── Annotated.hs
│ │ │ └── Types.hs
│ │ ├── Expr.hs
│ │ ├── Frames.hs
│ │ ├── Fresh/
│ │ │ └── Basic.hs
│ │ ├── Fresh.hs
│ │ ├── Json.hs
│ │ ├── Lint.hs
│ │ ├── Normal.hs
│ │ ├── Options/
│ │ │ └── Parser.hs
│ │ ├── Options.hs
│ │ ├── Parser.hs
│ │ ├── Prelude.hs
│ │ ├── Pretty.hs
│ │ ├── Reduce.hs
│ │ ├── Render/
│ │ │ └── Frame.hs
│ │ ├── Render.hs
│ │ ├── Scope.hs
│ │ ├── Standard.hs
│ │ ├── String/
│ │ │ └── Coerce.hs
│ │ ├── String.hs
│ │ ├── TH.hs
│ │ ├── Thunk/
│ │ │ └── Basic.hs
│ │ ├── Thunk.hs
│ │ ├── Type/
│ │ │ ├── Assumption.hs
│ │ │ ├── Env.hs
│ │ │ ├── Infer.hs
│ │ │ ├── LICENSE
│ │ │ └── Type.hs
│ │ ├── Unused.hs
│ │ ├── Utils/
│ │ │ └── Fix1.hs
│ │ ├── Utils.hs
│ │ ├── Value/
│ │ │ ├── Equal.hs
│ │ │ └── Monad.hs
│ │ ├── Value.hs
│ │ ├── Var.hs
│ │ └── XML.hs
│ └── Nix.hs
└── tests/
├── EvalTests.hs
├── Main.hs
├── NixLanguageTests.hs
├── ParserTests.hs
├── PrettyParseTests.hs
├── PrettyTests.hs
├── ReduceExprTests.hs
├── TestCommon.hs
├── eval-compare/
│ ├── builtins.appendContext.nix
│ ├── builtins.eq-bottom-00.nix
│ ├── builtins.fetchurl-01.nix
│ ├── builtins.fromJSON-01.nix
│ ├── builtins.getContext.nix
│ ├── builtins.lessThan-01.nix
│ ├── builtins.mapAttrs-01.nix
│ ├── builtins.pathExists.nix
│ ├── builtins.replaceStrings-01.nix
│ ├── builtins.split-01.nix
│ ├── builtins.split-02.nix
│ ├── builtins.split-03.nix
│ ├── builtins.split-04.nix
│ ├── builtins.string.store.nix
│ ├── builtins.toJSON.nix
│ ├── current-system.nix
│ ├── ellipsis.nix
│ ├── ind-string-01.nix
│ ├── ind-string-02.nix
│ ├── ind-string-03.nix
│ ├── ind-string-04.nix
│ ├── ind-string-05.nix
│ ├── ind-string-06.nix
│ ├── ind-string-07.nix
│ ├── ind-string-08.nix
│ ├── ind-string-09.nix
│ ├── ind-string-10.nix
│ ├── ind-string-11.nix
│ ├── ind-string-12.nix
│ ├── ind-string-13.nix
│ ├── ind-string-14.nix
│ ├── ind-string-15.nix
│ ├── ind-string-16.nix
│ ├── ind-string-17.nix
│ ├── ind-string-18.nix
│ ├── ind-string-19.nix
│ ├── paths-01.nix
│ └── placeholder.nix
└── files/
├── attrs.nix
├── callLibs.nix
├── eighty.nix
├── file.nix
├── file2.nix
├── findFile.nix
├── force.nix
├── goodbye.nix
├── hello.nix
├── hello2.nix
├── if-then.nix
├── lint.nix
├── loop.nix
├── test.nix
└── with.nix
================================================
FILE CONTENTS
================================================
================================================
FILE: .fourmolu.yaml
================================================
indentation: 2
column-limit: none
function-arrows: trailing
comma-style: leading
import-export-style: diff-friendly
indent-wheres: false
record-brace-space: false
newlines-between-decls: 1
haddock-style: multi-line
let-style: auto
in-style: right-align
single-constraint-parens: auto
unicode: never
respectful: true
================================================
FILE: .github/dependabot.yml
================================================
version: 2
updates:
# Maintain dependencies for GitHub Actions
- package-ecosystem: "github-actions"
directory: "/"
schedule:
interval: "daily"
================================================
FILE: .github/workflows/Cabal-Linux.yml
================================================
name: "Hackage, Cabal, Linux"
on:
pull_request:
push:
branches:
- master
schedule:
- cron: "45 02 * * *"
env:
cabalConfig: --enable-tests --enable-benchmarks --disable-optimization --enable-deterministic
jobs:
build10:
name: "GHC"
runs-on: ubuntu-latest
strategy:
fail-fast: false
matrix:
ghc:
[ "9.10" ]
steps:
- name: "Git checkout"
uses: actions/checkout@v4
with:
submodules: recursive
- name: "Haskell env setup"
id: HaskEnvSetup
uses: haskell-actions/setup@v2
with:
ghc-version: ${{ matrix.ghc }}
- name: "Install additional system packages"
run: sudo apt install libsodium-dev
# 2020-08-01: NOTE: Nix instantiate still needed for HNix tests
- name: "Install Nix"
uses: cachix/install-nix-action@v25
- name: "Repository update"
run: cabal v2-update
# Freeze is for the caching
- name: "Configuration freeze"
run: cabal v2-freeze $cabalConfig --minimize-conflict-set
- name: "Configuring GitHub cache"
uses: actions/cache@v3
with:
path: |
${{ steps.HaskEnvSetup.outputs.cabal-store }}
dist-newstyle
key: ${{ runner.os }}-Cabal-${{ matrix.ghc }}-${{ hashFiles('cabal.project.freeze') }}
# 2022-04-22: `v2-` added to invalidate corrupted caches, can be removed after one week
restore-keys: ${{ runner.os }}-Cabal-${{ matrix.ghc }}-v2-
- name: "Build"
run: cabal v2-build $cabalConfig
- name: "Tests"
run: cabal v2-test $cabalConfig
- name: "Haddock"
if: ${{ matrix.ghc == '9.0' }}
run: cabal v2-haddock $cabalConfig
- name: "Source distribution file"
if: ${{ matrix.ghc == '9.0' }}
run: cabal v2-sdist
================================================
FILE: .github/workflows/HLint.yml
================================================
name: "Checking code"
on:
pull_request:
push:
branches:
- master
jobs:
build10:
name: "HLint"
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v4
- name: 'Installing'
uses: haskell-actions/hlint-setup@v2
with:
version: '3.5'
- name: 'Checking code'
uses: haskell-actions/hlint-run@v2
with:
path: .
fail-on: warning
================================================
FILE: .github/workflows/On-Release-Cabal-Linux.yml
================================================
name: "Release testing, Hackage, Cabal, Linux"
on:
release:
# created: a draft is saved, or a release or pre-release is published without previously being saved as a draft
types: [ created ]
env:
cabalConfig: --enable-tests --enable-benchmarks --disable-optimization --enable-deterministic
jobs:
build10:
name: "GHC"
runs-on: ubuntu-latest
strategy:
matrix:
ghc: [ "9.10" ]
steps:
- name: "Git checkout"
uses: actions/checkout@v4
with:
submodules: recursive
- name: "Haskell env setup"
id: HaskEnvSetup
uses: haskell-actions/setup@v2
with:
ghc-version: ${{ matrix.ghc }}
- name: "Install additional system packages"
run: sudo apt install libsodium-dev
# 2020-08-01: NOTE: Nix instantiate still needed for HNix tests
- name: "Install Nix"
uses: cachix/install-nix-action@v25
- name: "Repository update"
run: cabal v2-update
# NOTE: Freeze is for the caching
- name: "Configuration freeze"
run: cabal v2-freeze $cabalConfig
- name: "Configuring GitHub cache"
uses: actions/cache@v3
with:
path: |
${{ steps.HaskEnvSetup.outputs.cabal-store }}
dist-newstyle
key: ${{ runner.os }}-Cabal-${{ matrix.ghc }}-${{ hashFiles('cabal.project.freeze') }}
# 2022-04-22: `v2-` added to invalidate corrupted caches, can be removed after one week
restore-keys: ${{ runner.os }}-Cabal-${{ matrix.ghc }}-v2-
- name: "Build"
run: cabal v2-build $cabalConfig
- name: "Tests"
run: cabal v2-test $cabalConfig
================================================
FILE: .github/workflows/On-Release-Nixpkgs-integration.yml
================================================
name: "Direct import & build inside Nixpkgs"
on:
release:
# created: a draft is saved, or a release or pre-release is published without previously being saved as a draft
types: [ created ]
jobs:
build10:
name: "Clean integration test"
runs-on: ubuntu-latest
steps:
- name: "Git checkout"
uses: actions/checkout@v4
- name: "Local cache"
uses: actions/cache@v3
with:
path: |
/nix/store
key: ${{ runner.os }}-Nixpkgs-integration-test
- name: "Install Nix"
uses: cachix/install-nix-action@v25
with:
nix_path: "nixpkgs=channel:nixos-unstable"
- name: "Run Nixpkgs integration test"
uses: Anton-Latukha/test-haskell-nixpkgs-integration-action@v1
================================================
FILE: .github/workflows/Quality.yml
================================================
name: "Quality checks"
on:
pull_request:
push:
branches:
- master
jobs:
formatting:
name: "Formatting (fourmolu)"
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v4
- uses: cachix/install-nix-action@v25
with:
extra_nix_config: |
accept-flake-config = true
- name: "Check Haskell formatting"
run: nix build .#checks.x86_64-linux.formatting --print-build-logs
- name: "Check shell script formatting"
run: nix build .#checks.x86_64-linux.shell-formatting --print-build-logs
shellcheck:
name: "ShellCheck"
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v4
- uses: cachix/install-nix-action@v25
with:
extra_nix_config: |
accept-flake-config = true
- name: "Lint shell scripts"
run: nix build .#checks.x86_64-linux.shellcheck --print-build-logs
warnings:
name: "Build (warnings as errors)"
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v4
with:
submodules: recursive
- uses: haskell-actions/setup@v2
with:
ghc-version: "9.10"
- uses: cachix/install-nix-action@v25
- run: sudo apt install libsodium-dev
- run: cabal v2-update
- name: "Build with -Werror"
run: >
cabal v2-build
--enable-tests --enable-benchmarks
--disable-optimization --enable-deterministic
--ghc-options=-Werror
haddock:
name: "Documentation (Haddock)"
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v4
with:
submodules: recursive
- uses: haskell-actions/setup@v2
with:
ghc-version: "9.10"
- uses: cachix/install-nix-action@v25
- run: sudo apt install libsodium-dev
- run: cabal v2-update
- name: "Build documentation"
run: >
cabal v2-haddock
--disable-optimization --enable-deterministic
- name: "Upload documentation"
uses: actions/upload-artifact@v4
with:
name: haddock-docs
path: dist-newstyle/build/**/doc/
coverage:
name: "Code coverage"
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v4
with:
submodules: recursive
- uses: haskell-actions/setup@v2
with:
ghc-version: "9.10"
- uses: cachix/install-nix-action@v25
- run: sudo apt install libsodium-dev
- run: cabal v2-update
- name: "Build and test with coverage"
run: |
cabal v2-configure --enable-tests --enable-coverage --disable-optimization
cabal v2-build
cabal v2-test
- name: "Upload coverage report"
uses: actions/upload-artifact@v4
with:
name: coverage-report
path: dist-newstyle/build/**/hpc/
benchmarks:
name: "Benchmarks"
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v4
with:
submodules: recursive
- uses: haskell-actions/setup@v2
with:
ghc-version: "9.10"
- uses: cachix/install-nix-action@v25
- run: sudo apt install libsodium-dev
- run: cabal v2-update
- name: "Run benchmarks"
run: |
cabal v2-build --enable-benchmarks --disable-optimization
cabal v2-bench 2>&1 | tee benchmark-results.txt
- name: "Upload benchmark results"
uses: actions/upload-artifact@v4
with:
name: benchmark-results
path: benchmark-results.txt
nix-build:
name: "Nix build"
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v4
- uses: cachix/install-nix-action@v25
with:
extra_nix_config: |
accept-flake-config = true
- name: "Build with Nix"
run: nix build --print-build-logs
================================================
FILE: .gitignore
================================================
**/#*
**/*~
**/.#*
/.history
/Setup
/dist/
/nix-test-eval*
/nix/
TAGS
cabal.project.local
ctags
dist-newstyle
result*
.ghc.environment.*
.hnixrc
================================================
FILE: .gitmodules
================================================
================================================
FILE: .hlint.yaml
================================================
- group: {name: generalise, enabled: true}
- group: {name: future, enabled: true}
- group: {name: attoparsec, enabled: true}
- group: {name: use-lens, enabled: true}
- arguments:
- "-XConstraintKinds"
- "-XDeriveGeneric"
- "-XGeneralizedNewtypeDeriving"
- "-XLambdaCase"
- "-XOverloadedStrings"
- "-XRecordWildCards"
- "-XScopedTypeVariables"
- "-XStandaloneDeriving"
- "-XTupleSections"
- "-XTypeApplications"
- "-XViewPatterns"
- ignore:
name: Use unless
- ignore:
name: Use head
- ignore:
name: Use Foldable.forM_
- hint:
lhs: "pure mempty"
note: "Use 'stub'"
rhs: stub
- hint:
lhs: "[]"
note: "Use `mempty`"
rhs: mempty
- hint:
lhs: "(: mempty)"
note: "Use `one`"
rhs: one
- hint:
lhs: "(:| mempty)"
note: "Use `one`"
rhs: one
- hint:
lhs: Data.Sequence.singleton
note: "Use `one`"
rhs: one
- hint:
lhs: Data.Text.singleton
note: "Use `one`"
rhs: one
- hint:
lhs: Data.Text.Lazy.singleton
note: "Use `one`"
rhs: one
- hint:
lhs: Data.ByteString.singleton
note: "Use `one`"
rhs: one
- hint:
lhs: Data.ByteString.Lazy.singleton
note: "Use `one`"
rhs: one
- hint:
lhs: Data.Map.singleton
note: "Use `one`"
rhs: one
- hint:
lhs: Data.Map.Strict.singleton
note: "Use `one`"
rhs: one
- hint:
lhs: Data.HashMap.Strict.singleton
note: "Use `one`"
rhs: one
- hint:
lhs: Data.HashMap.Lazy.singleton
note: "Use `one`"
rhs: one
- hint:
lhs: Data.IntMap.singleton
note: "Use `one`"
rhs: one
- hint:
lhs: Data.IntMap.Strict.singleton
note: "Use `one`"
rhs: one
- hint:
lhs: Data.Set.singleton
note: "Use `one`"
rhs: one
- hint:
lhs: Data.HashSet.singleton
note: "Use `one`"
rhs: one
- hint:
lhs: Data.IntSet.singleton
note: "Use `one`"
rhs: one
- warn:
lhs: "Control.Exception.evaluate (x `deepseq` mempty)"
rhs: evaluateNF_ x
- warn:
lhs: "void (evaluateWHNF x)"
rhs: evaluateWHNF_ x
- warn:
lhs: "void (evaluateNF x)"
rhs: evaluateNF_ x
- warn:
lhs: "foldl' (+) 0"
rhs: sum
- warn:
lhs: "foldl' (*) 1"
rhs: product
- hint:
lhs: "fmap and (sequenceA s)"
note: Applying this hint would mean that some actions that were being executed previously would no longer be executed.
rhs: andM s
- hint:
lhs: "and <$> sequenceA s"
note: Applying this hint would mean that some actions that were being executed previously would no longer be executed.
rhs: andM s
- hint:
lhs: "fmap or (sequenceA s)"
note: Applying this hint would mean that some actions that were being executed previously would no longer be executed.
rhs: orM s
- hint:
lhs: "or <$> sequenceA s"
note: Applying this hint would mean that some actions that were being executed previously would no longer be executed.
rhs: orM s
- hint:
lhs: "fmap and (traversable f s)"
note: Applying this hint would mean that some actions that were being executed previously would no longer be executed.
rhs: allM f s
- hint:
lhs: "and <$> traversable f s"
note: Applying this hint would mean that some actions that were being executed previously would no longer be executed.
rhs: allM f s
- hint:
lhs: "fmap or (traversable f s)"
note: Applying this hint would mean that some actions that were being executed previously would no longer be executed.
rhs: anyM f s
- hint:
lhs: "or <$> traversable f s"
note: Applying this hint would mean that some actions that were being executed previously would no longer be executed.
rhs: anyM f s
- warn:
lhs: "getAlt (foldMap (Alt . f) xs)"
rhs: asumMap xs
- warn:
lhs: "getAlt . foldMap (Alt . f)"
rhs: asumMap
- hint:
lhs: "foldr (\\x acc -> f x <|> acc) empty"
note: "Use 'asumMap'"
rhs: asumMap f
- hint:
lhs: "asum (fmap f xs)"
note: "Use 'asumMap'"
rhs: asumMap f xs
- warn:
lhs: "fmap fst &&& fmap snd"
rhs: unzip
- hint:
lhs: "fmap (fmap f) x"
note: "Use '(<<$>>)'"
rhs: "f <<$>> x"
- warn:
lhs: "fmap f (nonEmpty x)"
rhs: viaNonEmpty f x
- warn:
lhs: fmap f . nonEmpty
rhs: viaNonEmpty f
- warn:
lhs: "f <$> nonEmpty x"
rhs: viaNonEmpty f x
- warn:
lhs: partitionEithers . fmap f
rhs: partitionWith f
- warn:
lhs: partitionEithers $ fmap f x
rhs: partitionWith f x
- warn:
lhs: forever
note: "'forever' is loosely typed and may hide errors"
rhs: infinitely
- warn:
lhs: "unlessM (not <$> x)"
rhs: whenM x
- warn:
lhs: "either (const True) (const False)"
rhs: isLeft
- warn:
lhs: "either (const False) (const True)"
rhs: isRight
- warn:
lhs: "either id (const a)"
rhs: fromLeft a
- warn:
lhs: "either (const b) id"
rhs: fromRight b
- warn:
lhs: "either Just (const Nothing)"
rhs: leftToMaybe
- warn:
lhs: "either (const Nothing) Just"
rhs: rightToMaybe
- warn:
lhs: "maybe (Left l) Right"
rhs: maybeToRight l
- warn:
lhs: "maybe (Right r) Left"
rhs: maybeToLeft r
- warn:
lhs: "case m of [] -> stub ; (x:xs) -> f (x :| xs)"
rhs: whenNotNull m f
- warn:
lhs: "case m of (x:xs) -> f (x :| xs); [] -> stub"
rhs: whenNotNull m f
- warn:
lhs: "m >>= \\case [] -> stub ; (x:xs) -> f (x :| xs)"
rhs: whenNotNullM m f
- warn:
lhs: "m >>= \\case (x:xs) -> f (x :| xs); [] -> stub"
rhs: whenNotNullM m f
- warn:
lhs: mapMaybe leftToMaybe
rhs: lefts
- warn:
lhs: mapMaybe rightToMaybe
rhs: rights
- warn:
lhs: flip runReaderT
rhs: usingReaderT
- warn:
lhs: flip runReader
rhs: usingReader
- warn:
lhs: flip runStateT
rhs: usingStateT
- warn:
lhs: flip runState
rhs: usingState
- warn:
lhs: "fst <$> usingStateT s st"
rhs: evaluatingStateT s st
- warn:
lhs: "fst (usingState s st)"
rhs: evaluatingState s st
- warn:
lhs: "snd <$> usingStateT s st"
rhs: executingStateT s st
- warn:
lhs: "snd (usingState s st)"
rhs: executingState s st
- warn:
lhs: "MaybeT (pure m)"
rhs: hoistMaybe m
- warn:
lhs: MaybeT . pure
rhs: hoistMaybe
- warn:
lhs: "ExceptT (pure m)"
rhs: hoistEither m
- warn:
lhs: ExceptT . pure
rhs: hoistEither
- warn:
lhs: fromMaybe mempty
rhs: maybeToMonoid
- warn:
lhs: "m ?: mempty"
rhs: maybeToMonoid m
- warn:
lhs: "Data.Map.toAscList (Data.Map.fromList x)"
rhs: sortWith fst x
- warn:
lhs: "Data.Map.toDescList (Data.Map.fromList x)"
rhs: "sortWith (Down . fst) x"
- warn:
lhs: "Data.Set.toList (Data.Set.fromList l)"
rhs: sortNub l
- warn:
lhs: "Data.Set.assocs (Data.Set.fromList l)"
rhs: sortNub l
- warn:
lhs: "Data.Set.toAscList (Data.Set.fromList l)"
rhs: sortNub l
- warn:
lhs: "Data.HashSet.toList (Data.HashSet.fromList l)"
rhs: unstableNub l
- warn:
lhs: nub
note: "'nub' is O(n^2), 'ordNub' is O(n log n)"
rhs: ordNub
- warn:
lhs: "sortBy (comparing f)"
note: "If the function you are using for 'comparing' is slow, use 'sortOn' instead of 'sortWith', because 'sortOn' caches applications the function and 'sortWith' doesn't."
rhs: sortWith f
- warn:
lhs: sortOn fst
note: "'sortWith' will be faster here because it doesn't do caching"
rhs: sortWith fst
- warn:
lhs: sortOn snd
note: "'sortWith' will be faster here because it doesn't do caching"
rhs: sortWith snd
- warn:
lhs: "sortOn (Down . fst)"
note: "'sortWith' will be faster here because it doesn't do caching"
rhs: "sortWith (Down . fst)"
- warn:
lhs: "sortOn (Down . snd)"
note: "'sortWith' will be faster here because it doesn't do caching"
rhs: "sortWith (Down . snd)"
- warn:
lhs: Data.Text.Lazy.IO.putStr
rhs: putLText
- warn:
lhs: Data.Text.Lazy.IO.putStrLn
rhs: putLTextLn
- warn:
lhs: Data.ByteString.Char8.putStr
rhs: putBS
- warn:
lhs: Data.ByteString.Char8.putStrLn
rhs: putBSLn
- warn:
lhs: Data.ByteString.Lazy.Char8.putStr
rhs: putLBS
- warn:
lhs: Data.ByteString.Lazy.Char8.putStrLn
rhs: putLBSLn
- warn:
lhs: Data.Text.Lazy.Text
rhs: LText
- warn:
lhs: Data.ByteString.Lazy.ByteString
rhs: LByteString
- warn:
lhs: Data.ByteString.UTF8.fromString
rhs: encodeUtf8
- warn:
lhs: Data.ByteString.UTF8.toString
rhs: decodeUtf8
- warn:
lhs: Data.Text.Encoding.encodeUtf8
rhs: encodeUtf8
- warn:
lhs: Data.Text.Encoding.decodeUtf8
rhs: decodeUtf8
- warn:
lhs: "Data.ByteString.Lazy.toStrict (encodeUtf8 x)"
rhs: encodeUtf8 x
- warn:
lhs: "toStrict (encodeUtf8 x)"
rhs: encodeUtf8 x
- warn:
lhs: "decodeUtf8 (Data.ByteString.Lazy.fromStrict x)"
rhs: decodeUtf8 x
- warn:
lhs: "decodeUtf8 (fromStrict x)"
rhs: decodeUtf8 x
- warn:
lhs: Data.ByteString.Lazy.UTF8.fromString
rhs: encodeUtf8
- warn:
lhs: Data.ByteString.Lazy.UTF8.toString
rhs: decodeUtf8
- warn:
lhs: "Data.ByteString.Lazy.fromStrict (Data.Text.Encoding.encodeUtf8 x)"
rhs: encodeUtf8 x
- warn:
lhs: "Data.ByteString.Lazy.fromStrict (encodeUtf8 x)"
rhs: encodeUtf8 x
- warn:
lhs: "Data.Text.Encoding.decodeUtf8 (Data.ByteString.Lazy.toStrict x)"
rhs: decodeUtf8 x
- warn:
lhs: "Data.Text.Encoding.decodeUtf8 (toStrict x)"
rhs: decodeUtf8 x
- warn:
lhs: "decodeUtf8 (Data.ByteString.Lazy.toStrict x)"
rhs: decodeUtf8 x
- warn:
lhs: "decodeUtf8 (toStrict x)"
rhs: decodeUtf8 x
- warn:
lhs: Data.Text.pack
rhs: toText
- warn:
lhs: Data.Text.unpack
rhs: toString
- warn:
lhs: Data.Text.Lazy.pack
rhs: toLText
- warn:
lhs: Data.Text.Lazy.unpack
rhs: toString
- warn:
lhs: Data.Text.Lazy.toStrict
rhs: toText
- warn:
lhs: Data.Text.Lazy.fromStrict
rhs: toLText
- warn:
lhs: "Data.Text.pack (show x)"
rhs: show x
- warn:
lhs: "Data.Text.Lazy.pack (show x)"
rhs: show x
- warn:
lhs: Data.ByteString.Lazy.fromStrict
rhs: fromStrict
- warn:
lhs: Data.ByteString.Lazy.toStrict
rhs: toStrict
- warn:
lhs: Data.Text.Lazy.fromStrict
rhs: fromStrict
- warn:
lhs: Data.Text.Lazy.toStrict
rhs: toStrict
- warn:
lhs: Control.Applicative.Alternative
name: "Use 'Alternative' from Relude"
note: "'Alternative' is already exported from Relude"
rhs: Alternative
- warn:
lhs: Control.Applicative.empty
name: "Use 'empty' from Relude"
note: "'empty' is already exported from Relude"
rhs: empty
- warn:
lhs: "(Control.Applicative.<|>)"
name: "Use '<|>' from Relude"
note: "Operator '(<|>)' is already exported from Relude"
rhs: "(<|>)"
- warn:
lhs: Control.Applicative.some
name: "Use 'some' from Relude"
note: "'some' is already exported from Relude"
rhs: some
- warn:
lhs: Control.Applicative.many
name: "Use 'many' from Relude"
note: "'many' is already exported from Relude"
rhs: many
- warn:
lhs: Control.Applicative.Const
name: "Use 'Const' from Relude"
note: "'Const' is already exported from Relude"
rhs: Const
- warn:
lhs: Control.Applicative.getConst
name: "Use 'getConst' from Relude"
note: "'getConst' is already exported from Relude"
rhs: getConst
- warn:
lhs: Control.Applicative.ZipList
name: "Use 'ZipList' from Relude"
note: "'ZipList' is already exported from Relude"
rhs: ZipList
- warn:
lhs: Control.Applicative.getZipList
name: "Use 'getZipList' from Relude"
note: "'getZipList' is already exported from Relude"
rhs: getZipList
- warn:
lhs: Control.Applicative.liftA2
name: "Use 'liftA2' from Relude"
note: "'liftA2' is already exported from Relude"
rhs: liftA2
- warn:
lhs: Control.Applicative.liftA3
name: "Use 'liftA3' from Relude"
note: "'liftA3' is already exported from Relude"
rhs: liftA3
- warn:
lhs: Control.Applicative.optional
name: "Use 'optional' from Relude"
note: "'optional' is already exported from Relude"
rhs: optional
- warn:
lhs: "(Control.Applicative.<**>)"
name: "Use '<**>' from Relude"
note: "Operator '(<**>)' is already exported from Relude"
rhs: "(<**>)"
- warn:
lhs: Data.Char.chr
name: "Use 'chr' from Relude"
note: "'chr' is already exported from Relude"
rhs: chr
- warn:
lhs: Data.Int.Int8
name: "Use 'Int8' from Relude"
note: "'Int8' is already exported from Relude"
rhs: Int8
- warn:
lhs: Data.Int.Int16
name: "Use 'Int16' from Relude"
note: "'Int16' is already exported from Relude"
rhs: Int16
- warn:
lhs: Data.Int.Int32
name: "Use 'Int32' from Relude"
note: "'Int32' is already exported from Relude"
rhs: Int32
- warn:
lhs: Data.Int.Int64
name: "Use 'Int64' from Relude"
note: "'Int64' is already exported from Relude"
rhs: Int64
- warn:
lhs: Data.Word.Word8
name: "Use 'Word8' from Relude"
note: "'Word8' is already exported from Relude"
rhs: Word8
- warn:
lhs: Data.Word.Word16
name: "Use 'Word16' from Relude"
note: "'Word16' is already exported from Relude"
rhs: Word16
- warn:
lhs: Data.Word.Word32
name: "Use 'Word32' from Relude"
note: "'Word32' is already exported from Relude"
rhs: Word32
- warn:
lhs: Data.Word.Word64
name: "Use 'Word64' from Relude"
note: "'Word64' is already exported from Relude"
rhs: Word64
- warn:
lhs: Data.Word.byteSwap16
name: "Use 'byteSwap16' from Relude"
note: "'byteSwap16' is already exported from Relude"
rhs: byteSwap16
- warn:
lhs: Data.Word.byteSwap32
name: "Use 'byteSwap32' from Relude"
note: "'byteSwap32' is already exported from Relude"
rhs: byteSwap32
- warn:
lhs: Data.Word.byteSwap64
name: "Use 'byteSwap64' from Relude"
note: "'byteSwap64' is already exported from Relude"
rhs: byteSwap64
- warn:
lhs: Numeric.Natural.Natural
name: "Use 'Natural' from Relude"
note: "'Natural' is already exported from Relude"
rhs: Natural
- warn:
lhs: System.IO.IOMode
name: "Use 'IOMode' from Relude"
note: "'IOMode' is already exported from Relude"
rhs: IOMode
- warn:
lhs: System.IO.ReadMode
name: "Use 'ReadMode' from Relude"
note: "'ReadMode' is already exported from Relude"
rhs: ReadMode
- warn:
lhs: System.IO.WriteMode
name: "Use 'WriteMode' from Relude"
note: "'WriteMode' is already exported from Relude"
rhs: WriteMode
- warn:
lhs: System.IO.AppendMode
name: "Use 'AppendMode' from Relude"
note: "'AppendMode' is already exported from Relude"
rhs: AppendMode
- warn:
lhs: System.IO.ReadWriteMode
name: "Use 'ReadWriteMode' from Relude"
note: "'ReadWriteMode' is already exported from Relude"
rhs: ReadWriteMode
- warn:
lhs: Data.Ord.Down
name: "Use 'Down' from Relude"
note: "'Down' is already exported from Relude"
rhs: Down
- warn:
lhs: Data.Ord.comparing
name: "Use 'comparing' from Relude"
note: "'comparing' is already exported from Relude"
rhs: comparing
- warn:
lhs: Data.Coerce.Coercible
name: "Use 'Coercible' from Relude"
note: "'Coercible' is already exported from Relude"
rhs: Coercible
- warn:
lhs: Data.Coerce.coerce
name: "Use 'coerce' from Relude"
note: "'coerce' is already exported from Relude"
rhs: coerce
- warn:
lhs: Data.Kind.Constraint
name: "Use 'Constraint' from Relude"
note: "'Constraint' is already exported from Relude"
rhs: Constraint
- warn:
lhs: Data.Kind.Type
name: "Use 'Type' from Relude"
note: "'Type' is already exported from Relude"
rhs: Type
- warn:
lhs: Data.Typeable.Typeable
name: "Use 'Typeable' from Relude"
note: "'Typeable' is already exported from Relude"
rhs: Typeable
- warn:
lhs: Data.Proxy.Proxy
name: "Use 'Proxy' from Relude"
note: "'Proxy' is already exported from Relude"
rhs: Proxy
- warn:
lhs: Data.Typeable.Typeable
name: "Use 'Typeable' from Relude"
note: "'Typeable' is already exported from Relude"
rhs: Typeable
- warn:
lhs: Data.Void.Void
name: "Use 'Void' from Relude"
note: "'Void' is already exported from Relude"
rhs: Void
- warn:
lhs: Data.Void.absurd
name: "Use 'absurd' from Relude"
note: "'absurd' is already exported from Relude"
rhs: absurd
- warn:
lhs: Data.Void.vacuous
name: "Use 'vacuous' from Relude"
note: "'vacuous' is already exported from Relude"
rhs: vacuous
- warn:
lhs: Data.Base.maxInt
name: "Use 'maxInt' from Relude"
note: "'maxInt' is already exported from Relude"
rhs: maxInt
- warn:
lhs: Data.Base.minInt
name: "Use 'minInt' from Relude"
note: "'minInt' is already exported from Relude"
rhs: minInt
- warn:
lhs: Data.Base.ord
name: "Use 'ord' from Relude"
note: "'ord' is already exported from Relude"
rhs: ord
- warn:
lhs: GHC.Enum.boundedEnumFrom
name: "Use 'boundedEnumFrom' from Relude"
note: "'boundedEnumFrom' is already exported from Relude"
rhs: boundedEnumFrom
- warn:
lhs: GHC.Enum.boundedEnumFromThen
name: "Use 'boundedEnumFromThen' from Relude"
note: "'boundedEnumFromThen' is already exported from Relude"
rhs: boundedEnumFromThen
- warn:
lhs: GHC.Generics.Generic
name: "Use 'Generic' from Relude"
note: "'Generic' is already exported from Relude"
rhs: Generic
- warn:
lhs: GHC.Real.Ratio
name: "Use 'Ratio' from Relude"
note: "'Ratio' is already exported from Relude"
rhs: Ratio
- warn:
lhs: GHC.Real.Rational
name: "Use 'Rational' from Relude"
note: "'Rational' is already exported from Relude"
rhs: Rational
- warn:
lhs: GHC.Real.denominator
name: "Use 'denominator' from Relude"
note: "'denominator' is already exported from Relude"
rhs: denominator
- warn:
lhs: GHC.Real.numerator
name: "Use 'numerator' from Relude"
note: "'numerator' is already exported from Relude"
rhs: numerator
- warn:
lhs: GHC.TypeNats.CmpNat
name: "Use 'CmpNat' from Relude"
note: "'CmpNat' is already exported from Relude"
rhs: CmpNat
- warn:
lhs: GHC.TypeNats.KnownNat
name: "Use 'KnownNat' from Relude"
note: "'KnownNat' is already exported from Relude"
rhs: KnownNat
- warn:
lhs: GHC.TypeNats.Nat
name: "Use 'Nat' from Relude"
note: "'Nat' is already exported from Relude"
rhs: Nat
- warn:
lhs: GHC.TypeNats.SomeNat
name: "Use 'SomeNat' from Relude"
note: "'SomeNat' is already exported from Relude"
rhs: SomeNat
- warn:
lhs: GHC.TypeNats.natVal
name: "Use 'natVal' from Relude"
note: "'natVal' is already exported from Relude"
rhs: natVal
- warn:
lhs: GHC.TypeNats.someNatVal
name: "Use 'someNatVal' from Relude"
note: "'someNatVal' is already exported from Relude"
rhs: someNatVal
- warn:
lhs: GHC.TypeLits.CmpNat
name: "Use 'CmpNat' from Relude"
note: "'CmpNat' is already exported from Relude"
rhs: CmpNat
- warn:
lhs: GHC.TypeLits.KnownNat
name: "Use 'KnownNat' from Relude"
note: "'KnownNat' is already exported from Relude"
rhs: KnownNat
- warn:
lhs: GHC.TypeLits.Nat
name: "Use 'Nat' from Relude"
note: "'Nat' is already exported from Relude"
rhs: Nat
- warn:
lhs: GHC.TypeLits.SomeNat
name: "Use 'SomeNat' from Relude"
note: "'SomeNat' is already exported from Relude"
rhs: SomeNat
- warn:
lhs: GHC.TypeLits.natVal
name: "Use 'natVal' from Relude"
note: "'natVal' is already exported from Relude"
rhs: natVal
- warn:
lhs: GHC.TypeLits.someNatVal
name: "Use 'someNatVal' from Relude"
note: "'someNatVal' is already exported from Relude"
rhs: someNatVal
- warn:
lhs: GHC.ExecutionStack.getStackTrace
name: "Use 'getStackTrace' from Relude"
note: "'getStackTrace' is already exported from Relude"
rhs: getStackTrace
- warn:
lhs: GHC.ExecutionStack.showStackTrace
name: "Use 'showStackTrace' from Relude"
note: "'showStackTrace' is already exported from Relude"
rhs: showStackTrace
- warn:
lhs: GHC.OverloadedLabels.IsLabel
name: "Use 'IsLabel' from Relude"
note: "'IsLabel' is already exported from Relude"
rhs: IsLabel
- warn:
lhs: GHC.OverloadedLabels.fromLabel
name: "Use 'fromLabel' from Relude"
note: "'fromLabel' is already exported from Relude"
rhs: fromLabel
- warn:
lhs: GHC.Stack.CallStack
name: "Use 'CallStack' from Relude"
note: "'CallStack' is already exported from Relude"
rhs: CallStack
- warn:
lhs: GHC.Stack.HasCallStack
name: "Use 'HasCallStack' from Relude"
note: "'HasCallStack' is already exported from Relude"
rhs: HasCallStack
- warn:
lhs: GHC.Stack.callStack
name: "Use 'callStack' from Relude"
note: "'callStack' is already exported from Relude"
rhs: callStack
- warn:
lhs: GHC.Stack.currentCallStack
name: "Use 'currentCallStack' from Relude"
note: "'currentCallStack' is already exported from Relude"
rhs: currentCallStack
- warn:
lhs: GHC.Stack.getCallStack
name: "Use 'getCallStack' from Relude"
note: "'getCallStack' is already exported from Relude"
rhs: getCallStack
- warn:
lhs: GHC.Stack.prettyCallStack
name: "Use 'prettyCallStack' from Relude"
note: "'prettyCallStack' is already exported from Relude"
rhs: prettyCallStack
- warn:
lhs: GHC.Stack.prettySrcLoc
name: "Use 'prettySrcLoc' from Relude"
note: "'prettySrcLoc' is already exported from Relude"
rhs: prettySrcLoc
- warn:
lhs: GHC.Stack.withFrozenCallStack
name: "Use 'withFrozenCallStack' from Relude"
note: "'withFrozenCallStack' is already exported from Relude"
rhs: withFrozenCallStack
- warn:
lhs: Data.Bifoldable.Bifoldable
name: "Use 'Bifoldable' from Relude"
note: "'Bifoldable' is already exported from Relude"
rhs: Bifoldable
- warn:
lhs: Data.Bifoldable.bifold
name: "Use 'bifold' from Relude"
note: "'bifold' is already exported from Relude"
rhs: bifold
- warn:
lhs: Data.Bifoldable.bifoldMap
name: "Use 'bifoldMap' from Relude"
note: "'bifoldMap' is already exported from Relude"
rhs: bifoldMap
- warn:
lhs: Data.Bifoldable.bifoldr
name: "Use 'bifoldr' from Relude"
note: "'bifoldr' is already exported from Relude"
rhs: bifoldr
- warn:
lhs: Data.Bifoldable.bifoldl
name: "Use 'bifoldl' from Relude"
note: "'bifoldl' is already exported from Relude"
rhs: bifoldl
- warn:
lhs: "Data.Bifoldable.bifoldl'"
name: "Use 'bifoldl'' from Relude"
note: "'bifoldl'' is already exported from Relude"
rhs: "bifoldl'"
- warn:
lhs: Data.Bifoldable.bifoldlM
name: "Use 'bifoldlM' from Relude"
note: "'bifoldlM' is already exported from Relude"
rhs: bifoldlM
- warn:
lhs: "Data.Bifoldable.bifoldr'"
name: "Use 'bifoldr'' from Relude"
note: "'bifoldr'' is already exported from Relude"
rhs: "bifoldr'"
- warn:
lhs: Data.Bifoldable.bifoldrM
name: "Use 'bifoldrM' from Relude"
note: "'bifoldrM' is already exported from Relude"
rhs: bifoldrM
- warn:
lhs: Data.Bifoldable.bitraverse_
name: "Use 'bitraverse_' from Relude"
note: "'bitraverse_' is already exported from Relude"
rhs: bitraverse_
- warn:
lhs: Data.Bifoldable.bifor_
name: "Use 'bifor_' from Relude"
note: "'bifor_' is already exported from Relude"
rhs: bifor_
- warn:
lhs: Data.Bifoldable.biasum
name: "Use 'biasum' from Relude"
note: "'biasum' is already exported from Relude"
rhs: biasum
- warn:
lhs: Data.Bifoldable.bisequence_
name: "Use 'bisequence_' from Relude"
note: "'bisequence_' is already exported from Relude"
rhs: bisequence_
- warn:
lhs: Data.Bifoldable.biList
name: "Use 'biList' from Relude"
note: "'biList' is already exported from Relude"
rhs: biList
- warn:
lhs: Data.Bifoldable.binull
name: "Use 'binull' from Relude"
note: "'binull' is already exported from Relude"
rhs: binull
- warn:
lhs: Data.Bifoldable.bilength
name: "Use 'bilength' from Relude"
note: "'bilength' is already exported from Relude"
rhs: bilength
- warn:
lhs: Data.Bifoldable.bielem
name: "Use 'bielem' from Relude"
note: "'bielem' is already exported from Relude"
rhs: bielem
- warn:
lhs: Data.Bifoldable.biand
name: "Use 'biand' from Relude"
note: "'biand' is already exported from Relude"
rhs: biand
- warn:
lhs: Data.Bifoldable.bior
name: "Use 'bior' from Relude"
note: "'bior' is already exported from Relude"
rhs: bior
- warn:
lhs: Data.Bifoldable.biany
name: "Use 'biany' from Relude"
note: "'biany' is already exported from Relude"
rhs: biany
- warn:
lhs: Data.Bifoldable.biall
name: "Use 'biall' from Relude"
note: "'biall' is already exported from Relude"
rhs: biall
- warn:
lhs: Data.Bifoldable.bifind
name: "Use 'bifind' from Relude"
note: "'bifind' is already exported from Relude"
rhs: bifind
- warn:
lhs: Data.Bitraversable.Bitraversable
name: "Use 'Bitraversable' from Relude"
note: "'Bitraversable' is already exported from Relude"
rhs: Bitraversable
- warn:
lhs: Data.Bitraversable.bitraverse
name: "Use 'bitraverse' from Relude"
note: "'bitraverse' is already exported from Relude"
rhs: bitraverse
- warn:
lhs: Data.Bitraversable.bisequence
name: "Use 'bisequence' from Relude"
note: "'bisequence' is already exported from Relude"
rhs: bisequence
- warn:
lhs: Data.Bitraversable.bifor
name: "Use 'bifor' from Relude"
note: "'bifor' is already exported from Relude"
rhs: bifor
- warn:
lhs: Data.Bitraversable.bimapDefault
name: "Use 'bimapDefault' from Relude"
note: "'bimapDefault' is already exported from Relude"
rhs: bimapDefault
- warn:
lhs: Data.Bitraversable.bifoldMapDefault
name: "Use 'bifoldMapDefault' from Relude"
note: "'bifoldMapDefault' is already exported from Relude"
rhs: bifoldMapDefault
- warn:
lhs: Control.Monad.guard
name: "Use 'guard' from Relude"
note: "'guard' is already exported from Relude"
rhs: guard
- warn:
lhs: Control.Monad.when
name: "Use 'when' from Relude"
note: "'when' is already exported from Relude"
rhs: when
- warn:
lhs: Data.Bool.bool
name: "Use 'bool' from Relude"
note: "'bool' is already exported from Relude"
rhs: bool
- warn:
lhs: Data.Hashable.Hashable
name: "Use 'Hashable' from Relude"
note: "'Hashable' is already exported from Relude"
rhs: Hashable
- warn:
lhs: Data.Hashable.hashWithSalt
name: "Use 'hashWithSalt' from Relude"
note: "'hashWithSalt' is already exported from Relude"
rhs: hashWithSalt
- warn:
lhs: Data.HashMap.Strict.HashMap
name: "Use 'HashMap' from Relude"
note: "'HashMap' is already exported from Relude"
rhs: HashMap
- warn:
lhs: Data.HashSet.HashSet
name: "Use 'HashSet' from Relude"
note: "'HashSet' is already exported from Relude"
rhs: HashSet
- warn:
lhs: Data.IntMap.Strict.IntMap
name: "Use 'IntMap' from Relude"
note: "'IntMap' is already exported from Relude"
rhs: IntMap
- warn:
lhs: Data.IntSet.IntSet
name: "Use 'IntSet' from Relude"
note: "'IntSet' is already exported from Relude"
rhs: IntSet
- warn:
lhs: Data.Map.Strict.Map
name: "Use 'Map' from Relude"
note: "'Map' is already exported from Relude"
rhs: Map
- warn:
lhs: Data.Sequence.Sequence
name: "Use 'Sequence' from Relude"
note: "'Sequence' is already exported from Relude"
rhs: Sequence
- warn:
lhs: Data.Set.Set
name: "Use 'Set' from Relude"
note: "'Set' is already exported from Relude"
rhs: Set
- warn:
lhs: Data.Tuple.swap
name: "Use 'swap' from Relude"
note: "'swap' is already exported from Relude"
rhs: swap
- warn:
lhs: Data.Vector.Vector
name: "Use 'Vector' from Relude"
note: "'Vector' is already exported from Relude"
rhs: Vector
- warn:
lhs: GHC.Exts.IsList
name: "Use 'IsList' from Relude"
note: "'IsList' is already exported from Relude"
rhs: IsList
- warn:
lhs: GHC.Exts.fromList
name: "Use 'fromList' from Relude"
note: "'fromList' is already exported from Relude"
rhs: fromList
- warn:
lhs: GHC.Exts.fromListN
name: "Use 'fromListN' from Relude"
note: "'fromListN' is already exported from Relude"
rhs: fromListN
- warn:
lhs: Debug.Trace.trace
name: "Use 'trace' from Relude"
note: "'trace' is already exported from Relude"
rhs: trace
- warn:
lhs: Debug.Trace.traceShow
name: "Use 'traceShow' from Relude"
note: "'traceShow' is already exported from Relude"
rhs: traceShow
- warn:
lhs: Debug.Trace.traceShowId
name: "Use 'traceShowId' from Relude"
note: "'traceShowId' is already exported from Relude"
rhs: traceShowId
- warn:
lhs: Debug.Trace.traceShowM
name: "Use 'traceShowM' from Relude"
note: "'traceShowM' is already exported from Relude"
rhs: traceShowM
- warn:
lhs: Debug.Trace.traceM
name: "Use 'traceM' from Relude"
note: "'traceM' is already exported from Relude"
rhs: traceM
- warn:
lhs: Debug.Trace.traceId
name: "Use 'traceId' from Relude"
note: "'traceId' is already exported from Relude"
rhs: traceId
- warn:
lhs: Control.DeepSeq.NFData
name: "Use 'NFData' from Relude"
note: "'NFData' is already exported from Relude"
rhs: NFData
- warn:
lhs: Control.DeepSeq.rnf
name: "Use 'rnf' from Relude"
note: "'rnf' is already exported from Relude"
rhs: rnf
- warn:
lhs: Control.DeepSeq.deepseq
name: "Use 'deepseq' from Relude"
note: "'deepseq' is already exported from Relude"
rhs: deepseq
- warn:
lhs: Control.DeepSeq.force
name: "Use 'force' from Relude"
note: "'force' is already exported from Relude"
rhs: force
- warn:
lhs: "(Control.DeepSeq.$!!)"
name: "Use '$!!' from Relude"
note: "Operator '($!!)' is already exported from Relude"
rhs: "($!!)"
- warn:
lhs: Control.Exception.Exception
name: "Use 'Exception' from Relude"
note: "'Exception' is already exported from Relude"
rhs: Exception
- warn:
lhs: Control.Exception.SomeException
name: "Use 'SomeException' from Relude"
note: "'SomeException' is already exported from Relude"
rhs: SomeException
- warn:
lhs: Control.Exception.toException
name: "Use 'toException' from Relude"
note: "'toException' is already exported from Relude"
rhs: toException
- warn:
lhs: Control.Exception.fromException
name: "Use 'fromException' from Relude"
note: "'fromException' is already exported from Relude"
rhs: fromException
- warn:
lhs: Control.Exception.displayException
name: "Use 'displayException' from Relude"
note: "'displayException' is already exported from Relude"
rhs: displayException
- warn:
lhs: Data.Foldable.asum
name: "Use 'asum' from Relude"
note: "'asum' is already exported from Relude"
rhs: asum
- warn:
lhs: Data.Foldable.find
name: "Use 'find' from Relude"
note: "'find' is already exported from Relude"
rhs: find
- warn:
lhs: Data.Foldable.find
name: "Use 'find' from Relude"
note: "'find' is already exported from Relude"
rhs: find
- warn:
lhs: Data.Foldable.fold
name: "Use 'fold' from Relude"
note: "'fold' is already exported from Relude"
rhs: fold
- warn:
lhs: "Data.Foldable.foldl'"
name: "Use 'foldl'' from Relude"
note: "'foldl'' is already exported from Relude"
rhs: "foldl'"
- warn:
lhs: forM_ b a
name: "Use 'traverse_'"
rhs: traverse_ a b
- warn:
lhs: for_ b a
name: "Use 'traverse_'"
note: "'for_' is already exported from Relude"
rhs: traverse a b
- warn:
lhs: Data.Foldable.sequenceA_
name: "Use 'sequenceA_' from Relude"
note: "'sequenceA_' is already exported from Relude"
rhs: sequenceA_
- warn:
lhs: Data.Foldable.toList
name: "Use 'toList' from Relude"
note: "'toList' is already exported from Relude"
rhs: toList
- warn:
lhs: forM b a
name: "Use 'traverse'"
rhs: traverse a b
- warn:
lhs: Data.Traversable.mapAccumL
name: "Use 'mapAccumL' from Relude"
note: "'mapAccumL' is already exported from Relude"
rhs: mapAccumL
- warn:
lhs: Data.Traversable.mapAccumR
name: "Use 'mapAccumR' from Relude"
note: "'mapAccumR' is already exported from Relude"
rhs: mapAccumR
- warn:
lhs: "(Control.Arrow.&&&)"
name: "Use '&&&' from Relude"
note: "Operator '(&&&)' is already exported from Relude"
rhs: "(&&&)"
- warn:
lhs: "(Control.Category.>>>)"
name: "Use '>>>' from Relude"
note: "Operator '(>>>)' is already exported from Relude"
rhs: "(>>>)"
- warn:
lhs: "(Control.Category.<<<)"
name: "Use '<<<' from Relude"
note: "Operator '(<<<)' is already exported from Relude"
rhs: "(<<<)"
- warn:
lhs: Data.Function.fix
name: "Use 'fix' from Relude"
note: "'fix' is already exported from Relude"
rhs: fix
- warn:
lhs: Data.Function.on
name: "Use 'on' from Relude"
note: "'on' is already exported from Relude"
rhs: 'on'
- warn:
lhs: Data.Bifunctor.Bifunctor
name: "Use 'Bifunctor' from Relude"
note: "'Bifunctor' is already exported from Relude"
rhs: Bifunctor
- warn:
lhs: Data.Bifunctor.bimap
name: "Use 'bimap' from Relude"
note: "'bimap' is already exported from Relude"
rhs: bimap
- warn:
lhs: Data.Bifunctor.first
name: "Use 'first' from Relude"
note: "'first' is already exported from Relude"
rhs: first
- warn:
lhs: Data.Bifunctor.second
name: "Use 'second' from Relude"
note: "'second' is already exported from Relude"
rhs: second
- warn:
lhs: Data.Functor.void
name: "Use 'void' from Relude"
note: "'void' is already exported from Relude"
rhs: void
- warn:
lhs: "(Data.Functor.$>)"
name: "Use '$>' from Relude"
note: "Operator '($>)' is already exported from Relude"
rhs: "($>)"
- warn:
lhs: "(Data.Functor.<&>)"
name: "Use '<&>' from Relude"
note: "Operator '(<&>)' is already exported from Relude"
rhs: "(<&>)"
- warn:
lhs: Data.Functor.Compose.Compose
name: "Use 'Compose' from Relude"
note: "'Compose' is already exported from Relude"
rhs: Compose
- warn:
lhs: Data.Functor.Identity.Identity
name: "Use 'Identity' from Relude"
note: "'Identity' is already exported from Relude"
rhs: Identity
- warn:
lhs: Data.Functor.Identity.runIdentity
name: "Use 'runIdentity' from Relude"
note: "'runIdentity' is already exported from Relude"
rhs: runIdentity
- warn:
lhs: Control.Concurrent.MVar.MVar
name: "Use 'MVar' from Relude"
note: "'MVar' is already exported from Relude"
rhs: MVar
- warn:
lhs: Control.Concurrent.MVar.newEmptyMVar
name: "Use 'newEmptyMVar' from Relude"
note: "'newEmptyMVar' is already exported from Relude"
rhs: newEmptyMVar
- warn:
lhs: Control.Concurrent.MVar.newMVar
name: "Use 'newMVar' from Relude"
note: "'newMVar' is already exported from Relude"
rhs: newMVar
- warn:
lhs: Control.Concurrent.MVar.putMVar
name: "Use 'putMVar' from Relude"
note: "'putMVar' is already exported from Relude"
rhs: putMVar
- warn:
lhs: Control.Concurrent.MVar.readMVar
name: "Use 'readMVar' from Relude"
note: "'readMVar' is already exported from Relude"
rhs: readMVar
- warn:
lhs: Control.Concurrent.MVar.swapMVar
name: "Use 'swapMVar' from Relude"
note: "'swapMVar' is already exported from Relude"
rhs: swapMVar
- warn:
lhs: Control.Concurrent.MVar.takeMVar
name: "Use 'takeMVar' from Relude"
note: "'takeMVar' is already exported from Relude"
rhs: takeMVar
- warn:
lhs: Control.Concurrent.MVar.tryPutMVar
name: "Use 'tryPutMVar' from Relude"
note: "'tryPutMVar' is already exported from Relude"
rhs: tryPutMVar
- warn:
lhs: Control.Concurrent.MVar.tryReadMVar
name: "Use 'tryReadMVar' from Relude"
note: "'tryReadMVar' is already exported from Relude"
rhs: tryReadMVar
- warn:
lhs: Control.Concurrent.MVar.tryTakeMVar
name: "Use 'tryTakeMVar' from Relude"
note: "'tryTakeMVar' is already exported from Relude"
rhs: tryTakeMVar
- warn:
lhs: Control.Monad.STM.STM
name: "Use 'STM' from Relude"
note: "'STM' is already exported from Relude"
rhs: STM
- warn:
lhs: Control.Monad.STM.atomically
name: "Use 'atomically' from Relude"
note: "'atomically' is already exported from Relude"
rhs: atomically
- warn:
lhs: Control.Monad.STM.throwSTM
name: "Use 'throwSTM' from Relude"
note: "'throwSTM' is already exported from Relude"
rhs: throwSTM
- warn:
lhs: Control.Monad.STM.catchSTM
name: "Use 'catchSTM' from Relude"
note: "'catchSTM' is already exported from Relude"
rhs: catchSTM
- warn:
lhs: Control.Concurrent.STM.TVar.TVar
name: "Use 'TVar' from Relude"
note: "'TVar' is already exported from Relude"
rhs: TVar
- warn:
lhs: Control.Concurrent.STM.TVar.newTVarIO
name: "Use 'newTVarIO' from Relude"
note: "'newTVarIO' is already exported from Relude"
rhs: newTVarIO
- warn:
lhs: Control.Concurrent.STM.TVar.readTVarIO
name: "Use 'readTVarIO' from Relude"
note: "'readTVarIO' is already exported from Relude"
rhs: readTVarIO
- warn:
lhs: "Control.Concurrent.STM.TVar.modifyTVar'"
name: "Use 'modifyTVar'' from Relude"
note: "'modifyTVar'' is already exported from Relude"
rhs: "modifyTVar'"
- warn:
lhs: Control.Concurrent.STM.TVar.newTVar
name: "Use 'newTVar' from Relude"
note: "'newTVar' is already exported from Relude"
rhs: newTVar
- warn:
lhs: Control.Concurrent.STM.TVar.readTVar
name: "Use 'readTVar' from Relude"
note: "'readTVar' is already exported from Relude"
rhs: readTVar
- warn:
lhs: Control.Concurrent.STM.TVar.writeTVar
name: "Use 'writeTVar' from Relude"
note: "'writeTVar' is already exported from Relude"
rhs: writeTVar
- warn:
lhs: Control.Concurrent.STM.TMVar.TMVar
name: "Use 'TMVar' from Relude"
note: "'TMVar' is already exported from Relude"
rhs: TMVar
- warn:
lhs: Control.Concurrent.STM.TMVar.newTMVar
name: "Use 'newTMVar' from Relude"
note: "'newTMVar' is already exported from Relude"
rhs: newTMVar
- warn:
lhs: Control.Concurrent.STM.TMVar.newEmptyTMVar
name: "Use 'newEmptyTMVar' from Relude"
note: "'newEmptyTMVar' is already exported from Relude"
rhs: newEmptyTMVar
- warn:
lhs: Control.Concurrent.STM.TMVar.newTMVarIO
name: "Use 'newTMVarIO' from Relude"
note: "'newTMVarIO' is already exported from Relude"
rhs: newTMVarIO
- warn:
lhs: Control.Concurrent.STM.TMVar.newEmptyTMVarIO
name: "Use 'newEmptyTMVarIO' from Relude"
note: "'newEmptyTMVarIO' is already exported from Relude"
rhs: newEmptyTMVarIO
- warn:
lhs: Control.Concurrent.STM.TMVar.takeTMVar
name: "Use 'takeTMVar' from Relude"
note: "'takeTMVar' is already exported from Relude"
rhs: takeTMVar
- warn:
lhs: Control.Concurrent.STM.TMVar.putTMVar
name: "Use 'putTMVar' from Relude"
note: "'putTMVar' is already exported from Relude"
rhs: putTMVar
- warn:
lhs: Control.Concurrent.STM.TMVar.readTMVar
name: "Use 'readTMVar' from Relude"
note: "'readTMVar' is already exported from Relude"
rhs: readTMVar
- warn:
lhs: Control.Concurrent.STM.TMVar.tryReadTMVar
name: "Use 'tryReadTMVar' from Relude"
note: "'tryReadTMVar' is already exported from Relude"
rhs: tryReadTMVar
- warn:
lhs: Control.Concurrent.STM.TMVar.swapTMVar
name: "Use 'swapTMVar' from Relude"
note: "'swapTMVar' is already exported from Relude"
rhs: swapTMVar
- warn:
lhs: Control.Concurrent.STM.TMVar.tryTakeTMVar
name: "Use 'tryTakeTMVar' from Relude"
note: "'tryTakeTMVar' is already exported from Relude"
rhs: tryTakeTMVar
- warn:
lhs: Control.Concurrent.STM.TMVar.tryPutTMVar
name: "Use 'tryPutTMVar' from Relude"
note: "'tryPutTMVar' is already exported from Relude"
rhs: tryPutTMVar
- warn:
lhs: Control.Concurrent.STM.TMVar.isEmptyTMVar
name: "Use 'isEmptyTMVar' from Relude"
note: "'isEmptyTMVar' is already exported from Relude"
rhs: isEmptyTMVar
- warn:
lhs: Control.Concurrent.STM.TMVar.mkWeakTMVar
name: "Use 'mkWeakTMVar' from Relude"
note: "'mkWeakTMVar' is already exported from Relude"
rhs: mkWeakTMVar
- warn:
lhs: Data.IORef.IORef
name: "Use 'IORef' from Relude"
note: "'IORef' is already exported from Relude"
rhs: IORef
- warn:
lhs: Data.IORef.atomicModifyIORef
name: "Use 'atomicModifyIORef' from Relude"
note: "'atomicModifyIORef' is already exported from Relude"
rhs: atomicModifyIORef
- warn:
lhs: "Data.IORef.atomicModifyIORef'"
name: "Use 'atomicModifyIORef'' from Relude"
note: "'atomicModifyIORef'' is already exported from Relude"
rhs: "atomicModifyIORef'"
- warn:
lhs: Data.IORef.atomicWriteIORef
name: "Use 'atomicWriteIORef' from Relude"
note: "'atomicWriteIORef' is already exported from Relude"
rhs: atomicWriteIORef
- warn:
lhs: Data.IORef.modifyIORef
name: "Use 'modifyIORef' from Relude"
note: "'modifyIORef' is already exported from Relude"
rhs: modifyIORef
- warn:
lhs: "Data.IORef.modifyIORef'"
name: "Use 'modifyIORef'' from Relude"
note: "'modifyIORef'' is already exported from Relude"
rhs: "modifyIORef'"
- warn:
lhs: Data.IORef.newIORef
name: "Use 'newIORef' from Relude"
note: "'newIORef' is already exported from Relude"
rhs: newIORef
- warn:
lhs: Data.IORef.readIORef
name: "Use 'readIORef' from Relude"
note: "'readIORef' is already exported from Relude"
rhs: readIORef
- warn:
lhs: Data.IORef.writeIORef
name: "Use 'writeIORef' from Relude"
note: "'writeIORef' is already exported from Relude"
rhs: writeIORef
- warn:
lhs: "atomicModifyIORef ref (\\a -> (f a, mempty))"
rhs: atomicModifyIORef_ ref f
- warn:
lhs: "atomicModifyIORef ref $ \\a -> (f a, mempty)"
rhs: atomicModifyIORef_ ref f
- warn:
lhs: "atomicModifyIORef' ref $ \\a -> (f a, mempty)"
rhs: "atomicModifyIORef'_ ref f"
- warn:
lhs: "atomicModifyIORef' ref (\\a -> (f a, mempty))"
rhs: "atomicModifyIORef'_ ref f"
- warn:
lhs: Data.Text.IO.getLine
name: "Use 'getLine' from Relude"
note: "'getLine' is already exported from Relude"
rhs: getLine
- warn:
lhs: System.IO.hFlush
name: "Use 'hFlush' from Relude"
note: "'hFlush' is already exported from Relude"
rhs: hFlush
- warn:
lhs: System.IO.hIsEOF
name: "Use 'hIsEOF' from Relude"
note: "'hIsEOF' is already exported from Relude"
rhs: hIsEOF
- warn:
lhs: System.IO.hSetBuffering
name: "Use 'hSetBuffering' from Relude"
note: "'hSetBuffering' is already exported from Relude"
rhs: hSetBuffering
- warn:
lhs: System.IO.hGetBuffering
name: "Use 'hGetBuffering' from Relude"
note: "'hGetBuffering' is already exported from Relude"
rhs: hGetBuffering
- warn:
lhs: System.IO.Handle
name: "Use 'Handle' from Relude"
note: "'Handle' is already exported from Relude"
rhs: Handle
- warn:
lhs: System.IO.stdin
name: "Use 'stdin' from Relude"
note: "'stdin' is already exported from Relude"
rhs: stdin
- warn:
lhs: System.IO.stdout
name: "Use 'stdout' from Relude"
note: "'stdout' is already exported from Relude"
rhs: stdout
- warn:
lhs: System.IO.stderr
name: "Use 'stderr' from Relude"
note: "'stderr' is already exported from Relude"
rhs: stderr
- warn:
lhs: System.IO.withFile
name: "Use 'withFile' from Relude"
note: "'withFile' is already exported from Relude"
rhs: withFile
- warn:
lhs: System.IO.BufferMode
name: "Use 'BufferMode' from Relude"
note: "'BufferMode' is already exported from Relude"
rhs: BufferMode
- warn:
lhs: System.Environment.getArgs
name: "Use 'getArgs' from Relude"
note: "'getArgs' is already exported from Relude"
rhs: getArgs
- warn:
lhs: System.Environment.lookupEnv
name: "Use 'lookupEnv' from Relude"
note: "'lookupEnv' is already exported from Relude"
rhs: lookupEnv
- warn:
lhs: Data.List.genericDrop
name: "Use 'genericDrop' from Relude"
note: "'genericDrop' is already exported from Relude"
rhs: genericDrop
- warn:
lhs: Data.List.genericLength
name: "Use 'genericLength' from Relude"
note: "'genericLength' is already exported from Relude"
rhs: genericLength
- warn:
lhs: Data.List.genericReplicate
name: "Use 'genericReplicate' from Relude"
note: "'genericReplicate' is already exported from Relude"
rhs: genericReplicate
- warn:
lhs: Data.List.genericSplitAt
name: "Use 'genericSplitAt' from Relude"
note: "'genericSplitAt' is already exported from Relude"
rhs: genericSplitAt
- warn:
lhs: Data.List.genericTake
name: "Use 'genericTake' from Relude"
note: "'genericTake' is already exported from Relude"
rhs: genericTake
- warn:
lhs: Data.List.group
name: "Use 'group' from Relude"
note: "'group' is already exported from Relude"
rhs: group
- warn:
lhs: Data.List.inits
name: "Use 'inits' from Relude"
note: "'inits' is already exported from Relude"
rhs: inits
- warn:
lhs: Data.List.intercalate
name: "Use 'intercalate' from Relude"
note: "'intercalate' is already exported from Relude"
rhs: intercalate
- warn:
lhs: Data.List.intersperse
name: "Use 'intersperse' from Relude"
note: "'intersperse' is already exported from Relude"
rhs: intersperse
- warn:
lhs: Data.List.isPrefixOf
name: "Use 'isPrefixOf' from Relude"
note: "'isPrefixOf' is already exported from Relude"
rhs: isPrefixOf
- warn:
lhs: Data.List.permutations
name: "Use 'permutations' from Relude"
note: "'permutations' is already exported from Relude"
rhs: permutations
- warn:
lhs: "Data.List.scanl'"
name: "Use 'scanl'' from Relude"
note: "'scanl'' is already exported from Relude"
rhs: "scanl'"
- warn:
lhs: Data.List.sort
name: "Use 'sort' from Relude"
note: "'sort' is already exported from Relude"
rhs: sort
- warn:
lhs: Data.List.sortBy
name: "Use 'sortBy' from Relude"
note: "'sortBy' is already exported from Relude"
rhs: sortBy
- warn:
lhs: Data.List.sortOn
name: "Use 'sortOn' from Relude"
note: "'sortOn' is already exported from Relude"
rhs: sortOn
- warn:
lhs: Data.List.subsequences
name: "Use 'subsequences' from Relude"
note: "'subsequences' is already exported from Relude"
rhs: subsequences
- warn:
lhs: Data.List.tails
name: "Use 'tails' from Relude"
note: "'tails' is already exported from Relude"
rhs: tails
- warn:
lhs: Data.List.transpose
name: "Use 'transpose' from Relude"
note: "'transpose' is already exported from Relude"
rhs: transpose
- warn:
lhs: Data.List.uncons
name: "Use 'uncons' from Relude"
note: "'uncons' is already exported from Relude"
rhs: uncons
- warn:
lhs: Data.List.unfoldr
name: "Use 'unfoldr' from Relude"
note: "'unfoldr' is already exported from Relude"
rhs: unfoldr
- warn:
lhs: Data.List.NonEmpty.NonEmpty
name: "Use 'NonEmpty' from Relude"
note: "'NonEmpty' is already exported from Relude"
rhs: NonEmpty
- warn:
lhs: "(Data.List.NonEmpty.:|)"
name: "Use ':|' from Relude"
note: "Operator '(:|)' is already exported from Relude"
rhs: "(:|)"
- warn:
lhs: Data.List.NonEmpty.nonEmpty
name: "Use 'nonEmpty' from Relude"
note: "'nonEmpty' is already exported from Relude"
rhs: nonEmpty
- warn:
lhs: Data.List.NonEmpty.head
name: "Use 'head' from Relude"
note: "'head' is already exported from Relude"
rhs: head
- warn:
lhs: Data.List.NonEmpty.init
name: "Use 'init' from Relude"
note: "'init' is already exported from Relude"
rhs: init
- warn:
lhs: Data.List.NonEmpty.last
name: "Use 'last' from Relude"
note: "'last' is already exported from Relude"
rhs: last
- warn:
lhs: Data.List.NonEmpty.tail
name: "Use 'tail' from Relude"
note: "'tail' is already exported from Relude"
rhs: tail
- warn:
lhs: GHC.Exts.sortWith
name: "Use 'sortWith' from Relude"
note: "'sortWith' is already exported from Relude"
rhs: sortWith
- warn:
lhs: Control.Monad.Except.ExceptT
name: "Use 'ExceptT' from Relude"
note: "'ExceptT' is already exported from Relude"
rhs: ExceptT
- warn:
lhs: Control.Monad.Except.runExceptT
name: "Use 'runExceptT' from Relude"
note: "'runExceptT' is already exported from Relude"
rhs: runExceptT
- warn:
lhs: Control.Monad.Reader.MonadReader
name: "Use 'MonadReader' from Relude"
note: "'MonadReader' is already exported from Relude"
rhs: MonadReader
- warn:
lhs: Control.Monad.Reader.Reader
name: "Use 'Reader' from Relude"
note: "'Reader' is already exported from Relude"
rhs: Reader
- warn:
lhs: Control.Monad.Reader.ReaderT
name: "Use 'ReaderT' from Relude"
note: "'ReaderT' is already exported from Relude"
rhs: ReaderT
- warn:
lhs: Control.Monad.Reader.runReaderT
name: "Use 'runReaderT' from Relude"
note: "'runReaderT' is already exported from Relude"
rhs: runReaderT
- warn:
lhs: Control.Monad.Reader.ask
name: "Use 'ask' from Relude"
note: "'ask' is already exported from Relude"
rhs: ask
- warn:
lhs: Control.Monad.Reader.asks
name: "Use 'asks' from Relude"
note: "'asks' is already exported from Relude"
rhs: asks
- warn:
lhs: Control.Monad.Reader.local
name: "Use 'local' from Relude"
note: "'local' is already exported from Relude"
rhs: local
- warn:
lhs: Control.Monad.Reader.reader
name: "Use 'reader' from Relude"
note: "'reader' is already exported from Relude"
rhs: reader
- warn:
lhs: Control.Monad.Reader.runReader
name: "Use 'runReader' from Relude"
note: "'runReader' is already exported from Relude"
rhs: runReader
- warn:
lhs: Control.Monad.Reader.withReader
name: "Use 'withReader' from Relude"
note: "'withReader' is already exported from Relude"
rhs: withReader
- warn:
lhs: Control.Monad.Reader.withReaderT
name: "Use 'withReaderT' from Relude"
note: "'withReaderT' is already exported from Relude"
rhs: withReaderT
- warn:
lhs: Control.Monad.State.Strict.MonadState
name: "Use 'MonadState' from Relude"
note: "'MonadState' is already exported from Relude"
rhs: MonadState
- warn:
lhs: Control.Monad.State.Strict.State
name: "Use 'State' from Relude"
note: "'State' is already exported from Relude"
rhs: State
- warn:
lhs: Control.Monad.State.Strict.StateT
name: "Use 'StateT' from Relude"
note: "'StateT' is already exported from Relude"
rhs: StateT
- warn:
lhs: Control.Monad.State.Strict.runStateT
name: "Use 'runStateT' from Relude"
note: "'runStateT' is already exported from Relude"
rhs: runStateT
- warn:
lhs: Control.Monad.State.Strict.evalState
name: "Use 'evalState' from Relude"
note: "'evalState' is already exported from Relude"
rhs: evalState
- warn:
lhs: Control.Monad.State.Strict.evalStateT
name: "Use 'evalStateT' from Relude"
note: "'evalStateT' is already exported from Relude"
rhs: evalStateT
- warn:
lhs: Control.Monad.State.Strict.execState
name: "Use 'execState' from Relude"
note: "'execState' is already exported from Relude"
rhs: execState
- warn:
lhs: Control.Monad.State.Strict.execStateT
name: "Use 'execStateT' from Relude"
note: "'execStateT' is already exported from Relude"
rhs: execStateT
- warn:
lhs: Control.Monad.State.Strict.get
name: "Use 'get' from Relude"
note: "'get' is already exported from Relude"
rhs: get
- warn:
lhs: Control.Monad.State.Strict.gets
name: "Use 'gets' from Relude"
note: "'gets' is already exported from Relude"
rhs: gets
- warn:
lhs: Control.Monad.State.Strict.modify
name: "Use 'modify' from Relude"
note: "'modify' is already exported from Relude"
rhs: modify
- warn:
lhs: "Control.Monad.State.Strict.modify'"
name: "Use 'modify'' from Relude"
note: "'modify'' is already exported from Relude"
rhs: "modify'"
- warn:
lhs: Control.Monad.State.Strict.put
name: "Use 'put' from Relude"
note: "'put' is already exported from Relude"
rhs: put
- warn:
lhs: Control.Monad.State.Strict.runState
name: "Use 'runState' from Relude"
note: "'runState' is already exported from Relude"
rhs: runState
- warn:
lhs: Control.Monad.State.Strict.state
name: "Use 'state' from Relude"
note: "'state' is already exported from Relude"
rhs: state
- warn:
lhs: Control.Monad.State.Strict.withState
name: "Use 'withState' from Relude"
note: "'withState' is already exported from Relude"
rhs: withState
- warn:
lhs: Control.Monad.Trans.MonadIO
name: "Use 'MonadIO' from Relude"
note: "'MonadIO' is already exported from Relude"
rhs: MonadIO
- warn:
lhs: Control.Monad.Trans.MonadTrans
name: "Use 'MonadTrans' from Relude"
note: "'MonadTrans' is already exported from Relude"
rhs: MonadTrans
- warn:
lhs: Control.Monad.Trans.lift
name: "Use 'lift' from Relude"
note: "'lift' is already exported from Relude"
rhs: lift
- warn:
lhs: Control.Monad.Trans.liftIO
name: "Use 'liftIO' from Relude"
note: "'liftIO' is already exported from Relude"
rhs: liftIO
- warn:
lhs: Control.Monad.Trans.Identity.IdentityT
name: "Use 'IdentityT' from Relude"
note: "'IdentityT' is already exported from Relude"
rhs: IdentityT
- warn:
lhs: Control.Monad.Trans.Identity.runIdentityT
name: "Use 'runIdentityT' from Relude"
note: "'runIdentityT' is already exported from Relude"
rhs: runIdentityT
- warn:
lhs: Control.Monad.Trans.Maybe.MaybeT
name: "Use 'MaybeT' from Relude"
note: "'MaybeT' is already exported from Relude"
rhs: MaybeT
- warn:
lhs: Control.Monad.Trans.Maybe.maybeToExceptT
name: "Use 'maybeToExceptT' from Relude"
note: "'maybeToExceptT' is already exported from Relude"
rhs: maybeToExceptT
- warn:
lhs: Control.Monad.Trans.Maybe.exceptToMaybeT
name: "Use 'exceptToMaybeT' from Relude"
note: "'exceptToMaybeT' is already exported from Relude"
rhs: exceptToMaybeT
- warn:
lhs: Control.Monad.MonadPlus
name: "Use 'MonadPlus' from Relude"
note: "'MonadPlus' is already exported from Relude"
rhs: MonadPlus
- warn:
lhs: Control.Monad.mzero
name: "Use 'mzero' from Relude"
note: "'mzero' is already exported from Relude"
rhs: mzero
- warn:
lhs: Control.Monad.mplus
name: "Use 'mplus' from Relude"
note: "'mplus' is already exported from Relude"
rhs: mplus
- warn:
lhs: Control.Monad.filterM
name: "Use 'filterM' from Relude"
note: "'filterM' is already exported from Relude"
rhs: filterM
- warn:
lhs: Control.Monad.forever
name: "Use 'forever' from Relude"
note: "'forever' is already exported from Relude"
rhs: forever
- warn:
lhs: Control.Monad.join
name: "Use 'join' from Relude"
note: "'join' is already exported from Relude"
rhs: join
- warn:
lhs: Control.Monad.mapAndUnzipM
name: "Use 'mapAndUnzipM' from Relude"
note: "'mapAndUnzipM' is already exported from Relude"
rhs: mapAndUnzipM
- warn:
lhs: Control.Monad.mfilter
name: "Use 'mfilter' from Relude"
note: "'mfilter' is already exported from Relude"
rhs: mfilter
- warn:
lhs: Control.Monad.replicateM
name: "Use 'replicateM' from Relude"
note: "'replicateM' is already exported from Relude"
rhs: replicateM
- warn:
lhs: Control.Monad.replicateM_
name: "Use 'replicateM_' from Relude"
note: "'replicateM_' is already exported from Relude"
rhs: replicateM_
- warn:
lhs: Control.Monad.zipWithM
name: "Use 'zipWithM' from Relude"
note: "'zipWithM' is already exported from Relude"
rhs: zipWithM
- warn:
lhs: Control.Monad.zipWithM_
name: "Use 'zipWithM_' from Relude"
note: "'zipWithM_' is already exported from Relude"
rhs: zipWithM_
- warn:
lhs: "(Control.Monad.<$!>)"
name: "Use '<$!>' from Relude"
note: "Operator '(<$!>)' is already exported from Relude"
rhs: "(<$!>)"
- warn:
lhs: "(Control.Monad.<=<)"
name: "Use '<=<' from Relude"
note: "Operator '(<=<)' is already exported from Relude"
rhs: "(<=<)"
- warn:
lhs: "(Control.Monad.=<<)"
name: "Use '=<<' from Relude"
note: "Operator '(=<<)' is already exported from Relude"
rhs: "(=<<)"
- warn:
lhs: "(Control.Monad.>=>)"
name: "Use '>=>' from Relude"
note: "Operator '(>=>)' is already exported from Relude"
rhs: "(>=>)"
- warn:
lhs: Control.Monad.Fail.MonadFail
name: "Use 'MonadFail' from Relude"
note: "'MonadFail' is already exported from Relude"
rhs: MonadFail
- warn:
lhs: Data.Maybe.catMaybes
name: "Use 'catMaybes' from Relude"
note: "'catMaybes' is already exported from Relude"
rhs: catMaybes
- warn:
lhs: Data.Maybe.fromMaybe
name: "Use 'fromMaybe' from Relude"
note: "'fromMaybe' is already exported from Relude"
rhs: fromMaybe
- warn:
lhs: Data.Maybe.isJust
name: "Use 'isJust' from Relude"
note: "'isJust' is already exported from Relude"
rhs: isJust
- warn:
lhs: Data.Maybe.isNothing
name: "Use 'isNothing' from Relude"
note: "'isNothing' is already exported from Relude"
rhs: isNothing
- warn:
lhs: Data.Maybe.listToMaybe
name: "Use 'listToMaybe' from Relude"
note: "'listToMaybe' is already exported from Relude"
rhs: listToMaybe
- warn:
lhs: Data.Maybe.mapMaybe
name: "Use 'mapMaybe' from Relude"
note: "'mapMaybe' is already exported from Relude"
rhs: mapMaybe
- warn:
lhs: Data.Maybe.maybeToList
name: "Use 'maybeToList' from Relude"
note: "'maybeToList' is already exported from Relude"
rhs: maybeToList
- warn:
lhs: Data.Either.isLeft
name: "Use 'isLeft' from Relude"
note: "'isLeft' is already exported from Relude"
rhs: isLeft
- warn:
lhs: Data.Either.isRight
name: "Use 'isRight' from Relude"
note: "'isRight' is already exported from Relude"
rhs: isRight
- warn:
lhs: Data.Either.lefts
name: "Use 'lefts' from Relude"
note: "'lefts' is already exported from Relude"
rhs: lefts
- warn:
lhs: Data.Either.partitionEithers
name: "Use 'partitionEithers' from Relude"
note: "'partitionEithers' is already exported from Relude"
rhs: partitionEithers
- warn:
lhs: Data.Either.rights
name: "Use 'rights' from Relude"
note: "'rights' is already exported from Relude"
rhs: rights
- warn:
lhs: Data.Monoid.All
name: "Use 'All' from Relude"
note: "'All' is already exported from Relude"
rhs: All
- warn:
lhs: Data.Monoid.getAll
name: "Use 'getAll' from Relude"
note: "'getAll' is already exported from Relude"
rhs: getAll
- warn:
lhs: Data.Monoid.Alt
name: "Use 'Alt' from Relude"
note: "'Alt' is already exported from Relude"
rhs: Alt
- warn:
lhs: Data.Monoid.getAlt
name: "Use 'getAlt' from Relude"
note: "'getAlt' is already exported from Relude"
rhs: getAlt
- warn:
lhs: Data.Monoid.Any
name: "Use 'Any' from Relude"
note: "'Any' is already exported from Relude"
rhs: Any
- warn:
lhs: Data.Monoid.getAny
name: "Use 'getAny' from Relude"
note: "'getAny' is already exported from Relude"
rhs: getAny
- warn:
lhs: Data.Monoid.Ap
name: "Use 'Ap' from Relude"
note: "'Ap' is already exported from Relude"
rhs: Ap
- warn:
lhs: Data.Monoid.getAp
name: "Use 'getAp' from Relude"
note: "'getAp' is already exported from Relude"
rhs: getAp
- warn:
lhs: Data.Monoid.Dual
name: "Use 'Dual' from Relude"
note: "'Dual' is already exported from Relude"
rhs: Dual
- warn:
lhs: Data.Monoid.getDual
name: "Use 'getDual' from Relude"
note: "'getDual' is already exported from Relude"
rhs: getDual
- warn:
lhs: Data.Monoid.Endo
name: "Use 'Endo' from Relude"
note: "'Endo' is already exported from Relude"
rhs: Endo
- warn:
lhs: Data.Monoid.appEndo
name: "Use 'appEndo' from Relude"
note: "'appEndo' is already exported from Relude"
rhs: appEndo
- warn:
lhs: Data.Monoid.First
name: "Use 'First' from Relude"
note: "'First' is already exported from Relude"
rhs: First
- warn:
lhs: Data.Monoid.getFirst
name: "Use 'getFirst' from Relude"
note: "'getFirst' is already exported from Relude"
rhs: getFirst
- warn:
lhs: Data.Monoid.Last
name: "Use 'Last' from Relude"
note: "'Last' is already exported from Relude"
rhs: Last
- warn:
lhs: Data.Monoid.getLast
name: "Use 'getLast' from Relude"
note: "'getLast' is already exported from Relude"
rhs: getLast
- warn:
lhs: Data.Monoid.Product
name: "Use 'Product' from Relude"
note: "'Product' is already exported from Relude"
rhs: Product
- warn:
lhs: Data.Monoid.getProduct
name: "Use 'getProduct' from Relude"
note: "'getProduct' is already exported from Relude"
rhs: getProduct
- warn:
lhs: Data.Monoid.Sum
name: "Use 'Sum' from Relude"
note: "'Sum' is already exported from Relude"
rhs: Sum
- warn:
lhs: Data.Monoid.getSum
name: "Use 'getSum' from Relude"
note: "'getSum' is already exported from Relude"
rhs: getSum
- warn:
lhs: Data.Semigroup.Option
name: "Use 'Option' from Relude"
note: "'Option' is already exported from Relude"
rhs: Option
- warn:
lhs: Data.Semigroup.getOption
name: "Use 'getOption' from Relude"
note: "'getOption' is already exported from Relude"
rhs: getOption
- warn:
lhs: Data.Semigroup.Semigroup
name: "Use 'Semigroup' from Relude"
note: "'Semigroup' is already exported from Relude"
rhs: Semigroup
- warn:
lhs: Data.Semigroup.sconcat
name: "Use 'sconcat' from Relude"
note: "'sconcat' is already exported from Relude"
rhs: sconcat
- warn:
lhs: Data.Semigroup.stimes
name: "Use 'stimes' from Relude"
note: "'stimes' is already exported from Relude"
rhs: stimes
- warn:
lhs: "(Data.Semigroup.<>)"
name: "Use '<>' from Relude"
note: "Operator '(<>)' is already exported from Relude"
rhs: "(<>)"
- warn:
lhs: Data.Semigroup.WrappedMonoid
name: "Use 'WrappedMonoid' from Relude"
note: "'WrappedMonoid' is already exported from Relude"
rhs: WrappedMonoid
- warn:
lhs: Data.Semigroup.cycle1
name: "Use 'cycle1' from Relude"
note: "'cycle1' is already exported from Relude"
rhs: cycle1
- warn:
lhs: Data.Semigroup.mtimesDefault
name: "Use 'mtimesDefault' from Relude"
note: "'mtimesDefault' is already exported from Relude"
rhs: mtimesDefault
- warn:
lhs: Data.Semigroup.stimesIdempotent
name: "Use 'stimesIdempotent' from Relude"
note: "'stimesIdempotent' is already exported from Relude"
rhs: stimesIdempotent
- warn:
lhs: Data.Semigroup.stimesIdempotentMonoid
name: "Use 'stimesIdempotentMonoid' from Relude"
note: "'stimesIdempotentMonoid' is already exported from Relude"
rhs: stimesIdempotentMonoid
- warn:
lhs: Data.Semigroup.stimesMonoid
name: "Use 'stimesMonoid' from Relude"
note: "'stimesMonoid' is already exported from Relude"
rhs: stimesMonoid
- warn:
lhs: Data.ByteString.ByteString
name: "Use 'ByteString' from Relude"
note: "'ByteString' is already exported from Relude"
rhs: ByteString
- warn:
lhs: Data.ByteString.Short.ShortByteString
name: "Use 'ShortByteString' from Relude"
note: "'ShortByteString' is already exported from Relude"
rhs: ShortByteString
- warn:
lhs: Data.ByteString.Short.toShort
name: "Use 'toShort' from Relude"
note: "'toShort' is already exported from Relude"
rhs: toShort
- warn:
lhs: Data.ByteString.Short.fromShort
name: "Use 'fromShort' from Relude"
note: "'fromShort' is already exported from Relude"
rhs: fromShort
- warn:
lhs: Data.String.IsString
name: "Use 'IsString' from Relude"
note: "'IsString' is already exported from Relude"
rhs: IsString
- warn:
lhs: Data.String.fromString
name: "Use 'fromString' from Relude"
note: "'fromString' is already exported from Relude"
rhs: fromString
- warn:
lhs: Data.Text.Text
name: "Use 'Text' from Relude"
note: "'Text' is already exported from Relude"
rhs: Text
- warn:
lhs: Data.Text.lines
name: "Use 'lines' from Relude"
note: "'lines' is already exported from Relude"
rhs: lines
- warn:
lhs: Data.Text.unlines
name: "Use 'unlines' from Relude"
note: "'unlines' is already exported from Relude"
rhs: unlines
- warn:
lhs: Data.Text.words
name: "Use 'words' from Relude"
note: "'words' is already exported from Relude"
rhs: words
- warn:
lhs: Data.Text.unwords
name: "Use 'unwords' from Relude"
note: "'unwords' is already exported from Relude"
rhs: unwords
- warn:
lhs: "Data.Text.Encoding.decodeUtf8'"
name: "Use 'decodeUtf8'' from Relude"
note: "'decodeUtf8'' is already exported from Relude"
rhs: "decodeUtf8'"
- warn:
lhs: Data.Text.Encoding.decodeUtf8With
name: "Use 'decodeUtf8With' from Relude"
note: "'decodeUtf8With' is already exported from Relude"
rhs: decodeUtf8With
- warn:
lhs: Data.Text.Encoding.Error.OnDecodeError
name: "Use 'OnDecodeError' from Relude"
note: "'OnDecodeError' is already exported from Relude"
rhs: OnDecodeError
- warn:
lhs: Data.Text.Encoding.Error.OnError
name: "Use 'OnError' from Relude"
note: "'OnError' is already exported from Relude"
rhs: OnError
- warn:
lhs: Data.Text.Encoding.Error.UnicodeException
name: "Use 'UnicodeException' from Relude"
note: "'UnicodeException' is already exported from Relude"
rhs: UnicodeException
- warn:
lhs: Data.Text.Encoding.Error.lenientDecode
name: "Use 'lenientDecode' from Relude"
note: "'lenientDecode' is already exported from Relude"
rhs: lenientDecode
- warn:
lhs: Data.Text.Encoding.Error.strictDecode
name: "Use 'strictDecode' from Relude"
note: "'strictDecode' is already exported from Relude"
rhs: strictDecode
- warn:
lhs: Text.Read.Read
name: "Use 'Read' from Relude"
note: "'Read' is already exported from Relude"
rhs: Read
- warn:
lhs: Text.Read.readMaybe
name: "Use 'readMaybe' from Relude"
note: "'readMaybe' is already exported from Relude"
rhs: readMaybe
- warn:
lhs: "(liftIO (newEmptyMVar ))"
name: "'liftIO' is not needed"
note: "If you import 'newEmptyMVar' from Relude, it's already lifted"
rhs: newEmptyMVar
- warn:
lhs: "(liftIO (newMVar x))"
name: "'liftIO' is not needed"
note: "If you import 'newMVar' from Relude, it's already lifted"
rhs: newMVar
- warn:
lhs: "(liftIO (putMVar x y))"
name: "'liftIO' is not needed"
note: "If you import 'putMVar' from Relude, it's already lifted"
rhs: putMVar
- warn:
lhs: "(liftIO (readMVar x))"
name: "'liftIO' is not needed"
note: "If you import 'readMVar' from Relude, it's already lifted"
rhs: readMVar
- warn:
lhs: "(liftIO (swapMVar x y))"
name: "'liftIO' is not needed"
note: "If you import 'swapMVar' from Relude, it's already lifted"
rhs: swapMVar
- warn:
lhs: "(liftIO (takeMVar x))"
name: "'liftIO' is not needed"
note: "If you import 'takeMVar' from Relude, it's already lifted"
rhs: takeMVar
- warn:
lhs: "(liftIO (tryPutMVar x y))"
name: "'liftIO' is not needed"
note: "If you import 'tryPutMVar' from Relude, it's already lifted"
rhs: tryPutMVar
- warn:
lhs: "(liftIO (tryReadMVar x))"
name: "'liftIO' is not needed"
note: "If you import 'tryReadMVar' from Relude, it's already lifted"
rhs: tryReadMVar
- warn:
lhs: "(liftIO (tryTakeMVar x))"
name: "'liftIO' is not needed"
note: "If you import 'tryTakeMVar' from Relude, it's already lifted"
rhs: tryTakeMVar
- warn:
lhs: "(liftIO (atomically x))"
name: "'liftIO' is not needed"
note: "If you import 'atomically' from Relude, it's already lifted"
rhs: atomically
- warn:
lhs: "(liftIO (newTVarIO x))"
name: "'liftIO' is not needed"
note: "If you import 'newTVarIO' from Relude, it's already lifted"
rhs: newTVarIO
- warn:
lhs: "(liftIO (readTVarIO x))"
name: "'liftIO' is not needed"
note: "If you import 'readTVarIO' from Relude, it's already lifted"
rhs: readTVarIO
- warn:
lhs: "(liftIO (newTMVarIO x))"
name: "'liftIO' is not needed"
note: "If you import 'newTMVarIO' from Relude, it's already lifted"
rhs: newTMVarIO
- warn:
lhs: "(liftIO (newEmptyTMVarIO ))"
name: "'liftIO' is not needed"
note: "If you import 'newEmptyTMVarIO' from Relude, it's already lifted"
rhs: newEmptyTMVarIO
- warn:
lhs: "(liftIO (exitWith x))"
name: "'liftIO' is not needed"
note: "If you import 'exitWith' from Relude, it's already lifted"
rhs: exitWith
- warn:
lhs: "(liftIO (exitFailure ))"
name: "'liftIO' is not needed"
note: "If you import 'exitFailure' from Relude, it's already lifted"
rhs: exitFailure
- warn:
lhs: "(liftIO (exitSuccess ))"
name: "'liftIO' is not needed"
note: "If you import 'exitSuccess' from Relude, it's already lifted"
rhs: exitSuccess
- warn:
lhs: "(liftIO (die x))"
name: "'liftIO' is not needed"
note: "If you import 'die' from Relude, it's already lifted"
rhs: die
- warn:
lhs: "(liftIO (readFile x))"
name: "'liftIO' is not needed"
note: "If you import 'readFile' from Relude, it's already lifted"
rhs: readFile
- warn:
lhs: "(liftIO (writeFile x y))"
name: "'liftIO' is not needed"
note: "If you import 'writeFile' from Relude, it's already lifted"
rhs: writeFile
- warn:
lhs: "(liftIO (appendFile x y))"
name: "'liftIO' is not needed"
note: "If you import 'appendFile' from Relude, it's already lifted"
rhs: appendFile
- warn:
lhs: "(liftIO (readFileText x))"
name: "'liftIO' is not needed"
note: "If you import 'readFileText' from Relude, it's already lifted"
rhs: readFileText
- warn:
lhs: "(liftIO (writeFileText x y))"
name: "'liftIO' is not needed"
note: "If you import 'writeFileText' from Relude, it's already lifted"
rhs: writeFileText
- warn:
lhs: "(liftIO (appendFileText x y))"
name: "'liftIO' is not needed"
note: "If you import 'appendFileText' from Relude, it's already lifted"
rhs: appendFileText
- warn:
lhs: "(liftIO (readFileLText x))"
name: "'liftIO' is not needed"
note: "If you import 'readFileLText' from Relude, it's already lifted"
rhs: readFileLText
- warn:
lhs: "(liftIO (writeFileLText x y))"
name: "'liftIO' is not needed"
note: "If you import 'writeFileLText' from Relude, it's already lifted"
rhs: writeFileLText
- warn:
lhs: "(liftIO (appendFileLText x y))"
name: "'liftIO' is not needed"
note: "If you import 'appendFileLText' from Relude, it's already lifted"
rhs: appendFileLText
- warn:
lhs: "(liftIO (readFileBS x))"
name: "'liftIO' is not needed"
note: "If you import 'readFileBS' from Relude, it's already lifted"
rhs: readFileBS
- warn:
lhs: "(liftIO (writeFileBS x y))"
name: "'liftIO' is not needed"
note: "If you import 'writeFileBS' from Relude, it's already lifted"
rhs: writeFileBS
- warn:
lhs: "(liftIO (appendFileBS x y))"
name: "'liftIO' is not needed"
note: "If you import 'appendFileBS' from Relude, it's already lifted"
rhs: appendFileBS
- warn:
lhs: "(liftIO (readFileLBS x))"
name: "'liftIO' is not needed"
note: "If you import 'readFileLBS' from Relude, it's already lifted"
rhs: readFileLBS
- warn:
lhs: "(liftIO (writeFileLBS x y))"
name: "'liftIO' is not needed"
note: "If you import 'writeFileLBS' from Relude, it's already lifted"
rhs: writeFileLBS
- warn:
lhs: "(liftIO (appendFileLBS x y))"
name: "'liftIO' is not needed"
note: "If you import 'appendFileLBS' from Relude, it's already lifted"
rhs: appendFileLBS
- warn:
lhs: "(liftIO (newIORef x))"
name: "'liftIO' is not needed"
note: "If you import 'newIORef' from Relude, it's already lifted"
rhs: newIORef
- warn:
lhs: "(liftIO (readIORef x))"
name: "'liftIO' is not needed"
note: "If you import 'readIORef' from Relude, it's already lifted"
rhs: readIORef
- warn:
lhs: "(liftIO (writeIORef x y))"
name: "'liftIO' is not needed"
note: "If you import 'writeIORef' from Relude, it's already lifted"
rhs: writeIORef
- warn:
lhs: "(liftIO (modifyIORef x y))"
name: "'liftIO' is not needed"
note: "If you import 'modifyIORef' from Relude, it's already lifted"
rhs: modifyIORef
- warn:
lhs: "(liftIO (modifyIORef' x y))"
name: "'liftIO' is not needed"
note: "If you import 'modifyIORef'' from Relude, it's already lifted"
rhs: "modifyIORef'"
- warn:
lhs: "(liftIO (atomicModifyIORef x y))"
name: "'liftIO' is not needed"
note: "If you import 'atomicModifyIORef' from Relude, it's already lifted"
rhs: atomicModifyIORef
- warn:
lhs: "(liftIO (atomicModifyIORef' x y))"
name: "'liftIO' is not needed"
note: "If you import 'atomicModifyIORef'' from Relude, it's already lifted"
rhs: "atomicModifyIORef'"
- warn:
lhs: "(liftIO (atomicWriteIORef x y))"
name: "'liftIO' is not needed"
note: "If you import 'atomicWriteIORef' from Relude, it's already lifted"
rhs: atomicWriteIORef
- warn:
lhs: "(liftIO (getLine ))"
name: "'liftIO' is not needed"
note: "If you import 'getLine' from Relude, it's already lifted"
rhs: getLine
- warn:
lhs: "(liftIO (print x))"
name: "'liftIO' is not needed"
note: "If you import 'print' from Relude, it's already lifted"
rhs: print
- warn:
lhs: "(liftIO (putStr x))"
name: "'liftIO' is not needed"
note: "If you import 'putStr' from Relude, it's already lifted"
rhs: putStr
- warn:
lhs: "(liftIO (putStrLn x))"
name: "'liftIO' is not needed"
note: "If you import 'putStrLn' from Relude, it's already lifted"
rhs: putStrLn
- warn:
lhs: "(liftIO (putText x))"
name: "'liftIO' is not needed"
note: "If you import 'putText' from Relude, it's already lifted"
rhs: putText
- warn:
lhs: "(liftIO (putTextLn x))"
name: "'liftIO' is not needed"
note: "If you import 'putTextLn' from Relude, it's already lifted"
rhs: putTextLn
- warn:
lhs: "(liftIO (putLText x))"
name: "'liftIO' is not needed"
note: "If you import 'putLText' from Relude, it's already lifted"
rhs: putLText
- warn:
lhs: "(liftIO (putLTextLn x))"
name: "'liftIO' is not needed"
note: "If you import 'putLTextLn' from Relude, it's already lifted"
rhs: putLTextLn
- warn:
lhs: "(liftIO (putBS x))"
name: "'liftIO' is not needed"
note: "If you import 'putBS' from Relude, it's already lifted"
rhs: putBS
- warn:
lhs: "(liftIO (putBSLn x))"
name: "'liftIO' is not needed"
note: "If you import 'putBSLn' from Relude, it's already lifted"
rhs: putBSLn
- warn:
lhs: "(liftIO (putLBS x))"
name: "'liftIO' is not needed"
note: "If you import 'putLBS' from Relude, it's already lifted"
rhs: putLBS
- warn:
lhs: "(liftIO (putLBSLn x))"
name: "'liftIO' is not needed"
note: "If you import 'putLBSLn' from Relude, it's already lifted"
rhs: putLBSLn
- warn:
lhs: "(liftIO (hFlush x))"
name: "'liftIO' is not needed"
note: "If you import 'hFlush' from Relude, it's already lifted"
rhs: hFlush
- warn:
lhs: "(liftIO (hIsEOF x))"
name: "'liftIO' is not needed"
note: "If you import 'hIsEOF' from Relude, it's already lifted"
rhs: hIsEOF
- warn:
lhs: "(liftIO (hSetBuffering x y))"
name: "'liftIO' is not needed"
note: "If you import 'hSetBuffering' from Relude, it's already lifted"
rhs: hSetBuffering
- warn:
lhs: "(liftIO (hGetBuffering x))"
name: "'liftIO' is not needed"
note: "If you import 'hGetBuffering' from Relude, it's already lifted"
rhs: hGetBuffering
- warn:
lhs: "(liftIO (getArgs ))"
name: "'liftIO' is not needed"
note: "If you import 'getArgs' from Relude, it's already lifted"
rhs: getArgs
- warn:
lhs: "(liftIO (lookupEnv x))"
name: "'liftIO' is not needed"
note: "If you import 'lookupEnv' from Relude, it's already lifted"
rhs: lookupEnv
- hint:
lhs: "fmap (bimap f g)"
note: "Use `bimapF` from `Relude.Extra.Bifunctor`"
rhs: bimapF f g
- hint:
lhs: "bimap f g <$> x"
note: "Use `bimapF` from `Relude.Extra.Bifunctor`"
rhs: bimapF f g x
- hint:
lhs: "fmap (first f)"
note: "Use `firstF` from `Relude.Extra.Bifunctor`"
rhs: firstF f
- hint:
lhs: fmap . first
note: "Use `firstF` from `Relude.Extra.Bifunctor`"
rhs: firstF
- hint:
lhs: "fmap (second f)"
note: "Use `secondF` from `Relude.Extra.Bifunctor`"
rhs: secondF f
- hint:
lhs: fmap . second
note: "Use `secondF` from `Relude.Extra.Bifunctor`"
rhs: secondF
- hint:
lhs: "[minBound .. maxBound]"
note: "Use `universe` from `Relude.Extra.Enum`"
rhs: universe
- hint:
lhs: toEnum
note: "`toEnum` from `Prelude` is a pure function but it may throw exception. Consider using `safeToEnum` from `Relude.Extra.Enum` instead."
rhs: safeToEnum
- hint:
lhs: sum xs / length xs
note: "Use `average` from `Relude.Extra.Foldable`"
rhs: average xs
- hint:
lhs: "\\a -> (a, a)"
note: "Use `dup`"
rhs: dup
- warn:
lhs: "() <$ a"
rhs: void a
- hint:
lhs: "pass"
note: "Use 'stub'"
rhs: stub
- hint:
lhs: "bool mempty a b"
note: "Use `whenTrue`"
rhs: a `whenTrue` b
- hint:
lhs: "bool a mempty b"
note: "Use `whenFalse`"
rhs: a `whenFalse` b
- hint:
lhs: "maybe mempty a b"
note: "Use `whenJust`"
rhs: a `whenJust` b
- hint:
lhs: "(mempty, mempty)"
note: "Is `mempty`"
rhs: mempty
- hint:
lhs: "concat a"
note: "Use `fold`"
rhs: fold a
- hint:
lhs: "mconcat a"
note: "Use `fold`"
rhs: fold a
- hint:
lhs: "concatMap a"
note: "Use `foldMap`"
rhs: foldMap a
- hint:
lhs: "[a]"
note: "Use `one`"
rhs: (one a)
# Submitted upstream: https://github.com/ndmitchell/hlint/pull/1309 remove when merges
- hint:
lhs: "either Left f e"
note: "Use `=<<`"
rhs: f =<< e
- warn: {lhs: "init (one x)", rhs: "mempty", name: Evaluate}
- warn: {lhs: "null (one x)", rhs: "False", name: Evaluate}
- warn: {lhs: "foldr1 f (one x)", rhs: x, name: Evaluate}
- warn: {lhs: "scanr f z mempty", rhs: "one z", name: Evaluate}
- warn: {lhs: "scanr1 f mempty", rhs: "mempty", name: Evaluate}
- warn: {lhs: "scanr1 f (one x)", rhs: "one x", name: Evaluate}
- warn: {lhs: "fold (one a)", rhs: a, name: Evaluate}
- warn: {lhs: "cycle (one x)", rhs: repeat x}
- hint: {lhs: "\\x -> one x", rhs: "(one x)"}
- hint: {lhs: "elem x (one y)", rhs: x == y, note: ValidInstance Eq a}
- hint: {lhs: "notElem x (one y)", rhs: x /= y, note: ValidInstance Eq a}
- warn: {lhs: "sequenceA (one a)", rhs: "pure <$> a"}
- warn: {lhs: "head $ x <> one y", rhs: "headDef y x"}
- warn: {lhs: "pictures (one p)", rhs: p, name: Evaluate}
- hint:
lhs: "x : mempty"
note: "Use `one`"
rhs: one x
- hint:
lhs: "x :| mempty"
note: "Use `one`"
rhs: one x
- hint:
lhs: "join . fmap join"
note: "Monad law"
rhs: join . join
- hint:
lhs: "join . fmap pure"
note: "Monad law"
rhs: id
- hint:
lhs: "join . pure"
note: "Monad law"
rhs: id
- hint:
lhs: "join (f . pure)"
note: "Monad law"
rhs: (f =<< pure)
- hint:
lhs: "join . (f <<$>>)"
note: "Monad law"
rhs: fmap f . join
- hint:
lhs: "Data.Traversable.sequence"
note: "Modern name is `sequenceA`"
rhs: sequenceA
- hint:
lhs: "()"
note: "Use `mempty`"
rhs: mempty
- hint:
lhs: "return"
note: "Please, use `pure` instead. even GHC already deprecates `return` starting from `9.2`."
rhs: pure
- hint:
lhs: "map"
note: "Use `fmap`"
rhs: fmap
- hint:
lhs: "mapM"
note: "Use `traverse`"
rhs: traverse
- hint:
lhs: "unless b"
note: "Use `when not` as it reads intuitively."
rhs: when (not b)
================================================
FILE: CLAUDE.md
================================================
# HNix Codebase Guide for Claude Code
This guide provides essential context for working with HNix - a Haskell implementation of the Nix expression language using advanced functional programming techniques including recursion schemes and abstract definitional interpreters.
## Quick Start Commands
### Essential Development Workflow
```bash
# Enter development environment
nix-shell
# Build the project
cabal v2-configure
cabal v2-build
# Run a single test
cabal v2-test --test-options="--pattern '/Parser/basic literals/'"
# Interactive REPL for exploration
cabal v2-repl
> :load Nix.Eval
> :type evalExprLoc
# Quick evaluation test
cabal v2-run hnix -- --eval --expr '1 + 1'
```
### Testing Commands
```bash
# Standard test suite
cabal v2-test
# All tests including Nixpkgs parsing (slow)
env ALL_TESTS=yes cabal v2-test
# Only Nixpkgs compatibility tests
env NIXPKGS_TESTS=yes cabal v2-test
# Pretty-printer round-trip tests
env PRETTY_TESTS=yes cabal v2-test
# Test with coverage
cabal v2-configure --enable-coverage
cabal v2-test --enable-coverage
```
### Debugging & Profiling
```bash
# Memory profiling (upload .prof to speedscope.app)
cabal v2-run --enable-profiling --flags=profiling \
hnix -- --eval --expr 'builtins.length [1 2 3]' +RTS -hy -l
# Stack trace on error
cabal v2-run hnix -- --trace --eval --expr 'throw "error"' +RTS -xc
# Heap profiling for thunk leaks
cabal v2-run hnix -- --eval --expr 'import <nixpkgs> {}' \
+RTS -h -i0.1 -RTS && hp2ps -e8in -c hnix.hp
# Reduce complex expressions for minimal repro
hnix --reduce bug.nix --eval --expr 'import ./bug.nix'
```
## Architecture: Working with Recursion Schemes
### Core Expression Types
```haskell
-- The functor (non-recursive structure)
data NExprF r -- 18 constructors: NConstant, NStr, NSym, NList, etc.
-- Fixed point gives recursion
type NExpr = Fix NExprF
-- Location annotations via composition
type NExprLoc = Fix (AnnF SrcSpan NExprF)
```
### Using ADI for Custom Behavior
The `adi` function (`src/Nix/Utils.hs:345`) enables behavior injection:
```haskell
-- Example: Add tracing to evaluation
tracingEval :: NExprLoc -> m (NValue t f m)
tracingEval = adi addTrace baseEval
where
addTrace :: Transform NExprLocF (m (NValue t f m))
addTrace f e = do
traceM $ "Evaluating: " ++ show (void e)
result <- f e
traceM $ "Result: " ++ show result
pure result
```
Common ADI use cases:
- **Error context**: `evalWithMetaInfo = adi addMetaInfo evalContent`
- **Profiling**: Inject timing measurements at each recursion
- **Memoization**: Cache results of sub-expressions
- **Debugging**: Track evaluation path
### Free Monad Value System
```haskell
type NValue t f m = Free (NValue' t f m) t
-- Pure t = thunk (unevaluated)
-- Free v = evaluated value
```
**Memory implications**:
- Thunks accumulate until forced
- Use `force` explicitly to prevent buildup
- Monitor with `+RTS -s` for thunk statistics
## Working with the Effect System
### Core Type Classes
```haskell
class MonadEval v m where
evalExprLoc :: NExprLoc -> m v -- Evaluate expression
evalError :: Doc v -> m a -- Report error
class MonadThunk t m a | t -> m a where
thunk :: m a -> m t -- Create thunk
force :: t -> m a -- Force evaluation
class (MonadEval v m, MonadThunk t m v) => MonadNix e t f m
```
### Adding New Effects
```haskell
-- Define capability
class Monad m => MonadMyEffect m where
myOperation :: String -> m Int
-- Add to evaluation monad
newtype MyNix m a = MyNix (ReaderT MyEnv m a)
deriving (Functor, Applicative, Monad)
instance MonadMyEffect (MyNix m) where
myOperation s = MyNix $ asks (lookupThing s . myEnvData)
```
## Extending HNix
### Adding Built-ins
1. Add to `src/Nix/Builtins.hs`:
```haskell
builtinsList :: [(Text, BuiltinType)]
builtinsList =
[ ("myBuiltin", arity2 myBuiltinImpl)
-- ...
]
myBuiltinImpl :: MonadNix e t f m => NValue t f m -> NValue t f m -> m (NValue t f m)
myBuiltinImpl arg1 arg2 = do
-- Force evaluation if needed
str <- fromStringNoContext =<< fromValue arg1
num <- fromValue arg2
-- Perform operation
pure $ nvStr $ makeNixString (str <> show num)
```
2. Test in `tests/EvalTests.hs`
3. Document behavior matching Nix semantics
### Modifying Evaluation
```haskell
-- Hook into evaluation via MonadEval instance
instance MonadEval (NValue t f m) MyCustomNix where
evalExprLoc expr = do
-- Pre-evaluation hook
logExpression expr
-- Delegate to standard evaluation
result <- standardEvalExprLoc expr
-- Post-evaluation hook
recordMetrics expr result
pure result
```
## Common Pitfalls & Solutions
### Memory Issues
**Problem**: Thunk accumulation causing memory exhaustion
```haskell
-- BAD: Builds huge thunk chain
foldl' (\acc x -> thunk (acc + x)) 0 [1..1000000]
-- GOOD: Forces evaluation incrementally
foldl' (\acc x -> force acc >>= \a -> pure (a + x)) 0 [1..1000000]
```
**Problem**: Lazy fields in strict data
```haskell
-- BAD: ~ makes field lazy despite ! on data
data MyData = MyData { ~myField :: !Int }
-- GOOD: Strict field in strict data
data MyData = MyData { myField :: !Int }
```
### Debugging Infinite Recursion
1. Enable tracing: `--trace` flag
2. Use `--reduce` to minimize test case
3. Add ADI transform to track recursion depth:
```haskell
depthCheck :: Transform NExprLocF (ReaderT Int m (NValue t f m))
depthCheck f e = do
depth <- ask
when (depth > 1000) $ error "Recursion limit"
local (+1) (f e)
```
### Performance Optimization
**Profile first**:
```bash
# Generate flamegraph
cabal v2-run hnix -- --eval --expr 'import <nixpkgs> {}' \
+RTS -p -RTS
```
**Common optimizations**:
1. Add strictness annotations to accumulators
2. Use `HashMap` instead of association lists
3. Cache frequently computed values
4. Specialize polymorphic functions with `{-# SPECIALIZE #-}`
## Module Organization & Dependencies
### Layered Architecture
```
┌─────────────────┐
│ Builtins │ (100+ built-in functions)
├─────────────────┤
│ Effects │ (MonadNix, MonadEval constraints)
├─────────────────┤
│ Exec │ (High-level evaluation)
├─────────────────┤
│ Eval │ (Core evaluation with ADI)
├─────────────────┤
│ Value/Thunk │ (Free monad values, lazy evaluation)
├─────────────────┤
│ Expr │ (NExprF functor, parser, pretty-printer)
└─────────────────┘
```
### Key Files for Common Tasks
- **Adding language features**: Start with `src/Nix/Parser.hs`, add to `NExprF` in `src/Nix/Expr/Types.hs`
- **Modifying evaluation**: `src/Nix/Eval.hs` for core, `src/Nix/Exec.hs` for high-level
- **Debugging issues**: `src/Nix/Reduce.hs` for test reduction, `src/Nix/Cited.hs` for error context
- **Performance work**: `src/Nix/Thunk/Basic.hs` for thunk implementation
- **Built-in functions**: `src/Nix/Builtins.hs` - match Nix semantics exactly
## Testing Philosophy
### Test Categories
- **Language tests** (`tests/NixLanguageTests.hs`): Official Nix test suite
- **Evaluation tests** (`tests/EvalTests.hs`): HNix-specific behavior
- **Parser tests** (`tests/ParserTests.hs`): Round-trip properties
- **Pretty tests** (`tests/PrettyTests.hs`): Pretty-printer correctness
### Writing Effective Tests
```haskell
-- Property-based test for parser round-trip
prop_parse_pretty :: NExpr -> Property
prop_parse_pretty expr =
parseNixText (prettyNix expr) === Right expr
-- Golden test for evaluation
goldenEval :: String -> NExpr -> TestTree
goldenEval name expr = goldenVsString name path $ do
result <- runLazyM defaultOptions $ evalExprLoc expr
pure $ encodeUtf8 $ prettyNValue result
```
## Important Implementation Notes
### Custom Prelude
Uses `relude` with project utilities in `Nix.Utils`. Key differences:
- `panic` instead of `error` for impossible cases
- `pass` for noop in do-blocks
- Strict `Text` by default
### String Context
Nix strings carry derivation context - critical for store paths:
```haskell
-- Context propagates through operations
makeNixString :: Text -> NixString -- No context
makeNixStringWithContext :: Text -> Context -> NixString
```
### Store Integration
**Warning**: `derivationStrict` creates real `/nix/store` entries. Use `--dry-run` for testing.
### Position Tracking
Custom `NSourcePos` for performance - strict fields prevent memory leaks during parsing.
## Current Status & Goals
**Primary Goal**: Evaluate all of Nixpkgs
```bash
hnix --eval --expr "import <nixpkgs> {}" --find
```
**Working**: Parser, lazy evaluation, most built-ins, REPL, type inference
**In Progress**: Full Nixpkgs evaluation, performance optimization
**Known Issues**: Tests disabled by default (`doCheck = false`) due to store interaction
## Resources
- [Win for Recursion Schemes](https://newartisans.com/2018/04/win-for-recursion-schemes/) - Essential architectural context
- [Design of HNix](https://github.com/haskell-nix/hnix/wiki/Design-of-the-HNix-code-base)
- [Gitter Chat](https://gitter.im/haskell-nix/Lobby)
================================================
FILE: CODEOWNERS
================================================
/ @jwiegley
================================================
FILE: ChangeLog.md
================================================
# ChangeLog
## [(diff)](https://github.com/haskell-nix/hnix/compare/0.16.0...0.17.0#files_bucket) 0.17.0
* Additional
* `Nix.Effect`
* [(link)](https://github.com/haskell-nix/hnix/pull/1051) Introduction of new type NarContent, a tagged union type of `byteString` and `FilePath`.
* [(link)](https://github.com/haskell-nix/hnix/pull/1051) getURL of instance MonadHttp IO is finally working through hnix-store. Which also means
builtins.fetchurl is working through it.
* Breaking:
* `Nix.Effect`
* [(link)](https://github.com/haskell-nix/hnix/pull/1051) MonadStore's addToStore signature changed to `StorePathName -> NarContent -> RecursiveFlag -> RepairFlag -> m (Either ErrorCall StorePath)` with new introduction of NarContent. Which enable us to add byteString as file to Store. It is corresponding to the hnix-store api change.
* `Nix.Expr.Types`
* [(link)](https://github.com/haskell-nix/hnix/pull/1042/files) The central HNix type `NExprF` changed, the `NApp` was moved out of `NBinary` & now a `NExprF` constructor of its own, the type signatures were changed accordingly.
* [(link)](https://github.com/haskell-nix/hnix/pull/1038/files) project was using `megaparsec` `{,Source}Pos` and to use it shipped a lot of orphan instances. To improve the situation & performance (reports [#1026](https://github.com/haskell-nix/hnix/issues/1026), [#746](https://github.com/haskell-nix/hnix/issues/746)) project uses `N{,Source}Pos` types, related type signatures were changed accordingly.
* `Nix.Value`
* [(link)](https://github.com/haskell-nix/hnix/pull/1046/files) Unify builder `mkNV*` and `NV*` patterns by bidirectional synonyms, a lot of builders `mkNV*` are removed, and merged to `NV*`. e.g. instead of builder `mkNVList`, `NVList` should be used.
* [(link)](https://github.com/haskell-nix/hnix/pull/1046/files) Constraint `NVConstraint f = (Comonad f, Applicative f)` was introduced, in order to unify builder `mkNV*` and `NV*` patterns.
* `Nix.Parser`:
* [(link)](https://github.com/haskell-nix/hnix/pull/1047/files) rm `OperatorInfo`, using `NOperatorDef`. Number of functions changed signatures accordingly:
* In `Nix.Pretty`:
* `NixDoc ann`
* `mkNixDoc`
* `selectOp`
* `hasAttrOp`
* `precedenceWrap`
* `wrapPath`
* In `Nix.Parser`:
* rm `get{App,Unary,Binary,Special}Operator`, currely `NOp` class instances are used instead.
* `Nix.Pretty`:
* [(link)](https://github.com/haskell-nix/hnix/pull/1047/files) rm `appOp`, instead use `appOpDef`.
* [(link)](https://github.com/haskell-nix/hnix/pull/1047/files) `precedenceWrap` behaviour is changed (to be literal to the name), the old behaviour is now a `wrap` function.
## [(diff)](https://github.com/haskell-nix/hnix/compare/0.15.0...0.16.0#files_bucket) 0.16.0
On update problems, please reach out to us. For support refere to: https://github.com/haskell-nix/hnix/issues/984
Partial log (for now):
* Breaking:
* Where `coerce` should work, removed `newtype` accessors.
* [(link)](https://github.com/haskell-nix/hnix/pull/1006/files), [(link)](https://github.com/haskell-nix/hnix/pull/1009/files) Incomprehensible record accessors zoo like: `arg`, `options`, `unStore`, `scFlavor`, `nsContext` `_provenance` - was organized, now all record accessors start with `get*`, and their names tend to have according unique sematic meaning of data action they do.
* Builder names got unified. Now they all start with `mk*`. So a lof of `nvSet` became `mkNVSet`.
* `Nix.String` builders/destructors instead of `make` use `mk`, & where mentioning of `string` is superflous - dropped it from the name, so `stringIgnoreContext`, became `ignoreContext`.
* Type system:
* Things that are paths are now `newtype Path = Path String`.
* Things that are indentifier names are now `newtype VarName = VarName Text`.
* Function signatures changed accordingly.
* Additional:
* [(link)](https://github.com/haskell-nix/hnix/pull/1019) Matched expression escaping & its representation to breaking changes in Nix `2.4`.
* `Builtins` (`builtins` function set) gained functions:
* [(link)](https://github.com/haskell-nix/hnix/pull/1032) `path`
* [(link)](https://github.com/haskell-nix/hnix/pull/1020) `isPathNix`
* [(link)](https://github.com/haskell-nix/hnix/pull/1032) `unsafeDiscardOutputDependency`
* [(link)](https://github.com/haskell-nix/hnix/pull/1031) `ceil`
* [(link)](https://github.com/haskell-nix/hnix/pull/1031) `floor`
* [(link)](https://github.com/haskell-nix/hnix/pull/1021) `hashFile`
* [(link)](https://github.com/haskell-nix/hnix/pull/1033) `groupBy`
* [(link)](https://github.com/haskell-nix/hnix/pull/1029) `data/nix` submodule (& its tests) updated to 2022-01-17.
* Other notes:
* `Shorthands` was kept untouched.
## [(diff)](https://github.com/haskell-nix/hnix/compare/0.14.0...0.15.0#files_bucket) 0.15.0
For support refere to: https://github.com/haskell-nix/hnix/issues/984
Partial log (for now):
* Breaking:
* `Nix.Expr.Shorthands`:
* `inherit{,From}`:
* dropped second(/third) argument as irrelevant ([report](https://github.com/haskell-nix/hnix/issues/326))
* bindings to inherit changed type from complex `[NKeyName]` (which is for static & dynamic keys) to `[VarName]` (`VarName` is newtype of `Text`).
* So examples of use now are: `inherit ["a", "b"]`, `inheritFrom (var "a") ["b", "c"]`
* `mkAssert`: fixed ([report](https://github.com/haskell-nix/hnix/issues/969)).
* fx presedence between the operators:
```haskell
(@@), (@.), (@./), ($==), ($!=), ($<), ($<=), ($>), ($>=), ($&&), ($||), ($->), ($//), ($+), ($-), ($*), ($/), ($++), (==>)
```
Now these shorthands can be used without sectioning & so represent the Nix expressions one to one.
```haskell
nix = " a/b // c/def // <g> < def/d"
hask = mkRelPath "a/b" $// mkRelPath "c/def" $// mkEnvPath "g" $< mkRelPath "def/d"
```
* Additional
* `Nix.Expr.Shorthands`:
* added:
* `emptySet`
* `emptyList`
* `mkOp{,2}`
* `mk{,Named,Variadic,General}ParamSet`
* `mkNeg` - number negation.
* `@.<|>` for Nix language `s.x or y` expession.
* entered deprecation:
* `mkOper{,2}` bacame `mkOp{,2}`.
* `mkBinop` became `mkOp2`.
* `mkParaset` supeceeded by `mk{,Named{,Variadic},Variadic,General}ParamSet`.
* fixed:
* `mkAssert` was creating `with`, now properly creates `assert`.
## [(diff)](https://github.com/haskell-nix/hnix/compare/0.13.1...0.14.0#files_bucket) 0.14.0 (2021-07-08)
* GHC 9.0 support.
* HNix switched to pre-0.9 style of log (aka "no log"). We temporarily stopped producing log, choosing effectiveness over writing about it.
* All changes seem trivial (from the inside). There is no changes in `Nix.Expr.Shorthands` module. Would there be difficulties in migration - please write to us - we would tackle & solve it togather.
A partial log:
* Breaking:
* `Nix.Effects`:
* rm `pathExits` in favour of `doesPathExist` (in `Nix.Render`: `class MonadFile`: `doesPathExist`)
* `Nix.Var`: was found being superflous ([report](https://github.com/haskell-nix/hnix/issues/946)), so reduced. use `Control.Monad.Ref` instead.
* `Nix.Normal`
* rename `opaque(,->Val)`, indicate that it is a literal.
* `Nix.Thunk`:
* `class MonadThunkId m => MonadThunk{,F} t m a`:
* rename `query(M->){,F}`
* Additional:
* `Nix.Utils`:
* added type `TransformF`
* `Nix.Eval`:
* added fun:
* `evalContent`
* `addMetaInfo`
* `Nix.Types.Assumption`:
* added instances:
* `Assumption`: `{Semigroup,Monoid,One}`
* `Nix.Type.Env`:
* added instances:
* `Env`: `{Semigroup,Monoid,One}`
* `Nix`:
* changed argument order:
* `nixEval`:
```haskell
-- was:
=> Maybe FilePath -> Transform g (m a) -> Alg g (m a) -> Fix g -> m a
-- became:
=> Transform g (m a) -> Alg g (m a) -> Maybe FilePath -> Fix g -> m a
```
* `Nix.Normal`
* add `thunkVal` literal & use it where appropriate `{deThunk, removeEffects}`
* `Nix.Thunk.Basic`:
* export `deferred`
### [(diff)](https://github.com/haskell-nix/hnix/compare/0.13.0.1...0.13.1#files_bucket) 0.13.1 (2021-05-22)
* [(link)](https://github.com/haskell-nix/hnix/pull/936/files) `Nix.Parser`: `annotateLocation`: Fix source location preservation.
* [(link)](https://github.com/haskell-nix/hnix/pull/934/files) Require Cabal dependency `relude` `>= 1.0`: since imports & Cabal file got cleaned-up & that clean-up depends on `relude` reimports introduced in aforementioned version.
* Refactors, reorganization in some modules, docs, clean-ups.
#### [(diff)](https://github.com/haskell-nix/hnix/compare/0.13.0...0.13.0.1#files_bucket) 0.13.0.1 (2021-05-11)
* [(link)](https://github.com/haskell-nix/hnix/pull/931/files) `Nix.Expr.Types`: Fix CPP on `Instances.TH.Lift` import.
## [(diff)](https://github.com/haskell-nix/hnix/compare/0.12.0...0.13.0#files_bucket) 0.13.0 (2021-05-10)
* Breaking:
* [(link)](https://github.com/haskell-nix/hnix/pull/859/files) [(link)](https://github.com/haskell-nix/hnix/pull/863/files) [(link)](https://github.com/haskell-nix/hnix/pull/866/files) `Nix.Thunk`: `class MonadThunk t m a | t -> m, t -> a`. Class was initially designed with Kleisli arrows (`v -> m a`) in mind, which where put to have the design open and inviting customization & integration. Those functional arguments are for custom implementation, so which in reality of the project were never used and HNax just "essentially" (simplifying, because `pure` was mixed with monadic binds to `f`) was passing `pure` into them (actually, `f <=< pure`). These Kliesli functors got arguments sorted properly and were moved to a `MonadThunkF` class and names gained `*F`. And `MonadThunk` now does only what is needed, for example `force` gets the thunk and computes it. All `MonadThunk{,F}` functions become with a classic Haskell arguments order, specialized, and got more straigh-forward to understand and use, and so now they tail recurse also.
Now, for example, instead of `force t f` use it as `v <- force t` `f =<< force t`, or `f <=< force`.
tl;dr: results:
```haskell
class MonadThunkId m => MonadThunk t m a | t -> m, t -> a where
thunkId :: t -> ThunkId m
thunk :: m a -> m t
queryM :: m a -> t -> m a
-- old became `queryMF`
force :: t -> m a
-- old became `forceF`
forceEff :: t -> m a
-- old became `forceEffF`
further :: t -> m t
-- old became `furtherF`
-- | Class of Kleisli functors for easiness of customized implementation developlemnt.
class MonadThunkF t m a | t -> m, t -> a where
queryMF :: (a -> m r) -> m r -> t -> m r
-- was :: t -> m r -> (a -> m r) -> m r
forceF :: (a -> m r) -> t -> m r
-- was :: t -> (a -> m r) -> m r
forceEffF :: (a -> m r) -> t -> m r
-- was :: t -> (a -> m r) -> m r
furtherF :: (m a -> m a) -> t -> m t
-- was :: t -> (m a -> m a) -> m t
```
* [(link)](https://github.com/haskell-nix/hnix/pull/862/files) [(link)](https://github.com/haskell-nix/hnix/pull/870/files) [(link)](https://github.com/haskell-nix/hnix/pull/871/files) [(link)](https://github.com/haskell-nix/hnix/pull/872/files) [(link)](https://github.com/haskell-nix/hnix/pull/873/files) `Nix.Value.Monad`: `class MonadValue v m`: instances became specialized, Kleisli versions unflipped the arguments of methods into a classical order and moved to the `class MonadValueF`. As a result, `demand` now gets optimized by GHC and also tail recurse. Please, use `f =<< demand t`, or just use `demandF`, while `demandF` in fact just `kleisli =<< demand t`.
```haskell
class MonadValue v m where
demand :: v -> m v
-- old became `demandF`
inform :: v -> m v
-- old became `informF`
class MonadValueF v m where
demandF :: (v -> m r) -> v -> m r
-- was :: v -> (v -> m r) -> m r
informF :: (m v -> m v) -> v -> m v
-- was :: v -> (m v -> m v) -> m v
```
* [(link)](https://github.com/haskell-nix/hnix/pull/863/files) `Nix.Normal`: `normalizeValue` removed first functional argument that was passing the function that did the thunk forcing. Now function provides the thunk forcing. Now to normalize simply use `normalizeValue v`. Old implementation now is `normalizeValueF`.
* [(link)](https://github.com/haskell-nix/hnix/pull/859/commits/8e043bcbda13ea4fd66d3eefd6da690bb3923edd) `Nix.Value.Equal`: `valueEqM`: freed from `RankNTypes: forall t f m .`.
* [(link)](https://github.com/haskell-nix/hnix/pull/802/commits/529095deaf6bc6b102fe5a3ac7baccfbb8852e49#) `Nix.Strings`: all `hacky*` functions replaced with lawful implemetations, because of that all functions become lawful - dropped the `principled` suffix from functions:
* `Nix.String`:
```haskell
hackyGetStringNoContext ->
getStringNoContext
hackyStringIgnoreContext ->
stringIgnoreContext
hackyMakeNixStringWithoutContext ->
makeNixStringWithoutContext
principledMempty -> mempty
principledStringMempty -> mempty
principledStringMConcat -> mconcat
principledStringMappend -> mappend
principledGetContext ->
getContext
principledMakeNixString ->
makeNixString
principledIntercalateNixStrin ->
intercalateNixString
principledGetStringNoContext ->
getStringNoContext
principledStringIgnoreContext ->
stringIgnoreContext
principledMakeNixStringWithoutContext ->
makeNixStringWithoutContext
principledMakeNixStringWithSingletonContext ->
makeNixStringWithSingletonContext
principledModifyNixContents ->
modifyNixContents
```
* [(link)](https://github.com/haskell-nix/hnix/pull/805/files):
* Data type: `MonadFix1T t m`: `Nix.Standard` -> `Nix.Utils.Fix1`
* Children found their parents:
```haskell
Binary NAtom :: Nix.Expr.Types -> Nix.Atoms
FromJSON NAtom :: Nix.Expr.Types -> Nix.Atoms
ToJSON NAtom :: Nix.Expr.Types -> Nix.Atoms
Eq1 (NValueF p m) :: Nix.Value.Equal -> Nix.Value
Eq1 (NValue' t f m a) :: Nix.Value.Equal -> Nix.Value
HasCitations m v (NValue' t f m a) :: Nix.Pretty -> Nix.Cited
HasCitations m v (NValue t f m) :: Nix.Pretty -> Nix.Cited
when
(package hashable >= 1.3.1) -- gained instance
$ Hashable1 NonEmpty:: Nix.Expr.Types -> Void -- please use upstreamed instance
-- | Was upstreamed, released in `ref-tf >= 0.5`.
MonadAtomicRef (ST s) :: Nix.Standard -> Void
MonadAtomicRef (Fix1T t m) :: Nix.Standard -> Nix.Utils.Fix1
MonadRef (Fix1T t m) :: Nix.Standard -> Nix.Utils.Fix1
MonadEnv (Fix1T t m) :: Nix.Standard -> Nix.Effects
MonadExec (Fix1T t m) :: Nix.Standard -> Nix.Effects
MonadHttp (Fix1T t m) :: Nix.Standard -> Nix.Effects
MonadInstantiate (Fix1T t m) :: Nix.Standard -> Nix.Effects
MonadIntrospect (Fix1T t m) :: Nix.Standard -> Nix.Effects
MonadPaths (Fix1T t m) :: Nix.Standard -> Nix.Effects
MonadPutStr (Fix1T t m) :: Nix.Standard -> Nix.Effects
MonadStore (Fix1T t m) :: Nix.Standard -> Nix.Effects
MonadFile (Fix1T t m) :: Nix.Standard -> Nix.Render
MonadEnv (Fix1 t) :: Nix.Standard -> Nix.Effects
MonadExec (Fix1 t) :: Nix.Standard -> Nix.Effects
MonadHttp (Fix1 t) :: Nix.Standard -> Nix.Effects
MonadInstantiate (Fix1 t) :: Nix.Standard -> Nix.Effects
MonadIntrospect (Fix1 t) :: Nix.Standard -> Nix.Effects
MonadPaths (Fix1 t) :: Nix.Standard -> Nix.Effects
MonadPutStr (Fix1 t) :: Nix.Standard -> Nix.Effects
```
* [(link)](https://github.com/haskell-nix/hnix/pull/878/files) `Nix.Value`: `nvSet{,',P}`: got unflipped, now accept source position argument before the value.
* [(link)](https://github.com/haskell-nix/hnix/pull/878/files) `Nix.Pretty`: `mkNixDoc`: got unflipped.
* [(link)](https://github.com/haskell-nix/hnix/pull/886/commits/381b0e5df9cc620a25533ff1c84045a4ea37a833) `Nix.Value`: Data constructor for `NValue' t f m a` changed (`NValue -> NValue'`).
* [(link)](https://github.com/haskell-nix/hnix/pull/884/files) `Nix.Parser`: `Parser`: Data type was equivalent to `Either`, so became a type synonim for `Either`.
* [(link)](https://github.com/haskell-nix/hnix/pull/884/files) `Nix.Thunk.Basic`: `instance MonadThunk (NThunkF m v) m v`: `queryM`: implementation no longer blocks the thunk resource it only reads from.
* [(link)](https://github.com/haskell-nix/hnix/pull/908/files): Migrated `(String -> Text)`:
* `Nix.Value`: `{NValueF, nvBuiltin{,'}, builtin{,2,3}, describeValue}`
* `Nix.Eval`: `MonadNixEval`
* `Nix.Render.Frame`: `render{Expr,Value}`
* `Nix.Type`: `TVar`
* `Nix.Thunk`: `ThunkLoop`
* `Nix.Exec`: `{nvBuiltinP, nixInstantiateExpr, exec}`
* `Nix.Effects`:
* `class`:
* `MonadExec: exec'`
* `MonadEnv: getEnvVar`
* `MonadInstantiate: instatiateExpr`
* `parseStoreResult`
* `Nix.Effects.Derivation`: `renderSymbolic`
* `Nix.Lint`: `{NTypeF, symerr}`
* Additional:
* [(link)](https://github.com/haskell-nix/hnix/commit/7e6cd97bf3288cb584241611fdb25bf85d7e0ba7) `cabal.project`: freed from the `cryptohash-sha512` override, Hackage trustees made a revision.
* [(link)](https://github.com/haskell-nix/hnix/pull/824/commits/4422eb10959115f21045f39e302314a77df4b775) To be more approachable for user understanding, the thunk representation in outputs changed from `"<CYCLE>" -> "<expr>"`.
* [(link)](https://github.com/haskell-nix/hnix/pull/925/commits/37e81c96996b07cbbdf9fa4bf380265e8c008482) The Nix evaluation cycle representation changed `"<CYCLE>" -> "<cycle>"`.
* [(link)](https://github.com/haskell-nix/hnix/commit/51a3ff9e0065d50e5c625738696526c4a232b0cf) `Nix.Expr.Types`: added hacky implementation of `liftTyped` for `instance Lift (Fix NExprF)`.
* [(link)](https://github.com/haskell-nix/hnix/commit/51a3ff9e0065d50e5c625738696526c4a232b0cf) `Nix.Builtins`: `derivation` primOp internal code always fully evaluated, so GHC now always ships only fully compiled version in the bytecode.
* [(link)](https://github.com/haskell-nix/hnix/pull/890): Project switched to prelude `relude`.
* A bunch of other stuff that is not user-facing.
## [(diff)](https://github.com/haskell-nix/hnix/compare/0.11.1...0.12.0#files_bucket) 0.12.0 (2021-01-05)
* *Disclaimer*: Current `derivationStrict` primOp implementation and so every evaluation of a derivation into a store path currently relies on the `hnix-store-remote`, which for those operations relies on the running `nix-daemon`, and so operations use/produce effects into the `/nix/store`. Be cautious - it is effectful.
* Introduction:
* New module `Nix.Effects.Derivation`.
* Operations on derivations:
* old got principled implementations.
* also new operations got introduced.
* Implementation of the `derivationStrict` primOp.
* Breaking:
* [(link)](https://github.com/haskell-nix/hnix/pull/554/commits/3bba5549273c892c60aad5dd6d5058a8db40efbf) `Nix.Effects`: **class** `MonadStore` got principled implementation.
* `addPath'` got principled into `addToStore`.
* `toFile_` got principled into `addTextToStore'`.
* For help & easy migration you may use `addPath` & `toFile_` `addTextToStore` standalone functions in the module.
* [(link)](https://github.com/haskell-nix/hnix/pull/554/commits/3bba5549273c892c60aad5dd6d5058a8db40efbf) `Nix.Effects.Basic`: `defaultDerivationStrict` got reimplemented & moved into `Nix.Effects.Derivation`.
* [(link)](https://github.com/haskell-nix/hnix/pull/554/commits/3bba5549273c892c60aad5dd6d5058a8db40efbf) `Nix.Standard`: instance for `MonadStore (Fix1T t m)` got principled accoding to class `MonadStore` changes.
* [(link)](https://github.com/haskell-nix/hnix/pull/554/commits/3bba5549273c892c60aad5dd6d5058a8db40efbf) `Nix.Fresh.Basic`: instance for `MonadStore (StdIdT m)` got principled.
* Additional:
* [(link)](https://github.com/haskell-nix/hnix/pull/554/commits/3bba5549273c892c60aad5dd6d5058a8db40efbf) **New module `Nix.Effects.Derivation`**: [HNix(0.12.0):Nix.Effects.Derivation documentation](https://hackage.haskell.org/package/hnix-0.12.0/docs/Nix-Effects-Derivation.html).
* [(link)](https://github.com/haskell-nix/hnix/pull/554/commits/9bcfbbe88ff0bd8d803296193ee1d8603dc5289e) `Nix.Convert`: Principled `NVPath -> NixString` coercion.
* In a form of principled `instance FromValue NixString m (NValue' t f m (NValue t f m))`.
* [(link)](https://github.com/haskell-nix/hnix/pull/554/commits/a8e6d28fdb98a1c34f425c8395338fdabe96becc) `Nix.String`: Allow custom computations inside string contexts.
* By providing `runWithStringContext{T,}'` methods into the API.
* [(link)](https://github.com/haskell-nix/hnix/pull/554/commits/e45f7632c51a9657f6e8d54c39fd4d21c466d85f) Includded support for new `base16-bytestring`, which advertices 2x-4x speed increase of its operations.
* [(link)](https://github.com/haskell-nix/hnix/pull/554/commits/3bba5549273c892c60aad5dd6d5058a8db40efbf) `Nix.Effects`: `addPath` & `toFile_` standalone functions got principled implementation through the internal use of the new `MonadStore` type class implementation.
* [(link)](https://github.com/haskell-nix/hnix/pull/554/commits/3bba5549273c892c60aad5dd6d5058a8db40efbf) `Nix.Effects`: added `addTextToStore`, `parseStoreResult` implementations.
* [(link)](https://github.com/haskell-nix/hnix/pull/554/commits/3bba5549273c892c60aad5dd6d5058a8db40efbf) `Nix.Effects`: added type synonyms `{RecursiveFlag, RepairFlag, StorePathName, FilePathFilter, StorePathSet}`.
* [(link)](https://github.com/haskell-nix/hnix/pull/760) `Nix.Exec`: Fixed the rendering of internal `Frames`.
* Which is an internal mechanism of a project to passing around messages with their context, still to be used internally).
* [(link)](https://github.com/haskell-nix/hnix/pull/554/commits/3bba5549273c892c60aad5dd6d5058a8db40efbf) `HNix / Nix`: The library now also uses `hnix-store-remote`.
* [(link)](https://github.com/haskell-nix/hnix/pull/554/commits/06b0fca9fd607eb2e995f003424e797a41ffa5b7) `cabal.project`: project uses `cryptohash-sha512` override, the `hnix-store-core` requires it from `hnix` and uses that override also. [Detailed info](https://github.com/haskell-hvr/cryptohash-sha512/pull/5#issuecomment-752796913). We promise to attend to this issue, probably by migrating to `cryptonite` in the nearest releases.
Future note: The HNix is a big project. During the initial development and currently the API for simplicity exposes allmost all functions, types, etc. Big open API means a big effort to create/maintain a quite noisy changelog and you parsing through it, and also creates a frequent requirements to mark releases as major and bother you due to some type changes in some parts that may not be used or applicable to be public API.
This year the most gracious API clean-up would happen, we would check and keep open what Hackage projects are using from the API, and the other parts would be open on the request by a way of rapid minor releases. That clean-up is also a work toward splitting the project into several packages some time in the future (split would be into something like Expressions, Evaluation, Executable, Extra), which migration also would be done most thoughful and graceful as possible, with as much easiness and automation provided for migration downstream as possible. If all goes as planned - all downstream would need to do is to get and run our script that would migrate our old map of module imports to new ones, and maybe manually add those newly formed packages into `.cabal` description.
If it is possible, please, try to switch & use the higher-level API functions where it is applicable. Thank you.
### [(diff)](https://github.com/haskell-nix/hnix/compare/0.11.0...0.11.1#files_bucket) 0.11.1 (2020-12-09)
* Additional:
* [(link)](https://github.com/haskell-nix/hnix/commit/d32a6fbaf3df1c8879d1b19a18f21c031a73e56c) `Nix.Builtins`: `isString` fixed - It used to return `True` for values coercible to string like derivations and paths. It only accepts string values now.
* [(link)](https://github.com/haskell-nix/hnix/commit/53b4db2525a8f074d8c262fa7b66ce97e5820890) `Nix.Builtins`: `substring` fixed - Negative lengths used to capture an empty string. Now they capture the whole rmeainder of the string.
* [(link)](https://github.com/haskell-nix/hnix/commit/dc31c5e64f8c7aaaea14cac0134bd47544533e67) `Nix.Effects`: `pathExists` fixed - Now also works with directories.
* [(link)](https://github.com/haskell-nix/hnix/commit/e2ad934492eeac9881527610e4a1c1cf31ea1115) `Nix.Parser`: `->` is now properly right-associative (was non-associative).
* [(link)](https://github.com/haskell-nix/hnix/commit/50baea5e1e482be3c4fcc13c9a45b1083243f681) `Nix.Parser`: Nix `assert` parser (`nixAssert` function) now accepts top-level Nix format also (which means also accepts all kinds of statements), before that it accepted only regular Nix expressions.
* [(link)](https://github.com/haskell-nix/hnix/commit/59698de7185dfae508e5ccea4377a82023c4a0d5) `Nix.Render`: `renderLocation` now also shows/handles location of errors in raw strings.
## [(diff)](https://github.com/haskell-nix/hnix/compare/0.10.1...0.11.0#files_bucket) 0.11.0 (2020-11-02)
* Breaking:
* [(link)](https://github.com/haskell-nix/hnix/pull/740) Deleted incorrect `instance Generic1 NKeyName` from `module Nix.Expr.Types`.
* [(link)](https://github.com/haskell-nix/hnix/pull/739) Parentheses now are properly included in the location annotation for Nix expressions, change of `nixParens` in `module Nix.Parser` essentially results in the change of all module `nix*` function results, essentially making results of the whole module more proper.
* Additional:
* [(link)](https://github.com/haskell-nix/hnix/pull/741) Fix QQ Text lifting error: work around of [GHC#12596 "can't find interface-file declaration"](https://gitlab.haskell.org/ghc/ghc/-/issues/12596).
* [(link)](https://github.com/haskell-nix/hnix/pull/744) Fix comments inclusion into location annotations, by using pre-whitespace position for source end locations.
### [(diff)](https://github.com/haskell-nix/hnix/compare/0.10.0...0.10.1#files_bucket) 0.10.1 (2020-09-13)
* Additional:
* [(link)](https://github.com/haskell-nix/hnix/pull/715) `{Binding, NExpr, NExprF, NKeyName}` gained `Ord1` instances.
* These instances were required by downstream projects to be able to use newer HNix.
* [(link)](https://github.com/haskell-nix/hnix/pull/712) CLI gained `--long-version` option for gathering a detailed debug information.
* Currently, reports Git commit and its date.
* [(link)](https://github.com/haskell-nix/hnix/issues/718) Currently does not work in case of use of the `nix-build`, in which case simply returns `UNKNOWN` placeholder.
## [(diff)](https://github.com/haskell-nix/hnix/compare/0.9.1...0.10.0#files_bucket) 0.10.0 (2020-09-12)
* Breaking:
* [(link)](https://github.com/haskell-nix/hnix/pull/699) Removed `NExpr` `{FromJSON, ToJSON}` instances.
* This also removed the JSON output feature for unevaluated expression trees.
* Additional:
* [(link)](https://github.com/haskell-nix/hnix/pull/703) CLI gained `--version` option.
* Dependencies:
* [(link)](https://github.com/haskell-nix/hnix/pull/686) Requires last major `data-fix` (`0.3`).
* [(link)](https://github.com/haskell-nix/hnix/pull/679) Requires last major `prettyprinter` (`1.7`).
### [(diff)](https://github.com/haskell-nix/hnix/compare/0.9.0...0.9.1#files_bucket) 0.9.1 (2020-07-13)
* Additional:
* REPL:
* Better tab completion.
* Accepting multi-line input.
* Support for passing evaluated expression result of `hnix --eval -E`.
to REPL as an `input` variable.
* Support for loading `.hnixrc` from the current directory.
* Reporting of `builtins.nixVersion` bumped from 2.0 to 2.3.
* Dependencies:
* Freed from: `{interpolate, contravariant, semigroups, generic-random, tasty-quickcheck}`.
* Requires last major `repline` (`0.4`).
## [(diff)](https://github.com/haskell-nix/hnix/compare/0.8.0...0.9.0#files_bucket) 0.9.0 (2020-06-15)
* Breaking:
* Removed instances due to migration to `haskeline 0.8`:
* `instance MonadException m => MonadException(StateT(HashMap FilePath NExprLoc) m)`.
* `instance MonadException m => MonadException(Fix1T StandardTF m)`.
* Dependencies:
* Requires last major `haskeline` (`0.8`).
* Additional:
* Library: Official support for `GHC 8.4 - 8.10`.
* Executable complies only under `GHC 8.10`.
* Changelog started. Previous release was `0.8.0`.
---
HNix uses [PVP Versioning][1].
[1]: https://pvp.haskell.org
================================================
FILE: LICENSE.md
================================================
Copyright (c) 2014-2025, John Wiegley. 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 New Artisans LLC nor the names of its
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.
================================================
FILE: License
================================================
Copyright (c) 2014, John Wiegley All rights reserved.
Redistribution and use in source and binary forms, with or without
modification, are permitted provided that the following conditions are met:
1. Redistributions of source code must retain the above copyright notice, this
list of conditions and the following disclaimer.
2. 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.
3. Neither the name of the copyright holder nor the names of its 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 HOLDER 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.
================================================
FILE: Makefile
================================================
all: default.nix
default.nix: hnix.cabal
cabal2nix --shell . > $@
================================================
FILE: ReadMe.md
================================================
[](https://gitter.im/haskell-nix/Lobby)
[](https://hackage.haskell.org/package/hnix)
[](https://matrix.hackage.haskell.org/package/hnix)
[](https://packdeps.haskellers.com/feed?needle=hnix)
[](https://hydra.nixos.org/job/nixpkgs/trunk/haskellPackages.hnix.x86_64-linux#tabs-status)
[](https://repology.org/project/haskell:hnix/versions)
# HNix
Parser, evaluator and type checker for the Nix language written in Haskell.
## Prerequisites
Tooling is WIP, `nix-shell` and `nix-store` are still used for their purpose, so, to access them Nix is required to be installed.
*Disclaimer*: Since still using Nix for some operations, current `derivationStrict` primOp implementation and so evaluations of a derivation into a store path currently rely on the `hnix-store-remote`, which for those operations relies on the running `nix-daemon`, and so operations use/produce effects into the `/nix/store`. Be cautious - it is effectful (produces `/nix/store` entries).
## Building the project
### Git clone
```shell
git clone 'https://github.com/haskell-nix/hnix.git' && cd hnix
```
### (optional) Cachix prebuild binary caches
If you would use our Nix-shell environment for development, you can connect to our Cachix HNix build caches:
1. Run:
```shell
nix-env -iA cachix -f https://cachix.org/api/v1/install
```
2. Run: `cachix use hnix`
### Building with Cabal
Cabal [Quickstart](https://cabal.readthedocs.io/en/3.4/nix-local-build.html).
1. (Optional), to enter the projects reproducible Nix environment:
```shell
nix-shell
```
2. Building:
```shell
cabal v2-configure
cabal v2-build
```
3. Loading the project into `ghci` REPL:
```shell
cabal v2-repl
```
4. Testing:
* Default suite:
```shell
cabal v2-test
```
* All available tests:
```shell
env ALL_TESTS=yes cabal v2-test
```
* Selected (list of tests is in `tests/Main.hs`):
```shell
env NIXPKGS_TESTS=yes PRETTY_TESTS=1 cabal v2-test
```
#### Checking the project
##### Benchmarks
To run benchmarks:
```shell
cabal v2-bench
```
##### Profiling
GHC User Manual has a full ["Profiling"](https://ghc.gitlab.haskell.org/ghc/doc/users_guide/profiling.html) section of relevant info.
To build `hnix` with profiling enabled:
```shell
cabal v2-run hnix --enable-profiling --flags=profiling -- <args> +RTS -p
```
Or to put simply:
```shell
# Run profiling for evaluation of a Firefox package.
# Generate:
# * for all functions
# * time profiling data
# * memory allocation profiling data
# * in the JSON profiling format
cabal v2-run --enable-profiling --flags=profiling --enable-library-profiling --profiling-detail='all-functions' hnix -- --eval --expr '(import <nixpkgs> {}).firefox.outPath' +RTS -Pj
# Then, upload the `hnix.prof` to the https://www.speedscope.app/ to analyze it.
```
"RTS" stands for "RunTime System" and has a lot of options, GHC User Manual has ["Running a compiled program"/"Setting RTS options"](https://ghc.gitlab.haskell.org/ghc/doc/users_guide/runtime_control.html) sections describing them.
##### Full debug info
To run stack traces & full tracing output on `hnix`:
```shell
cabal v2-configure --enable-tests --enable-profiling --flags=profiling --flags=tracing
cabal v2-run hnix -- -v5 --trace <args> +RTS -xc
```
This would give the most information as to what happens during parsing & evaluation.
#### Runing executable
```shell
cabal v2-run hnix -- --help
```
(`--` is for separation between `cabal` & `hnix` args)
### Building with Nix-build
There is a number of build options to use with `nix-build`, documentation of them is in: `./default.nix`, keys essentially pass-through the [Nixpkgs Haskell Lib API](https://github.com/NixOS/nixpkgs/blob/master/pkgs/development/haskell-modules/lib.nix).
Options can be used as:
```shell
nix-build \
--arg <option1> <argument1> \
--arg <option2> <argument2> \
--argstr <option3> "<strinTypeArg>"
```
#### Checking the project
##### Benchmarks
```shell
nix-build \
--arg disableOptimization false \
--arg enableDeadCodeElimination true \
--arg doStrip true \
--arg doBenchmark true
```
##### Profiling
```shell
nix-build \
--arg disableOptimization false \
--arg enableDeadCodeElimination true \
--arg enableLibraryProfiling true \
--arg enableExecutableProfiling true
./result/bin/hnix <args> +RTS -p
```
##### Full debug info
```shell
nix-build \
--arg disableOptimization false \
--arg enableDeadCodeElimination true \
--arg doBenchmark true \
--arg doStrip false \
--arg enableLibraryProfiling true \
--arg enableExecutableProfiling true \
--arg doTracing true \
--arg enableDWARFDebugging true
./result/bin/hnix -v5 --trace <args> +RTS -xc
```
#### Runing executable
```shell
./result/bin/hnix
```
## Using HNix
See:
```
hnix --help
```
It has a pretty full/good description of the current options.
### Parse & print
To parse a file with `hnix` and pretty print the result:
```shell
hnix file.nix
```
### Evaluating and printing the resulting value
Expression from a file:
```shell
hnix --eval file.nix
```
Expression:
```shell
hnix --eval --expr 'import <nixpkgs> {}'
```
### Evaluating Nixpkgs
Currently, the main high-level goal is to be able to evaluate all of Nixpkgs:
```shell
hnix --eval --expr "import <nixpkgs> {}" --find
```
### Options supported only by HNix
To see value provenance and thunk context:
```shell
hnix -v2 --values --thunk --eval --expr 'import <nixpkgs> {}'
```
To see tracing as the evaluator runs (note that building with `cabal configure --flags=tracing` will produce much more output than this):
```shell
hnix --trace --eval --expr 'import <nixpkgs> {}'
```
To attempt to generate a reduced test case demonstrating an error:
```shell
hnix --reduce bug.nix --eval --expr 'import <nixpkgs> {}'
```
### REPL
To enter REPL:
```shell
hnix --repl
```
Evaluate an expression and load it into REPL:
```shell
hnix --eval --expr '(import <nixpkgs> {}).pkgs.hello' --repl
```
This binds the evaluated expression result to the `input` variable, so that variable can be inspected.
Use the `:help` command for a list of all available REPL commands.
#### Language laziness
Nix is a lazy language with the ability of recursion, so by default REPL and eval prints are lazy:
```shell
hnix \
--eval \
--expr '{ x = true; }'
{ x = "<expr>"; }
```
To disable laziness add the `--strict` to commands or `:set strict` in the REPL.
```shell
hnix \
--eval \
--strict \
--expr '{ x = true; }'
{ x = true; }
```
## Contributing
* The Haskell Language Server (HLS) works great with our project.
* [Design of the HNix code base Wiki article](https://github.com/haskell-nix/hnix/wiki/Design-of-the-HNix-code-base).
1. If something in the [quests](https://github.com/haskell-nix/hnix/issues?q=is%3Aissue+is%3Aopen+label%3A%22help+wanted%22+no%3Aassignee) looks interesting, look through the thread and leave a comment taking it, to let others know you're working on it.
2. You are free to chat with everyone on [Gitter](https://gitter.im/haskell-nix/Lobby).
3. When the pull request is ready to be submitted, to save time - please, test it with:
```shell
cabal v2-test
```
Please, check that all default tests that were passing prior are still passing. It's OK if no new tests are passing.
### (optional) Minimalistic development status loop with amazing [`ghcid`](https://github.com/ndmitchell/ghcid)
If HLS is not your cup of yea:
```shell
ghcid --command="cabal v2-repl --repl-options=-fno-code --repl-options=-fno-break-on-exception --repl-options=-fno-break-on-error --repl-options=-v1 --repl-options=-ferror-spans --repl-options=-j"
```
(optional) To use projects reproducible environment, wrap `ghcid ...` command into a `nix-shell --command ' '`.
For simplicity `alias` the command in your shell.
## Current status
To understand the project implementation state see:
* [ChangeLog](https://github.com/haskell-nix/hnix/blob/master/ChangeLog.md)
* [Opened reports](https://github.com/haskell-nix/hnix/issues)
* [Project status](https://github.com/haskell-nix/hnix/wiki/Project-status)
* [Design of the HNix code base](https://github.com/haskell-nix/hnix/wiki/Design-of-the-HNix-code-base)
================================================
FILE: benchmarks/Main.hs
================================================
module Main where
import Criterion.Main
import Nix.Prelude
import qualified ParserBench
main :: IO ()
main = defaultMain $ one ParserBench.benchmarks
================================================
FILE: benchmarks/ParserBench.hs
================================================
module ParserBench (benchmarks) where
import Nix.Parser
import Nix.Prelude
import Criterion
benchFile :: Path -> Benchmark
benchFile = bench . coerce <*> whnfIO . parseNixFile . ("data/" <>)
benchmarks :: Benchmark
benchmarks =
bgroup
"Parser"
$ fmap
benchFile
[ "nixpkgs-all-packages.nix"
, "nixpkgs-all-packages-pretty.nix"
, "let-comments.nix"
, "let-comments-multiline.nix"
, "let.nix"
, "simple.nix"
, "simple-pretty.nix"
]
================================================
FILE: brittany.yaml
================================================
conf_debug:
dconf_roundtrip_exactprint_only: false
dconf_dump_bridoc_simpl_par: false
dconf_dump_ast_unknown: false
dconf_dump_bridoc_simpl_floating: false
dconf_dump_config: false
dconf_dump_bridoc_raw: false
dconf_dump_bridoc_final: false
dconf_dump_bridoc_simpl_alt: false
dconf_dump_bridoc_simpl_indent: false
dconf_dump_annotations: false
dconf_dump_bridoc_simpl_columns: false
dconf_dump_ast_full: false
conf_forward:
options_ghc: []
conf_errorHandling:
econf_ExactPrintFallback: ExactPrintFallbackModeInline
econf_Werror: false
econf_omit_output_valid_check: false
econf_produceOutputOnErrors: false
conf_preprocessor:
ppconf_CPPMode: CPPModeWarn
ppconf_hackAroundIncludes: false
conf_obfuscate: false
conf_roundtrip_exactprint_only: false
conf_version: 1
conf_layout:
lconfig_reformatModulePreamble: true
lconfig_altChooser:
tag: AltChooserBoundedSearch
contents: 3
lconfig_allowSingleLineExportList: true
lconfig_importColumn: 50
lconfig_hangingTypeSignature: false
lconfig_importAsColumn: 50
lconfig_alignmentLimit: 30
lconfig_indentListSpecial: true
lconfig_indentAmount: 2
lconfig_alignmentBreakOnMultiline: true
lconfig_cols: 80
lconfig_indentPolicy: IndentPolicyFree
lconfig_indentWhereSpecial: true
lconfig_columnAlignMode:
tag: ColumnAlignModeMajority
contents: 0.7
================================================
FILE: build.sh
================================================
#!/usr/bin/env bash
# NOTE: Script to easy import nix-build settings from env, useful for tooling env replication and the CI builds, relies on `default.nix` interface, which exposes Nixpkgs Haskell Lib interface
# The most strict error checking requirements
set -Eexuo pipefail
### NOTE: Section handles imports from env, these are settings for Nixpkgs.
### They use the `default.nix` interface, which exposes expose most of the Nixpkgs Haskell.lib API: https://github.com/NixOS/nixpkgs/blob/master/pkgs/development/haskell-modules/lib.nix
### Some of these options implicitly switch the dependent options.
### Documentation of this settings is mosly in `default.nix`, since most settings it Nixpkgs related
### Additional documentation is in Nixpkgs Haskell.lib: https://github.com/NixOS/nixpkgs/blob/master/pkgs/development/haskell-modules/lib.nix
# NOTE: If vars not imported - init the vars with default values
# Non-set/passed ''/'default' compiler setting means currently default GHC of Nixpkgs ecosystem.
compiler=${compiler:-'default'}
packageRoot=${packageRoot:-'pkgs.nix-gitignore.gitignoreSource [ ] ./.'}
cabalName=${cabalName:-'hnix'}
rev=${rev:-'default'}
# Account in Cachix to use
cachixAccount=${cachixAccount:-'hnix'}
allowInconsistentDependencies=${allowInconsistentDependencies:-'false'}
doJailbreak=${doJailbreak:-'false'}
doCheck=${doCheck:-'true'}
sdistTarball=${sdistTarball:-'false'}
buildFromSdist=${buildFromSdist:-'false'}
failOnAllWarnings=${failOnAllWarnings:-'false'}
buildStrictly=${buildStrictly:-'false'}
enableDeadCodeElimination=${enableDeadCodeElimination:-'false'}
disableOptimization=${disableOptimization:-'true'}
linkWithGold=${linkWithGold:-'false'}
enableLibraryProfiling=${enableLibraryProfiling:-'false'}
enableExecutableProfiling=${enableExecutableProfiling:-'false'}
doTracing=${doTracing:-'false'}
enableDWARFDebugging=${enableDWARFDebugging:-'false'}
doStrip=${doStrip:-'false'}
enableSharedLibraries=${enableSharedLibraries:-'true'}
enableStaticLibraries=${enableStaticLibraries:-'false'}
enableSharedExecutables=${enableSharedExecutables:-'false'}
justStaticExecutables=${justStaticExecutables:-'false'}
enableSeparateBinOutput=${enableSeparateBinOutput:-'false'}
checkUnusedPackages=${checkUnusedPackages:-'false'}
doHaddock=${doHaddock:-'false'}
doHyperlinkSource=${doHyperlinkSource:-'false'}
doCoverage=${doCoverage:-'false'}
doBenchmark=${doBenchmark:-'false'}
generateOptparseApplicativeCompletions=${generateOptparseApplicativeCompletions:-'false'}
# [ "binary1" "binary2" ] - should pass " quotes into Nix interpreter
executableNamesToShellComplete=${executableNamesToShellComplete:-'[ "hnix" ]'}
withHoogle=${withHoogle:-'false'}
# If key not provided (branch is not inside the central repo) - init CACHIX_SIGNING_KEY as empty
CACHIX_SIGNING_KEY=${CACHIX_SIGNING_KEY:-""}
BUILD_PROJECT() {
IFS=$'\n\t'
if [ ! "$compiler" = "ghcjs" ]; then
# Normal GHC build
nix-build \
--argstr compiler "$compiler" \
--argstr rev "$rev" \
--arg allowInconsistentDependencies "$allowInconsistentDependencies" \
--arg doJailbreak "$doJailbreak" \
--arg doCheck "$doCheck" \
--arg sdistTarball "$sdistTarball" \
--arg buildFromSdist "$buildFromSdist" \
--arg failOnAllWarnings "$failOnAllWarnings" \
--arg buildStrictly "$buildStrictly" \
--arg enableDeadCodeElimination "$enableDeadCodeElimination" \
--arg disableOptimization "$disableOptimization" \
--arg linkWithGold "$linkWithGold" \
--arg enableLibraryProfiling "$enableLibraryProfiling" \
--arg enableExecutableProfiling "$enableExecutableProfiling" \
--arg doTracing "$doTracing" \
--arg enableDWARFDebugging "$enableDWARFDebugging" \
--arg doStrip "$doStrip" \
--arg doHyperlinkSource "$doHyperlinkSource" \
--arg enableSharedLibraries "$enableSharedLibraries" \
--arg enableStaticLibraries "$enableStaticLibraries" \
--arg enableSharedExecutables "$enableSharedExecutables" \
--arg justStaticExecutables "$justStaticExecutables" \
--arg checkUnusedPackages "$checkUnusedPackages" \
--arg doCoverage "$doCoverage" \
--arg doHaddock "$doHaddock" \
--arg doBenchmark "$doBenchmark" \
--arg generateOptparseApplicativeCompletions "$generateOptparseApplicativeCompletions" \
--arg executableNamesToShellComplete "$executableNamesToShellComplete" \
--arg withHoogle "$withHoogle"
fi
}
MAIN() {
# Overall it is useful to have in CI test builds the latest stable Nix
# 2020-06-24: HACK: Do not ask why different commands on Linux and macOS. IDK, wished they we the same. These are the only commands that worked on according platforms right after the fresh Nix installer rollout.
# 2020-07-06: HACK: GitHub Actions CI shown that nix-channel or nix-upgrade-nix do not work, there is probably some new rollout, shortcircuting for the time bing with || true
(nix-channel --update && nix-env -u) || (sudo nix upgrade-nix) || true
# Report the Nixpkgs channel revision
nix-instantiate --eval -E 'with import <nixpkgs> {}; lib.version or lib.nixpkgsVersion'
# Secrets are not shared to PRs from forks
# nix-build | cachix push <account> - uploads binaries, runs&works only in the branches of the main repository, so for PRs - else case runs
if [ ! "$CACHIX_SIGNING_KEY" = "" ]; then
# Build of the inside repo branch - enable push Cachix cache
BUILD_PROJECT | cachix push "$cachixAccount"
else
# Build of the side repo/PR - can not push Cachix cache
BUILD_PROJECT
fi
}
# Run the entry function of the script
MAIN
================================================
FILE: cabal.project
================================================
packages:
./hnix.cabal
================================================
FILE: data/let-comments-multiline.nix
================================================
let
b.a = 3; /*
this is a multiline comment
/* we can also nest these comments
*/ /*
*/
b.c = { e = {}; };
/* just some more comments
*/
b.c.e.f = 4;
/* this file is documented really well */
in b /* todo */
================================================
FILE: data/let-comments.nix
================================================
let
b.a = 3;
# this is a oneline comment
# we can also nest these comments
# #
#
#
b.c = { e = {}; };
# just some more comments
#
b.c.e.f = 4;
# this file is documented really well
in b # todo
================================================
FILE: data/let.nix
================================================
let
b.a = 3;
b.c = { e = {}; };
b.c.e.f = 4;
in b
================================================
FILE: data/nix/README.md
================================================
Extracted from https://github.com/NixOS/nix (GPLv2)
commit 6c2af1f201a925c2aa632737765685c72b642847
Date: Mon Nov 8 14:13:42 202
Keep only `tests/lang` which are required by `hnix`es testsuite.
================================================
FILE: data/nix/tests/lang/data
================================================
foo
================================================
FILE: data/nix/tests/lang/dir1/a.nix
================================================
"a"
================================================
FILE: data/nix/tests/lang/dir2/a.nix
================================================
"X"
================================================
FILE: data/nix/tests/lang/dir2/b.nix
================================================
"b"
================================================
FILE: data/nix/tests/lang/dir3/a.nix
================================================
"X"
================================================
FILE: data/nix/tests/lang/dir3/b.nix
================================================
"X"
================================================
FILE: data/nix/tests/lang/dir3/c.nix
================================================
"c"
================================================
FILE: data/nix/tests/lang/dir4/a.nix
================================================
"X"
================================================
FILE: data/nix/tests/lang/dir4/c.nix
================================================
"X"
================================================
FILE: data/nix/tests/lang/eval-fail-abort.nix
================================================
if true then abort "this should fail" else 1
================================================
FILE: data/nix/tests/lang/eval-fail-assert.nix
================================================
let {
x = arg: assert arg == "y"; 123;
body = x "x";
}
================================================
FILE: data/nix/tests/lang/eval-fail-bad-antiquote-1.nix
================================================
"${x: x}"
================================================
FILE: data/nix/tests/lang/eval-fail-bad-antiquote-2.nix
================================================
"${./fnord}"
================================================
FILE: data/nix/tests/lang/eval-fail-bad-antiquote-3.nix
================================================
''${x: x}''
================================================
FILE: data/nix/tests/lang/eval-fail-blackhole.nix
================================================
let {
body = x;
x = y;
y = x;
}
================================================
FILE: data/nix/tests/lang/eval-fail-deepseq.nix
================================================
builtins.deepSeq { x = abort "foo"; } 456
================================================
FILE: data/nix/tests/lang/eval-fail-hashfile-missing.nix
================================================
let
paths = [ ./this-file-is-definitely-not-there-7392097 "/and/neither/is/this/37293620" ];
in
toString (builtins.concatLists (map (hash: map (builtins.hashFile hash) paths) ["md5" "sha1" "sha256" "sha512"]))
================================================
FILE: data/nix/tests/lang/eval-fail-missing-arg.nix
================================================
({x, y, z}: x + y + z) {x = "foo"; z = "bar";}
================================================
FILE: data/nix/tests/lang/eval-fail-nonexist-path.nix
================================================
# This must fail to evaluate, since ./fnord doesn't exist. If it did
# exist, it would produce "/nix/store/<hash>-fnord/xyzzy" (with an
# appropriate context).
"${./fnord}/xyzzy"
================================================
FILE: data/nix/tests/lang/eval-fail-path-slash.nix
================================================
# Trailing slashes in paths are not allowed.
# This restriction could be lifted sometime,
# for example if we make '/' a path concatenation operator.
# See https://github.com/NixOS/nix/issues/1138
# and https://nixos.org/nix-dev/2016-June/020829.html
/nix/store/
================================================
FILE: data/nix/tests/lang/eval-fail-remove.nix
================================================
let {
attrs = {x = 123; y = 456;};
body = (removeAttrs attrs ["x"]).x;
}
================================================
FILE: data/nix/tests/lang/eval-fail-scope-5.nix
================================================
let {
x = "a";
y = "b";
f = {x ? y, y ? x}: x + y;
body = f {};
}
================================================
FILE: data/nix/tests/lang/eval-fail-seq.nix
================================================
builtins.seq (abort "foo") 2
================================================
FILE: data/nix/tests/lang/eval-fail-substring.nix
================================================
builtins.substring (builtins.sub 0 1) 1 "x"
================================================
FILE: data/nix/tests/lang/eval-fail-to-path.nix
================================================
builtins.toPath "foo/bar"
================================================
FILE: data/nix/tests/lang/eval-fail-undeclared-arg.nix
================================================
({x, z}: x + z) {x = "foo"; y = "bla"; z = "bar";}
================================================
FILE: data/nix/tests/lang/eval-okay-any-all.exp
================================================
[ false false true true true true false true ]
================================================
FILE: data/nix/tests/lang/eval-okay-any-all.nix
================================================
with builtins;
[ (any (x: x == 1) [])
(any (x: x == 1) [2 3 4])
(any (x: x == 1) [1 2 3 4])
(any (x: x == 1) [4 3 2 1])
(all (x: x == 1) [])
(all (x: x == 1) [1])
(all (x: x == 1) [1 2 3])
(all (x: x == 1) [1 1 1])
]
================================================
FILE: data/nix/tests/lang/eval-okay-arithmetic.exp
================================================
2216
================================================
FILE: data/nix/tests/lang/eval-okay-arithmetic.nix
================================================
with import ./lib.nix;
let {
/* Supposedly tail recursive version:
range_ = accum: first: last:
if first == last then ([first] ++ accum)
else range_ ([first] ++ accum) (builtins.add first 1) last;
range = range_ [];
*/
x = 12;
err = abort "urgh";
body = sum
[ (sum (range 1 50))
(123 + 456)
(0 + -10 + -(-11) + -x)
(10 - 7 - -2)
(10 - (6 - -1))
(10 - 1 + 2)
(3 * 4 * 5)
(56088 / 123 / 2)
(3 + 4 * const 5 0 - 6 / id 2)
(builtins.bitAnd 12 10) # 0b1100 & 0b1010 = 8
(builtins.bitOr 12 10) # 0b1100 | 0b1010 = 14
(builtins.bitXor 12 10) # 0b1100 ^ 0b1010 = 6
(if 3 < 7 then 1 else err)
(if 7 < 3 then err else 1)
(if 3 < 3 then err else 1)
(if 3 <= 7 then 1 else err)
(if 7 <= 3 then err else 1)
(if 3 <= 3 then 1 else err)
(if 3 > 7 then err else 1)
(if 7 > 3 then 1 else err)
(if 3 > 3 then err else 1)
(if 3 >= 7 then err else 1)
(if 7 >= 3 then 1 else err)
(if 3 >= 3 then 1 else err)
(if 2 > 1 == 1 < 2 then 1 else err)
(if 1 + 2 * 3 >= 7 then 1 else err)
(if 1 + 2 * 3 < 7 then err else 1)
# Not integer, but so what.
(if "aa" < "ab" then 1 else err)
(if "aa" < "aa" then err else 1)
(if "foo" < "foobar" then 1 else err)
];
}
================================================
FILE: data/nix/tests/lang/eval-okay-attrnames.exp
================================================
"newxfoonewxy"
================================================
FILE: data/nix/tests/lang/eval-okay-attrnames.nix
================================================
with import ./lib.nix;
let
attrs = {y = "y"; x = "x"; foo = "foo";} // rec {x = "newx"; bar = x;};
names = builtins.attrNames attrs;
values = map (name: builtins.getAttr name attrs) names;
in assert values == builtins.attrValues attrs; concat values
================================================
FILE: data/nix/tests/lang/eval-okay-attrs.exp
================================================
987
================================================
FILE: data/nix/tests/lang/eval-okay-attrs.nix
================================================
let {
as = { x = 123; y = 456; } // { z = 789; } // { z = 987; };
body = if as ? a then as.a else assert as ? z; as.z;
}
================================================
FILE: data/nix/tests/lang/eval-okay-attrs2.exp
================================================
987
================================================
FILE: data/nix/tests/lang/eval-okay-attrs2.nix
================================================
let {
as = { x = 123; y = 456; } // { z = 789; } // { z = 987; };
A = "a";
Z = "z";
body = if builtins.hasAttr A as
then builtins.getAttr A as
else assert builtins.hasAttr Z as; builtins.getAttr Z as;
}
================================================
FILE: data/nix/tests/lang/eval-okay-attrs3.exp
================================================
"foo 22 80 itchyxac"
================================================
FILE: data/nix/tests/lang/eval-okay-attrs3.nix
================================================
let
config =
{
services.sshd.enable = true;
services.sshd.port = 22;
services.httpd.port = 80;
hostName = "itchy";
a.b.c.d.e.f.g.h.i.j.k.l.m.n.o.p.q.r.s.t.u.v.w.x.y.z = "x";
foo = {
a = "a";
b.c = "c";
};
};
in
if config.services.sshd.enable
then "foo ${toString config.services.sshd.port} ${toString config.services.httpd.port} ${config.hostName}"
+ "${config.a.b.c.d.e.f.g.h.i.j.k.l.m.n.o.p.q.r.s.t.u.v.w.x.y.z}"
+ "${config.foo.a}"
+ "${config.foo.b.c}"
else "bar"
================================================
FILE: data/nix/tests/lang/eval-okay-attrs4.exp
================================================
[ true false true false false true false false ]
================================================
FILE: data/nix/tests/lang/eval-okay-attrs4.nix
================================================
let
as = { x.y.z = 123; a.b.c = 456; };
bs = null;
in [ (as ? x) (as ? y) (as ? x.y.z) (as ? x.y.z.a) (as ? x.y.a) (as ? a.b.c) (bs ? x) (bs ? x.y.z) ]
================================================
FILE: data/nix/tests/lang/eval-okay-attrs5.exp
================================================
[ 123 "foo" 456 456 "foo" "xyzzy" "xyzzy" true ]
================================================
FILE: data/nix/tests/lang/eval-okay-attrs5.nix
================================================
with import ./lib.nix;
let
as = { x.y.z = 123; a.b.c = 456; };
bs = { f-o-o.bar = "foo"; };
or = x: y: x || y;
in
[ as.x.y.z
as.foo or "foo"
as.x.y.bla or as.a.b.c
as.a.b.c or as.x.y.z
as.x.y.bla or bs.f-o-o.bar or "xyzzy"
as.x.y.bla or bs.bar.foo or "xyzzy"
(123).bla or null.foo or "xyzzy"
# Backwards compatibility test.
(fold or [] [true false false])
]
================================================
FILE: data/nix/tests/lang/eval-okay-attrs6.exp
================================================
{ __overrides = { bar = "qux"; }; bar = "qux"; foo = "bar"; }
================================================
FILE: data/nix/tests/lang/eval-okay-attrs6.nix
================================================
rec {
"${"foo"}" = "bar";
__overrides = { bar = "qux"; };
}
================================================
FILE: data/nix/tests/lang/eval-okay-autoargs.exp
================================================
"xyzzy!xyzzy!foobar"
================================================
FILE: data/nix/tests/lang/eval-okay-autoargs.flags
================================================
--arg lib import(lang/lib.nix) --argstr xyzzy xyzzy! -A result
================================================
FILE: data/nix/tests/lang/eval-okay-autoargs.nix
================================================
let
foobar = "foobar";
in
{ xyzzy2 ? xyzzy # mutually recursive args
, xyzzy ? "blaat" # will be overridden by --argstr
, fb ? foobar
, lib # will be set by --arg
}:
{
result = lib.concat [xyzzy xyzzy2 fb];
}
================================================
FILE: data/nix/tests/lang/eval-okay-backslash-newline-1.exp
================================================
"a\nb"
================================================
FILE: data/nix/tests/lang/eval-okay-backslash-newline-1.nix
================================================
"a\
b"
================================================
FILE: data/nix/tests/lang/eval-okay-backslash-newline-2.exp
================================================
"a\nb"
================================================
FILE: data/nix/tests/lang/eval-okay-backslash-newline-2.nix
================================================
''a''\
b''
================================================
FILE: data/nix/tests/lang/eval-okay-builtins-add.exp
================================================
[ 5 4 "int" "tt" "float" 4 ]
================================================
FILE: data/nix/tests/lang/eval-okay-builtins-add.nix
================================================
[
(builtins.add 2 3)
(builtins.add 2 2)
(builtins.typeOf (builtins.add 2 2))
("t" + "t")
(builtins.typeOf (builtins.add 2.0 2))
(builtins.add 2.0 2)
]
================================================
FILE: data/nix/tests/lang/eval-okay-builtins.exp
================================================
/foo
================================================
FILE: data/nix/tests/lang/eval-okay-builtins.nix
================================================
assert builtins ? currentSystem;
assert !builtins ? __currentSystem;
let {
x = if builtins ? dirOf then builtins.dirOf /foo/bar else "";
y = if builtins ? fnord then builtins.fnord "foo" else "";
body = x + y;
}
================================================
FILE: data/nix/tests/lang/eval-okay-callable-attrs.exp
================================================
true
================================================
FILE: data/nix/tests/lang/eval-okay-callable-attrs.nix
================================================
({ __functor = self: x: self.foo && x; foo = false; } // { foo = true; }) true
================================================
FILE: data/nix/tests/lang/eval-okay-catattrs.exp
================================================
[ 1 2 ]
================================================
FILE: data/nix/tests/lang/eval-okay-catattrs.nix
================================================
builtins.catAttrs "a" [ { a = 1; } { b = 0; } { a = 2; } ]
================================================
FILE: data/nix/tests/lang/eval-okay-closure.exp.xml
================================================
<?xml version='1.0' encoding='utf-8'?>
<expr>
<list>
<attrs>
<attr name="foo">
<bool value="true" />
</attr>
<attr name="key">
<int value="-13" />
</attr>
</attrs>
<attrs>
<attr name="foo">
<bool value="true" />
</attr>
<attr name="key">
<int value="-12" />
</attr>
</attrs>
<attrs>
<attr name="foo">
<bool value="true" />
</attr>
<attr name="key">
<int value="-11" />
</attr>
</attrs>
<attrs>
<attr name="foo">
<bool value="true" />
</attr>
<attr name="key">
<int value="-9" />
</attr>
</attrs>
<attrs>
<attr name="foo">
<bool value="true" />
</attr>
<attr name="key">
<int value="-8" />
</attr>
</attrs>
<attrs>
<attr name="foo">
<bool value="true" />
</attr>
<attr name="key">
<int value="-7" />
</attr>
</attrs>
<attrs>
<attr name="foo">
<bool value="true" />
</attr>
<attr name="key">
<int value="-5" />
</attr>
</attrs>
<attrs>
<attr name="foo">
<bool value="true" />
</attr>
<attr name="key">
<int value="-4" />
</attr>
</attrs>
<attrs>
<attr name="foo">
<bool value="true" />
</attr>
<attr name="key">
<int value="-3" />
</attr>
</attrs>
<attrs>
<attr name="key">
<int value="-1" />
</attr>
</attrs>
<attrs>
<attr name="foo">
<bool value="true" />
</attr>
<attr name="key">
<int value="0" />
</attr>
</attrs>
<attrs>
<attr name="foo">
<bool value="true" />
</attr>
<attr name="key">
<int value="1" />
</attr>
</attrs>
<attrs>
<attr name="foo">
<bool value="true" />
</attr>
<attr name="key">
<int value="2" />
</attr>
</attrs>
<attrs>
<attr name="foo">
<bool value="true" />
</attr>
<attr name="key">
<int value="4" />
</attr>
</attrs>
<attrs>
<attr name="foo">
<bool value="true" />
</attr>
<attr name="key">
<int value="5" />
</attr>
</attrs>
<attrs>
<attr name="foo">
<bool value="true" />
</attr>
<attr name="key">
<int value="6" />
</attr>
</attrs>
<attrs>
<attr name="key">
<int value="8" />
</attr>
</attrs>
<attrs>
<attr name="foo">
<bool value="true" />
</attr>
<attr name="key">
<int value="9" />
</attr>
</attrs>
<attrs>
<attr name="foo">
<bool value="true" />
</attr>
<attr name="key">
<int value="10" />
</attr>
</attrs>
<attrs>
<attr name="foo">
<bool value="true" />
</attr>
<attr name="key">
<int value="13" />
</attr>
</attrs>
<attrs>
<attr name="foo">
<bool value="true" />
</attr>
<attr name="key">
<int value="14" />
</attr>
</attrs>
<attrs>
<attr name="foo">
<bool value="true" />
</attr>
<attr name="key">
<int value="15" />
</attr>
</attrs>
<attrs>
<attr name="key">
<int value="17" />
</attr>
</attrs>
<attrs>
<attr name="foo">
<bool value="true" />
</attr>
<attr name="key">
<int value="18" />
</attr>
</attrs>
<attrs>
<attr name="foo">
<bool value="true" />
</attr>
<attr name="key">
<int value="19" />
</attr>
</attrs>
<attrs>
<attr name="foo">
<bool value="true" />
</attr>
<attr name="key">
<int value="22" />
</attr>
</attrs>
<attrs>
<attr name="foo">
<bool value="true" />
</attr>
<attr name="key">
<int value="23" />
</attr>
</attrs>
<attrs>
<attr name="key">
<int value="26" />
</attr>
</attrs>
<attrs>
<attr name="foo">
<bool value="true" />
</attr>
<attr name="key">
<int value="27" />
</attr>
</attrs>
<attrs>
<attr name="foo">
<bool value="true" />
</attr>
<attr name="key">
<int value="28" />
</attr>
</attrs>
<attrs>
<attr name="foo">
<bool value="true" />
</attr>
<attr name="key">
<int value="31" />
</attr>
</attrs>
<attrs>
<attr name="foo">
<bool value="true" />
</attr>
<attr name="key">
<int value="32" />
</attr>
</attrs>
<attrs>
<attr name="key">
<int value="35" />
</attr>
</attrs>
<attrs>
<attr name="foo">
<bool value="true" />
</attr>
<attr name="key">
<int value="36" />
</attr>
</attrs>
<attrs>
<attr name="foo">
<bool value="true" />
</attr>
<attr name="key">
<int value="40" />
</attr>
</attrs>
<attrs>
<attr name="foo">
<bool value="true" />
</attr>
<attr name="key">
<int value="41" />
</attr>
</attrs>
<attrs>
<attr name="key">
<int value="44" />
</attr>
</attrs>
<attrs>
<attr name="foo">
<bool value="true" />
</attr>
<attr name="key">
<int value="45" />
</attr>
</attrs>
<attrs>
<attr name="foo">
<bool value="true" />
</attr>
<attr name="key">
<int value="49" />
</attr>
</attrs>
<attrs>
<attr name="key">
<int value="53" />
</attr>
</attrs>
<attrs>
<attr name="foo">
<bool value="true" />
</attr>
<attr name="key">
<int value="54" />
</attr>
</attrs>
<attrs>
<attr name="foo">
<bool value="true" />
</attr>
<attr name="key">
<int value="58" />
</attr>
</attrs>
<attrs>
<attr name="key">
<int value="62" />
</attr>
</attrs>
<attrs>
<attr name="foo">
<bool value="true" />
</attr>
<attr name="key">
<int value="67" />
</attr>
</attrs>
<attrs>
<attr name="key">
<int value="71" />
</attr>
</attrs>
<attrs>
<attr name="key">
<int value="80" />
</attr>
</attrs>
</list>
</expr>
================================================
FILE: data/nix/tests/lang/eval-okay-closure.nix
================================================
let
closure = builtins.genericClosure {
startSet = [{key = 80;}];
operator = {key, foo ? false}:
if builtins.lessThan key 0
then []
else [{key = builtins.sub key 9;} {key = builtins.sub key 13; foo = true;}];
};
sort = (import ./lib.nix).sortBy (a: b: builtins.lessThan a.key b.key);
in sort closure
================================================
FILE: data/nix/tests/lang/eval-okay-comments.exp
================================================
"abcdefghijklmnopqrstuvwxyz"
================================================
FILE: data/nix/tests/lang/eval-okay-comments.nix
================================================
# A simple comment
"a"+ # And another
## A double comment
"b"+ ## And another
# Nested # comments #
"c"+ # and # some # other #
# An empty line, following here:
"d"+ # and a comment not starting the line !
"e"+
/* multiline comments */
"f" +
/* multiline
comments,
on
multiple
lines
*/
"g" +
# Small, tricky comments
/**/ "h"+ /*/*/ "i"+ /***/ "j"+ /* /*/ "k"+ /*/* /*/ "l"+
# Comments with an even number of ending '*' used to fail:
"m"+
/* */ /* **/ /* ***/ /* ****/ "n"+
/* */ /** */ /*** */ /**** */ "o"+
/** **/ /*** ***/ /**** ****/ "p"+
/* * ** *** **** ***** */ "q"+
# Random comments
/* ***** ////// * / * / /* */ "r"+
# Mixed comments
/* # */
"s"+
# /* #
"t"+
# /* # */
"u"+
# /*********/
"v"+
## */*
"w"+
/*
* Multiline, decorated comments
* # This ain't a nest'd comm'nt
*/
"x"+
''${/** with **/"y"
# real
/* comments
inside ! # */
# (and empty lines)
}''+ /* And a multiline comment,
on the same line,
after some spaces
*/ # followed by a one-line comment
"z"
/* EOF */
================================================
FILE: data/nix/tests/lang/eval-okay-concat.exp
================================================
[ 1 2 3 4 5 6 7 8 9 ]
================================================
FILE: data/nix/tests/lang/eval-okay-concat.nix
================================================
[1 2 3] ++ [4 5 6] ++ [7 8 9]
================================================
FILE: data/nix/tests/lang/eval-okay-concatmap.exp
================================================
[ [ 1 3 5 7 9 ] [ "a" "z" "b" "z" ] ]
================================================
FILE: data/nix/tests/lang/eval-okay-concatmap.nix
================================================
with import ./lib.nix;
[ (builtins.concatMap (x: if x / 2 * 2 == x then [] else [ x ]) (range 0 10))
(builtins.concatMap (x: [x] ++ ["z"]) ["a" "b"])
]
================================================
FILE: data/nix/tests/lang/eval-okay-concatstringssep.exp
================================================
[ "" "foobarxyzzy" "foo, bar, xyzzy" "foo" "" ]
================================================
FILE: data/nix/tests/lang/eval-okay-concatstringssep.nix
================================================
with builtins;
[ (concatStringsSep "" [])
(concatStringsSep "" ["foo" "bar" "xyzzy"])
(concatStringsSep ", " ["foo" "bar" "xyzzy"])
(concatStringsSep ", " ["foo"])
(concatStringsSep ", " [])
]
================================================
FILE: data/nix/tests/lang/eval-okay-context-introspection.exp
================================================
true
================================================
FILE: data/nix/tests/lang/eval-okay-context-introspection.nix
================================================
let
drv = derivation {
name = "fail";
builder = "/bin/false";
system = "x86_64-linux";
outputs = [ "out" "foo" ];
};
path = "${./eval-okay-context-introspection.nix}";
desired-context = {
"${builtins.unsafeDiscardStringContext path}" = {
path = true;
};
"${builtins.unsafeDiscardStringContext drv.drvPath}" = {
outputs = [ "foo" "out" ];
allOutputs = true;
};
};
legit-context = builtins.getContext "${path}${drv.outPath}${drv.foo.outPath}${drv.drvPath}";
constructed-context = builtins.getContext (builtins.appendContext "" desired-context);
in legit-context == constructed-context
================================================
FILE: data/nix/tests/lang/eval-okay-context.exp
================================================
"foo eval-okay-context.nix bar"
================================================
FILE: data/nix/tests/lang/eval-okay-context.nix
================================================
let s = "foo ${builtins.substring 33 100 (baseNameOf "${./eval-okay-context.nix}")} bar";
in
if s != "foo eval-okay-context.nix bar"
then abort "context not discarded"
else builtins.unsafeDiscardStringContext s
================================================
FILE: data/nix/tests/lang/eval-okay-curpos.exp
================================================
[ 3 7 4 9 ]
================================================
FILE: data/nix/tests/lang/eval-okay-curpos.nix
================================================
# Bla
let
x = __curPos;
y = __curPos;
in [ x.line x.column y.line y.column ]
================================================
FILE: data/nix/tests/lang/eval-okay-deepseq.exp
================================================
456
================================================
FILE: data/nix/tests/lang/eval-okay-deepseq.nix
================================================
builtins.deepSeq (let as = { x = 123; y = as; }; in as) 456
================================================
FILE: data/nix/tests/lang/eval-okay-delayed-with-inherit.exp
================================================
"b-overridden"
================================================
FILE: data/nix/tests/lang/eval-okay-delayed-with-inherit.nix
================================================
let
pkgs_ = with pkgs; {
a = derivation {
name = "a";
system = builtins.currentSystem;
builder = "/bin/sh";
args = [ "-c" "touch $out" ];
inherit b;
};
inherit b;
};
packageOverrides = p: {
b = derivation {
name = "b-overridden";
system = builtins.currentSystem;
builder = "/bin/sh";
args = [ "-c" "touch $out" ];
};
};
pkgs = pkgs_ // (packageOverrides pkgs_);
in pkgs.a.b.name
================================================
FILE: data/nix/tests/lang/eval-okay-delayed-with.exp
================================================
"b-overridden b-overridden a"
================================================
FILE: data/nix/tests/lang/eval-okay-delayed-with.nix
================================================
let
pkgs_ = with pkgs; {
a = derivation {
name = "a";
system = builtins.currentSystem;
builder = "/bin/sh";
args = [ "-c" "touch $out" ];
inherit b;
};
b = derivation {
name = "b";
system = builtins.currentSystem;
builder = "/bin/sh";
args = [ "-c" "touch $out" ];
inherit a;
};
c = b;
};
packageOverrides = pkgs: with pkgs; {
b = derivation (b.drvAttrs // { name = "${b.name}-overridden"; });
};
pkgs = pkgs_ // (packageOverrides pkgs_);
in "${pkgs.a.b.name} ${pkgs.c.name} ${pkgs.b.a.name}"
================================================
FILE: data/nix/tests/lang/eval-okay-dynamic-attrs-2.exp
================================================
true
================================================
FILE: data/nix/tests/lang/eval-okay-dynamic-attrs-2.nix
================================================
{ a."${"b"}" = true; a."${"c"}" = false; }.a.b
================================================
FILE: data/nix/tests/lang/eval-okay-dynamic-attrs-bare.exp
================================================
{ binds = true; hasAttrs = true; multiAttrs = true; recBinds = true; selectAttrs = true; selectOrAttrs = true; }
================================================
FILE: data/nix/tests/lang/eval-okay-dynamic-attrs-bare.nix
================================================
let
aString = "a";
bString = "b";
in {
hasAttrs = { a.b = null; } ? ${aString}.b;
selectAttrs = { a.b = true; }.a.${bString};
selectOrAttrs = { }.${aString} or true;
binds = { ${aString}."${bString}c" = true; }.a.bc;
recBinds = rec { ${bString} = a; a = true; }.b;
multiAttrs = { ${aString} = true; ${bString} = false; }.a;
}
================================================
FILE: data/nix/tests/lang/eval-okay-dynamic-attrs.exp
================================================
{ binds = true; hasAttrs = true; multiAttrs = true; recBinds = true; selectAttrs = true; selectOrAttrs = true; }
================================================
FILE: data/nix/tests/lang/eval-okay-dynamic-attrs.nix
================================================
let
aString = "a";
bString = "b";
in {
hasAttrs = { a.b = null; } ? "${aString}".b;
selectAttrs = { a.b = true; }.a."${bString}";
selectOrAttrs = { }."${aString}" or true;
binds = { "${aString}"."${bString}c" = true; }.a.bc;
recBinds = rec { "${bString}" = a; a = true; }.b;
multiAttrs = { "${aString}" = true; "${bString}" = false; }.a;
}
================================================
FILE: data/nix/tests/lang/eval-okay-elem.exp
================================================
[ true false 30 ]
================================================
FILE: data/nix/tests/lang/eval-okay-elem.nix
================================================
with import ./lib.nix;
let xs = range 10 40; in
[ (builtins.elem 23 xs) (builtins.elem 42 xs) (builtins.elemAt xs 20) ]
================================================
FILE: data/nix/tests/lang/eval-okay-empty-args.exp
================================================
"ab"
================================================
FILE: data/nix/tests/lang/eval-okay-empty-args.nix
================================================
({}: {x,y,}: "${x}${y}") {} {x = "a"; y = "b";}
================================================
FILE: data/nix/tests/lang/eval-okay-eq-derivations.exp
================================================
[ true true true false ]
================================================
FILE: data/nix/tests/lang/eval-okay-eq-derivations.nix
================================================
let
drvA1 = derivation { name = "a"; builder = "/foo"; system = "i686-linux"; };
drvA2 = derivation { name = "a"; builder = "/foo"; system = "i686-linux"; };
drvA3 = derivation { name = "a"; builder = "/foo"; system = "i686-linux"; } // { dummy = 1; };
drvC1 = derivation { name = "c"; builder = "/foo"; system = "i686-linux"; };
drvC2 = derivation { name = "c"; builder = "/bar"; system = "i686-linux"; };
in [ (drvA1 == drvA1) (drvA1 == drvA2) (drvA1 == drvA3) (drvC1 == drvC2) ]
================================================
FILE: data/nix/tests/lang/eval-okay-eq.exp.disabled
================================================
Bool(True)
================================================
FILE: data/nix/tests/lang/eval-okay-eq.nix
================================================
["foobar" (rec {x = 1; y = x;})]
==
[("foo" + "bar") ({x = 1; y = 1;})]
================================================
FILE: data/nix/tests/lang/eval-okay-filter.exp
================================================
[ 0 2 4 6 8 10 100 102 104 106 108 110 ]
================================================
FILE: data/nix/tests/lang/eval-okay-filter.nix
================================================
with import ./lib.nix;
builtins.filter
(x: x / 2 * 2 == x)
(builtins.concatLists [ (range 0 10) (range 100 110) ])
================================================
FILE: data/nix/tests/lang/eval-okay-flatten.exp
================================================
"1234567"
================================================
FILE: data/nix/tests/lang/eval-okay-flatten.nix
================================================
with import ./lib.nix;
let {
l = ["1" "2" ["3" ["4"] ["5" "6"]] "7"];
body = concat (flatten l);
}
================================================
FILE: data/nix/tests/lang/eval-okay-float.exp
================================================
[ 3.4 3.5 2.5 1.5 ]
================================================
FILE: data/nix/tests/lang/eval-okay-float.nix
================================================
[
(1.1 + 2.3)
(builtins.add (0.5 + 0.5) (2.0 + 0.5))
((0.5 + 0.5) * (2.0 + 0.5))
((1.5 + 1.5) / (0.5 * 4.0))
]
================================================
FILE: data/nix/tests/lang/eval-okay-floor-ceil.exp
================================================
"23;24;23;23"
================================================
FILE: data/nix/tests/lang/eval-okay-floor-ceil.nix
================================================
with import ./lib.nix;
let
n1 = builtins.floor 23.5;
n2 = builtins.ceil 23.5;
n3 = builtins.floor 23;
n4 = builtins.ceil 23;
in
builtins.concatStringsSep ";" (map toString [ n1 n2 n3 n4 ])
================================================
FILE: data/nix/tests/lang/eval-okay-foldlStrict.exp
================================================
500500
================================================
FILE: data/nix/tests/lang/eval-okay-foldlStrict.nix
================================================
with import ./lib.nix;
builtins.foldl' (x: y: x + y) 0 (range 1 1000)
================================================
FILE: data/nix/tests/lang/eval-okay-fromTOML.exp
================================================
[ { clients = { data = [ [ "gamma" "delta" ] [ 1 2 ] ]; hosts = [ "alpha" "omega" ]; }; database = { connection_max = 5000; enabled = true; ports = [ 8001 8001 8002 ]; server = "192.168.1.1"; }; owner = { name = "Tom Preston-Werner"; }; servers = { alpha = { dc = "eqdc10"; ip = "10.0.0.1"; }; beta = { dc = "eqdc10"; ip = "10.0.0.2"; }; }; title = "TOML Example"; } { "1234" = "value"; "127.0.0.1" = "value"; a = { b = { c = { }; }; }; arr1 = [ 1 2 3 ]; arr2 = [ "red" "yellow" "green" ]; arr3 = [ [ 1 2 ] [ 3 4 5 ] ]; arr4 = [ "all" "strings" "are the same" "type" ]; arr5 = [ [ 1 2 ] [ "a" "b" "c" ] ]; arr7 = [ 1 2 3 ]; arr8 = [ 1 2 ]; bare-key = "value"; bare_key = "value"; bin1 = 214; bool1 = true; bool2 = false; "character encoding" = "value"; d = { e = { f = { }; }; }; dog = { "tater.man" = { type = { name = "pug"; }; }; }; flt1 = 1; flt2 = 3.1415; flt3 = -0.01; flt4 = 5e+22; flt5 = 1e+06; flt6 = -0.02; flt7 = 6.626e-34; flt8 = 9.22462e+06; fruit = [ { name = "apple"; physical = { color = "red"; shape = "round"; }; variety = [ { name = "red delicious"; } { name = "granny smith"; } ]; } { name = "banana"; variety = [ { name = "plantain"; } ]; } ]; g = { h = { i = { }; }; }; hex1 = 3735928559; hex2 = 3735928559; hex3 = 3735928559; int1 = 99; int2 = 42; int3 = 0; int4 = -17; int5 = 1000; int6 = 5349221; int7 = 12345; j = { "ʞ" = { l = { }; }; }; key = "value"; key2 = "value"; name = "Orange"; oct1 = 342391; oct2 = 493; physical = { color = "orange"; shape = "round"; }; products = [ { name = "Hammer"; sku = 738594937; } { } { color = "gray"; name = "Nail"; sku = 284758393; } ]; "quoted \"value\"" = "value"; site = { "google.com" = true; }; str = "I'm a string. \"You can quote me\". Name\tJosé\nLocation\tSF."; table-1 = { key1 = "some string"; key2 = 123; }; table-2 = { key1 = "another string"; key2 = 456; }; x = { y = { z = { w = { animal = { type = { name = "pug"; }; }; name = { first = "Tom"; last = "Preston-Werner"; }; point = { x = 1; y = 2; }; }; }; }; }; "ʎǝʞ" = "value"; } { metadata = { "checksum aho-corasick 0.6.4 (registry+https://github.com/rust-lang/crates.io-index)" = "d6531d44de723825aa81398a6415283229725a00fa30713812ab9323faa82fc4"; "checksum ansi_term 0.11.0 (registry+https://github.com/rust-lang/crates.io-index)" = "ee49baf6cb617b853aa8d93bf420db2383fab46d314482ca2803b40d5fde979b"; "checksum ansi_term 0.9.0 (registry+https://github.com/rust-lang/crates.io-index)" = "23ac7c30002a5accbf7e8987d0632fa6de155b7c3d39d0067317a391e00a2ef6"; "checksum arrayvec 0.4.7 (registry+https://github.com/rust-lang/crates.io-index)" = "a1e964f9e24d588183fcb43503abda40d288c8657dfc27311516ce2f05675aef"; }; package = [ { dependencies = [ "memchr 2.0.1 (registry+https://github.com/rust-lang/crates.io-index)" ]; name = "aho-corasick"; source = "registry+https://github.com/rust-lang/crates.io-index"; version = "0.6.4"; } { name = "ansi_term"; source = "registry+https://github.com/rust-lang/crates.io-index"; version = "0.9.0"; } { dependencies = [ "libc 0.2.42 (registry+https://github.com/rust-lang/crates.io-index)" "termion 1.5.1 (registry+https://github.com/rust-lang/crates.io-index)" "winapi 0.3.5 (registry+https://github.com/rust-lang/crates.io-index)" ]; name = "atty"; source = "registry+https://github.com/rust-lang/crates.io-index"; version = "0.2.10"; } ]; } { a = [ [ { b = true; } ] ]; c = [ [ { d = true; } ] ]; e = [ [ 123 ] ]; } ]
================================================
FILE: data/nix/tests/lang/eval-okay-fromTOML.nix
================================================
[
(builtins.fromTOML ''
# This is a TOML document.
title = "TOML Example"
[owner]
name = "Tom Preston-Werner"
#dob = 1979-05-27T07:32:00-08:00 # First class dates
[database]
server = "192.168.1.1"
ports = [ 8001, 8001, 8002 ]
connection_max = 5000
enabled = true
[servers]
# Indentation (tabs and/or spaces) is allowed but not required
[servers.alpha]
ip = "10.0.0.1"
dc = "eqdc10"
[servers.beta]
ip = "10.0.0.2"
dc = "eqdc10"
[clients]
data = [ ["gamma", "delta"], [1, 2] ]
# Line breaks are OK when inside arrays
hosts = [
"alpha",
"omega"
]
'')
(builtins.fromTOML ''
key = "value"
bare_key = "value"
bare-key = "value"
1234 = "value"
"127.0.0.1" = "value"
"character encoding" = "value"
"ʎǝʞ" = "value"
'key2' = "value"
'quoted "value"' = "value"
name = "Orange"
physical.color = "orange"
physical.shape = "round"
site."google.com" = true
# This is legal according to the spec, but cpptoml doesn't handle it.
#a.b.c = 1
#a.d = 2
str = "I'm a string. \"You can quote me\". Name\tJos\u00E9\nLocation\tSF."
int1 = +99
int2 = 42
int3 = 0
int4 = -17
int5 = 1_000
int6 = 5_349_221
int7 = 1_2_3_4_5
hex1 = 0xDEADBEEF
hex2 = 0xdeadbeef
hex3 = 0xdead_beef
oct1 = 0o01234567
oct2 = 0o755
bin1 = 0b11010110
flt1 = +1.0
flt2 = 3.1415
flt3 = -0.01
flt4 = 5e+22
flt5 = 1e6
flt6 = -2E-2
flt7 = 6.626e-34
flt8 = 9_224_617.445_991_228_313
bool1 = true
bool2 = false
# FIXME: not supported because Nix doesn't have a date/time type.
#odt1 = 1979-05-27T07:32:00Z
#odt2 = 1979-05-27T00:32:00-07:00
#odt3 = 1979-05-27T00:32:00.999999-07:00
#odt4 = 1979-05-27 07:32:00Z
#ldt1 = 1979-05-27T07:32:00
#ldt2 = 1979-05-27T00:32:00.999999
#ld1 = 1979-05-27
#lt1 = 07:32:00
#lt2 = 00:32:00.999999
arr1 = [ 1, 2, 3 ]
arr2 = [ "red", "yellow", "green" ]
arr3 = [ [ 1, 2 ], [3, 4, 5] ]
arr4 = [ "all", 'strings', """are the same""", ''''type'''']
arr5 = [ [ 1, 2 ], ["a", "b", "c"] ]
arr7 = [
1, 2, 3
]
arr8 = [
1,
2, # this is ok
]
[table-1]
key1 = "some string"
key2 = 123
[table-2]
key1 = "another string"
key2 = 456
[dog."tater.man"]
type.name = "pug"
[a.b.c]
[ d.e.f ]
[ g . h . i ]
[ j . "ʞ" . 'l' ]
[x.y.z.w]
name = { first = "Tom", last = "Preston-Werner" }
point = { x = 1, y = 2 }
animal = { type.name = "pug" }
[[products]]
name = "Hammer"
sku = 738594937
[[products]]
[[products]]
name = "Nail"
sku = 284758393
color = "gray"
[[fruit]]
name = "apple"
[fruit.physical]
color = "red"
shape = "round"
[[fruit.variety]]
name = "red delicious"
[[fruit.variety]]
name = "granny smith"
[[fruit]]
name = "banana"
[[fruit.variety]]
name = "plantain"
'')
(builtins.fromTOML ''
[[package]]
name = "aho-corasick"
version = "0.6.4"
source = "registry+https://github.com/rust-lang/crates.io-index"
dependencies = [
"memchr 2.0.1 (registry+https://github.com/rust-lang/crates.io-index)",
]
[[package]]
name = "ansi_term"
version = "0.9.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
[[package]]
name = "atty"
version = "0.2.10"
source = "registry+https://github.com/rust-lang/crates.io-index"
dependencies = [
"libc 0.2.42 (registry+https://github.com/rust-lang/crates.io-index)",
"termion 1.5.1 (registry+https://github.com/rust-lang/crates.io-index)",
"winapi 0.3.5 (registry+https://github.com/rust-lang/crates.io-index)",
]
[metadata]
"checksum aho-corasick 0.6.4 (registry+https://github.com/rust-lang/crates.io-index)" = "d6531d44de723825aa81398a6415283229725a00fa30713812ab9323faa82fc4"
"checksum ansi_term 0.11.0 (registry+https://github.com/rust-lang/crates.io-index)" = "ee49baf6cb617b853aa8d93bf420db2383fab46d314482ca2803b40d5fde979b"
"checksum ansi_term 0.9.0 (registry+https://github.com/rust-lang/crates.io-index)" = "23ac7c30002a5accbf7e8987d0632fa6de155b7c3d39d0067317a391e00a2ef6"
"checksum arrayvec 0.4.7 (registry+https://github.com/rust-lang/crates.io-index)" = "a1e964f9e24d588183fcb43503abda40d288c8657dfc27311516ce2f05675aef"
'')
(builtins.fromTOML ''
a = [[{ b = true }]]
c = [ [ { d = true } ] ]
e = [[123]]
'')
]
================================================
FILE: data/nix/tests/lang/eval-okay-fromjson-escapes.exp
================================================
"quote \" reverse solidus \\ solidus / backspace formfeed newline \n carriage return \r horizontal tab \t 1 char unicode encoded backspace 1 char unicode encoded e with accent é 2 char unicode encoded s with caron š 3 char unicode encoded rightwards arrow →"
================================================
FILE: data/nix/tests/lang/eval-okay-fromjson-escapes.nix
================================================
# This string contains all supported escapes in a JSON string, per json.org
# \b and \f are not supported by Nix
builtins.fromJSON ''"quote \" reverse solidus \\ solidus \/ backspace \b formfeed \f newline \n carriage return \r horizontal tab \t 1 char unicode encoded backspace \u0008 1 char unicode encoded e with accent \u00e9 2 char unicode encoded s with caron \u0161 3 char unicode encoded rightwards arrow \u2192"''
================================================
FILE: data/nix/tests/lang/eval-okay-fromjson.exp
================================================
true
================================================
FILE: data/nix/tests/lang/eval-okay-fromjson.nix
================================================
# RFC 7159, section 13.
builtins.fromJSON
''
{
"Image": {
"Width": 800,
"Height": 600,
"Title": "View from 15th Floor",
"Thumbnail": {
"Url": "http://www.example.com/image/481989943",
"Height": 125,
"Width": 100
},
"Animated" : false,
"IDs": [116, 943, 234, 38793, true ,false,null, -100],
"Latitude": 37.7668,
"Longitude": -122.3959
}
}
''
==
{ Image =
{ Width = 800;
Height = 600;
Title = "View from 15th Floor";
Thumbnail =
{ Url = http://www.example.com/image/481989943;
Height = 125;
Width = 100;
};
Animated = false;
IDs = [ 116 943 234 38793 true false null (0-100) ];
Latitude = 37.7668;
Longitude = -122.3959;
};
}
================================================
FILE: data/nix/tests/lang/eval-okay-functionargs.exp.xml
================================================
<?xml version='1.0' encoding='utf-8'?>
<expr>
<list>
<string value="stdenv" />
<string value="fetchurl" />
<string value="aterm-stdenv" />
<string value="aterm-stdenv2" />
<string value="libX11" />
<string value="libXv" />
<string value="mplayer-stdenv2.libXv-libX11" />
<string value="mplayer-stdenv2.libXv-libX11_2" />
<string value="nix-stdenv-aterm-stdenv" />
<string value="nix-stdenv2-aterm2-stdenv2" />
</list>
</expr>
================================================
FILE: data/nix/tests/lang/eval-okay-functionargs.nix
================================================
let
stdenvFun = { }: { name = "stdenv"; };
stdenv2Fun = { }: { name = "stdenv2"; };
fetchurlFun = { stdenv }: assert stdenv.name == "stdenv"; { name = "fetchurl"; };
atermFun = { stdenv, fetchurl }: { name = "aterm-${stdenv.name}"; };
aterm2Fun = { stdenv, fetchurl }: { name = "aterm2-${stdenv.name}"; };
nixFun = { stdenv, fetchurl, aterm }: { name = "nix-${stdenv.name}-${aterm.name}"; };
mplayerFun =
{ stdenv, fetchurl, enableX11 ? false, xorg ? null, enableFoo ? true, foo ? null }:
assert stdenv.name == "stdenv2";
assert enableX11 -> xorg.libXv.name == "libXv";
assert enableFoo -> foo != null;
{ name = "mplayer-${stdenv.name}.${xorg.libXv.name}-${xorg.libX11.name}"; };
makeOverridable = f: origArgs: f origArgs //
{ override = newArgs:
makeOverridable f (origArgs // (if builtins.isFunction newArgs then newArgs origArgs else newArgs));
};
callP
gitextract_q_z2xg1p/
├── .fourmolu.yaml
├── .github/
│ ├── dependabot.yml
│ └── workflows/
│ ├── Cabal-Linux.yml
│ ├── HLint.yml
│ ├── On-Release-Cabal-Linux.yml
│ ├── On-Release-Nixpkgs-integration.yml
│ └── Quality.yml
├── .gitignore
├── .gitmodules
├── .hlint.yaml
├── CLAUDE.md
├── CODEOWNERS
├── ChangeLog.md
├── LICENSE.md
├── License
├── Makefile
├── ReadMe.md
├── benchmarks/
│ ├── Main.hs
│ └── ParserBench.hs
├── brittany.yaml
├── build.sh
├── cabal.project
├── data/
│ ├── let-comments-multiline.nix
│ ├── let-comments.nix
│ ├── let.nix
│ ├── nix/
│ │ ├── README.md
│ │ └── tests/
│ │ └── lang/
│ │ ├── binary-data
│ │ ├── data
│ │ ├── dir1/
│ │ │ └── a.nix
│ │ ├── dir2/
│ │ │ ├── a.nix
│ │ │ └── b.nix
│ │ ├── dir3/
│ │ │ ├── a.nix
│ │ │ ├── b.nix
│ │ │ └── c.nix
│ │ ├── dir4/
│ │ │ ├── a.nix
│ │ │ └── c.nix
│ │ ├── eval-fail-abort.nix
│ │ ├── eval-fail-assert.nix
│ │ ├── eval-fail-bad-antiquote-1.nix
│ │ ├── eval-fail-bad-antiquote-2.nix
│ │ ├── eval-fail-bad-antiquote-3.nix
│ │ ├── eval-fail-blackhole.nix
│ │ ├── eval-fail-deepseq.nix
│ │ ├── eval-fail-hashfile-missing.nix
│ │ ├── eval-fail-missing-arg.nix
│ │ ├── eval-fail-nonexist-path.nix
│ │ ├── eval-fail-path-slash.nix
│ │ ├── eval-fail-remove.nix
│ │ ├── eval-fail-scope-5.nix
│ │ ├── eval-fail-seq.nix
│ │ ├── eval-fail-substring.nix
│ │ ├── eval-fail-to-path.nix
│ │ ├── eval-fail-undeclared-arg.nix
│ │ ├── eval-okay-any-all.exp
│ │ ├── eval-okay-any-all.nix
│ │ ├── eval-okay-arithmetic.exp
│ │ ├── eval-okay-arithmetic.nix
│ │ ├── eval-okay-attrnames.exp
│ │ ├── eval-okay-attrnames.nix
│ │ ├── eval-okay-attrs.exp
│ │ ├── eval-okay-attrs.nix
│ │ ├── eval-okay-attrs2.exp
│ │ ├── eval-okay-attrs2.nix
│ │ ├── eval-okay-attrs3.exp
│ │ ├── eval-okay-attrs3.nix
│ │ ├── eval-okay-attrs4.exp
│ │ ├── eval-okay-attrs4.nix
│ │ ├── eval-okay-attrs5.exp
│ │ ├── eval-okay-attrs5.nix
│ │ ├── eval-okay-attrs6.exp
│ │ ├── eval-okay-attrs6.nix
│ │ ├── eval-okay-autoargs.exp
│ │ ├── eval-okay-autoargs.flags
│ │ ├── eval-okay-autoargs.nix
│ │ ├── eval-okay-backslash-newline-1.exp
│ │ ├── eval-okay-backslash-newline-1.nix
│ │ ├── eval-okay-backslash-newline-2.exp
│ │ ├── eval-okay-backslash-newline-2.nix
│ │ ├── eval-okay-builtins-add.exp
│ │ ├── eval-okay-builtins-add.nix
│ │ ├── eval-okay-builtins.exp
│ │ ├── eval-okay-builtins.nix
│ │ ├── eval-okay-callable-attrs.exp
│ │ ├── eval-okay-callable-attrs.nix
│ │ ├── eval-okay-catattrs.exp
│ │ ├── eval-okay-catattrs.nix
│ │ ├── eval-okay-closure.exp.xml
│ │ ├── eval-okay-closure.nix
│ │ ├── eval-okay-comments.exp
│ │ ├── eval-okay-comments.nix
│ │ ├── eval-okay-concat.exp
│ │ ├── eval-okay-concat.nix
│ │ ├── eval-okay-concatmap.exp
│ │ ├── eval-okay-concatmap.nix
│ │ ├── eval-okay-concatstringssep.exp
│ │ ├── eval-okay-concatstringssep.nix
│ │ ├── eval-okay-context-introspection.exp
│ │ ├── eval-okay-context-introspection.nix
│ │ ├── eval-okay-context.exp
│ │ ├── eval-okay-context.nix
│ │ ├── eval-okay-curpos.exp
│ │ ├── eval-okay-curpos.nix
│ │ ├── eval-okay-deepseq.exp
│ │ ├── eval-okay-deepseq.nix
│ │ ├── eval-okay-delayed-with-inherit.exp
│ │ ├── eval-okay-delayed-with-inherit.nix
│ │ ├── eval-okay-delayed-with.exp
│ │ ├── eval-okay-delayed-with.nix
│ │ ├── eval-okay-dynamic-attrs-2.exp
│ │ ├── eval-okay-dynamic-attrs-2.nix
│ │ ├── eval-okay-dynamic-attrs-bare.exp
│ │ ├── eval-okay-dynamic-attrs-bare.nix
│ │ ├── eval-okay-dynamic-attrs.exp
│ │ ├── eval-okay-dynamic-attrs.nix
│ │ ├── eval-okay-elem.exp
│ │ ├── eval-okay-elem.nix
│ │ ├── eval-okay-empty-args.exp
│ │ ├── eval-okay-empty-args.nix
│ │ ├── eval-okay-eq-derivations.exp
│ │ ├── eval-okay-eq-derivations.nix
│ │ ├── eval-okay-eq.exp.disabled
│ │ ├── eval-okay-eq.nix
│ │ ├── eval-okay-filter.exp
│ │ ├── eval-okay-filter.nix
│ │ ├── eval-okay-flatten.exp
│ │ ├── eval-okay-flatten.nix
│ │ ├── eval-okay-float.exp
│ │ ├── eval-okay-float.nix
│ │ ├── eval-okay-floor-ceil.exp
│ │ ├── eval-okay-floor-ceil.nix
│ │ ├── eval-okay-foldlStrict.exp
│ │ ├── eval-okay-foldlStrict.nix
│ │ ├── eval-okay-fromTOML.exp
│ │ ├── eval-okay-fromTOML.nix
│ │ ├── eval-okay-fromjson-escapes.exp
│ │ ├── eval-okay-fromjson-escapes.nix
│ │ ├── eval-okay-fromjson.exp
│ │ ├── eval-okay-fromjson.nix
│ │ ├── eval-okay-functionargs.exp.xml
│ │ ├── eval-okay-functionargs.nix
│ │ ├── eval-okay-getattrpos-functionargs.exp
│ │ ├── eval-okay-getattrpos-functionargs.nix
│ │ ├── eval-okay-getattrpos-undefined.exp
│ │ ├── eval-okay-getattrpos-undefined.nix
│ │ ├── eval-okay-getattrpos.exp
│ │ ├── eval-okay-getattrpos.nix
│ │ ├── eval-okay-getenv.exp
│ │ ├── eval-okay-getenv.nix
│ │ ├── eval-okay-hash.exp
│ │ ├── eval-okay-hashfile.exp
│ │ ├── eval-okay-hashfile.nix
│ │ ├── eval-okay-hashstring.exp
│ │ ├── eval-okay-hashstring.nix
│ │ ├── eval-okay-if.exp
│ │ ├── eval-okay-if.nix
│ │ ├── eval-okay-import.exp
│ │ ├── eval-okay-import.nix
│ │ ├── eval-okay-ind-string.exp
│ │ ├── eval-okay-ind-string.nix
│ │ ├── eval-okay-let.exp
│ │ ├── eval-okay-let.nix
│ │ ├── eval-okay-list.exp
│ │ ├── eval-okay-list.nix
│ │ ├── eval-okay-listtoattrs.exp
│ │ ├── eval-okay-listtoattrs.nix
│ │ ├── eval-okay-logic.exp
│ │ ├── eval-okay-logic.nix
│ │ ├── eval-okay-map.exp
│ │ ├── eval-okay-map.nix
│ │ ├── eval-okay-mapattrs.exp
│ │ ├── eval-okay-mapattrs.nix
│ │ ├── eval-okay-nested-with.exp
│ │ ├── eval-okay-nested-with.nix
│ │ ├── eval-okay-new-let.exp
│ │ ├── eval-okay-new-let.nix
│ │ ├── eval-okay-null-dynamic-attrs.exp
│ │ ├── eval-okay-null-dynamic-attrs.nix
│ │ ├── eval-okay-overrides.exp
│ │ ├── eval-okay-overrides.nix
│ │ ├── eval-okay-partition.exp
│ │ ├── eval-okay-partition.nix
│ │ ├── eval-okay-path-antiquotation.nix
│ │ ├── eval-okay-path.nix
│ │ ├── eval-okay-pathexists.exp
│ │ ├── eval-okay-pathexists.nix
│ │ ├── eval-okay-patterns.exp
│ │ ├── eval-okay-patterns.nix
│ │ ├── eval-okay-readDir.exp
│ │ ├── eval-okay-readDir.nix
│ │ ├── eval-okay-readfile.exp
│ │ ├── eval-okay-readfile.nix
│ │ ├── eval-okay-redefine-builtin.exp
│ │ ├── eval-okay-redefine-builtin.nix
│ │ ├── eval-okay-regex-match.exp
│ │ ├── eval-okay-regex-match.nix
│ │ ├── eval-okay-regex-split.exp
│ │ ├── eval-okay-regex-split.nix
│ │ ├── eval-okay-remove.exp
│ │ ├── eval-okay-remove.nix
│ │ ├── eval-okay-replacestrings.exp
│ │ ├── eval-okay-replacestrings.nix
│ │ ├── eval-okay-scope-1.exp
│ │ ├── eval-okay-scope-1.nix
│ │ ├── eval-okay-scope-2.exp
│ │ ├── eval-okay-scope-2.nix
│ │ ├── eval-okay-scope-3.exp
│ │ ├── eval-okay-scope-3.nix
│ │ ├── eval-okay-scope-4.exp
│ │ ├── eval-okay-scope-4.nix
│ │ ├── eval-okay-scope-6.exp
│ │ ├── eval-okay-scope-6.nix
│ │ ├── eval-okay-scope-7.exp
│ │ ├── eval-okay-scope-7.nix
│ │ ├── eval-okay-search-path.exp
│ │ ├── eval-okay-search-path.flags
│ │ ├── eval-okay-search-path.nix
│ │ ├── eval-okay-seq.exp
│ │ ├── eval-okay-seq.nix
│ │ ├── eval-okay-sort.exp
│ │ ├── eval-okay-sort.nix
│ │ ├── eval-okay-splitversion.exp
│ │ ├── eval-okay-splitversion.nix
│ │ ├── eval-okay-string.exp
│ │ ├── eval-okay-string.nix
│ │ ├── eval-okay-strings-as-attrs-names.exp
│ │ ├── eval-okay-strings-as-attrs-names.nix
│ │ ├── eval-okay-substring.exp
│ │ ├── eval-okay-substring.nix
│ │ ├── eval-okay-tail-call-1.exp-disabled
│ │ ├── eval-okay-tail-call-1.nix
│ │ ├── eval-okay-tojson.exp
│ │ ├── eval-okay-tojson.nix
│ │ ├── eval-okay-toxml.exp
│ │ ├── eval-okay-toxml.nix
│ │ ├── eval-okay-toxml2.exp
│ │ ├── eval-okay-toxml2.nix
│ │ ├── eval-okay-tryeval.exp
│ │ ├── eval-okay-tryeval.nix
│ │ ├── eval-okay-types.exp
│ │ ├── eval-okay-types.nix
│ │ ├── eval-okay-versions.exp
│ │ ├── eval-okay-versions.nix
│ │ ├── eval-okay-with.exp
│ │ ├── eval-okay-with.nix
│ │ ├── eval-okay-xml.exp.xml
│ │ ├── eval-okay-xml.nix
│ │ ├── imported.nix
│ │ ├── imported2.nix
│ │ ├── lib.nix
│ │ ├── parse-fail-dup-attrs-1.nix
│ │ ├── parse-fail-dup-attrs-2.nix
│ │ ├── parse-fail-dup-attrs-3.nix
│ │ ├── parse-fail-dup-attrs-4.nix
│ │ ├── parse-fail-dup-attrs-7.nix
│ │ ├── parse-fail-dup-formals.nix
│ │ ├── parse-fail-mixed-nested-attrs1.nix
│ │ ├── parse-fail-mixed-nested-attrs2.nix
│ │ ├── parse-fail-patterns-1.nix
│ │ ├── parse-fail-regression-20060610.nix
│ │ ├── parse-fail-uft8.nix
│ │ ├── parse-fail-undef-var-2.nix
│ │ ├── parse-fail-undef-var.nix
│ │ ├── parse-okay-1.nix
│ │ ├── parse-okay-crlf.nix
│ │ ├── parse-okay-dup-attrs-5.nix
│ │ ├── parse-okay-dup-attrs-6.nix
│ │ ├── parse-okay-mixed-nested-attrs-1.nix
│ │ ├── parse-okay-mixed-nested-attrs-2.nix
│ │ ├── parse-okay-mixed-nested-attrs-3.nix
│ │ ├── parse-okay-regression-20041027.nix
│ │ ├── parse-okay-regression-751.nix
│ │ ├── parse-okay-subversion.nix
│ │ ├── parse-okay-url.nix
│ │ └── readDir/
│ │ ├── bar
│ │ └── foo/
│ │ └── git-hates-directories
│ ├── nixpkgs-all-packages-pretty.nix
│ ├── nixpkgs-all-packages.nix
│ ├── simple-pretty.nix
│ └── simple.nix
├── default.nix
├── doc/
│ ├── grammar.y
│ └── lexer.l
├── flake.nix
├── hnix.cabal
├── hydra.json
├── jobsets.nix
├── lefthook.yml
├── main/
│ ├── Main.hs
│ └── Repl.hs
├── release.nix
├── shell.nix
├── src/
│ ├── Nix/
│ │ ├── Atoms.hs
│ │ ├── Builtins.hs
│ │ ├── Cache.hs
│ │ ├── Cited/
│ │ │ └── Basic.hs
│ │ ├── Cited.hs
│ │ ├── Context.hs
│ │ ├── Convert.hs
│ │ ├── Effects/
│ │ │ ├── Basic.hs
│ │ │ └── Derivation.hs
│ │ ├── Effects.hs
│ │ ├── Eval.hs
│ │ ├── Exec.hs
│ │ ├── Expr/
│ │ │ ├── Shorthands.hs
│ │ │ ├── Strings.hs
│ │ │ ├── Types/
│ │ │ │ └── Annotated.hs
│ │ │ └── Types.hs
│ │ ├── Expr.hs
│ │ ├── Frames.hs
│ │ ├── Fresh/
│ │ │ └── Basic.hs
│ │ ├── Fresh.hs
│ │ ├── Json.hs
│ │ ├── Lint.hs
│ │ ├── Normal.hs
│ │ ├── Options/
│ │ │ └── Parser.hs
│ │ ├── Options.hs
│ │ ├── Parser.hs
│ │ ├── Prelude.hs
│ │ ├── Pretty.hs
│ │ ├── Reduce.hs
│ │ ├── Render/
│ │ │ └── Frame.hs
│ │ ├── Render.hs
│ │ ├── Scope.hs
│ │ ├── Standard.hs
│ │ ├── String/
│ │ │ └── Coerce.hs
│ │ ├── String.hs
│ │ ├── TH.hs
│ │ ├── Thunk/
│ │ │ └── Basic.hs
│ │ ├── Thunk.hs
│ │ ├── Type/
│ │ │ ├── Assumption.hs
│ │ │ ├── Env.hs
│ │ │ ├── Infer.hs
│ │ │ ├── LICENSE
│ │ │ └── Type.hs
│ │ ├── Unused.hs
│ │ ├── Utils/
│ │ │ └── Fix1.hs
│ │ ├── Utils.hs
│ │ ├── Value/
│ │ │ ├── Equal.hs
│ │ │ └── Monad.hs
│ │ ├── Value.hs
│ │ ├── Var.hs
│ │ └── XML.hs
│ └── Nix.hs
└── tests/
├── EvalTests.hs
├── Main.hs
├── NixLanguageTests.hs
├── ParserTests.hs
├── PrettyParseTests.hs
├── PrettyTests.hs
├── ReduceExprTests.hs
├── TestCommon.hs
├── eval-compare/
│ ├── builtins.appendContext.nix
│ ├── builtins.eq-bottom-00.nix
│ ├── builtins.fetchurl-01.nix
│ ├── builtins.fromJSON-01.nix
│ ├── builtins.getContext.nix
│ ├── builtins.lessThan-01.nix
│ ├── builtins.mapAttrs-01.nix
│ ├── builtins.pathExists.nix
│ ├── builtins.replaceStrings-01.nix
│ ├── builtins.split-01.nix
│ ├── builtins.split-02.nix
│ ├── builtins.split-03.nix
│ ├── builtins.split-04.nix
│ ├── builtins.string.store.nix
│ ├── builtins.toJSON.nix
│ ├── current-system.nix
│ ├── ellipsis.nix
│ ├── ind-string-01.nix
│ ├── ind-string-02.nix
│ ├── ind-string-03.nix
│ ├── ind-string-04.nix
│ ├── ind-string-05.nix
│ ├── ind-string-06.nix
│ ├── ind-string-07.nix
│ ├── ind-string-08.nix
│ ├── ind-string-09.nix
│ ├── ind-string-10.nix
│ ├── ind-string-11.nix
│ ├── ind-string-12.nix
│ ├── ind-string-13.nix
│ ├── ind-string-14.nix
│ ├── ind-string-15.nix
│ ├── ind-string-16.nix
│ ├── ind-string-17.nix
│ ├── ind-string-18.nix
│ ├── ind-string-19.nix
│ ├── paths-01.nix
│ └── placeholder.nix
└── files/
├── attrs.nix
├── callLibs.nix
├── eighty.nix
├── file.nix
├── file2.nix
├── findFile.nix
├── force.nix
├── goodbye.nix
├── hello.nix
├── hello2.nix
├── if-then.nix
├── lint.nix
├── loop.nix
├── test.nix
└── with.nix
Condensed preview — 404 files, each showing path, character count, and a content snippet. Download the .json file or copy for the full structured content (1,728K chars).
[
{
"path": ".fourmolu.yaml",
"chars": 316,
"preview": "indentation: 2\ncolumn-limit: none\nfunction-arrows: trailing\ncomma-style: leading\nimport-export-style: diff-friendly\ninde"
},
{
"path": ".github/dependabot.yml",
"chars": 163,
"preview": "version: 2\nupdates:\n\n # Maintain dependencies for GitHub Actions\n - package-ecosystem: \"github-actions\"\n directory:"
},
{
"path": ".github/workflows/Cabal-Linux.yml",
"chars": 1888,
"preview": "name: \"Hackage, Cabal, Linux\"\n\non:\n pull_request:\n push:\n branches:\n - master\n schedule:\n - cron: \"45 02 *"
},
{
"path": ".github/workflows/HLint.yml",
"chars": 413,
"preview": "name: \"Checking code\"\n\non:\n pull_request:\n push:\n branches:\n - master\n\njobs:\n build10:\n name: \"HLint\"\n "
},
{
"path": ".github/workflows/On-Release-Cabal-Linux.yml",
"chars": 1688,
"preview": "name: \"Release testing, Hackage, Cabal, Linux\"\n\non:\n release:\n # created: a draft is saved, or a release or pre-rele"
},
{
"path": ".github/workflows/On-Release-Nixpkgs-integration.yml",
"chars": 753,
"preview": "name: \"Direct import & build inside Nixpkgs\"\n\non:\n release:\n # created: a draft is saved, or a release or pre-releas"
},
{
"path": ".github/workflows/Quality.yml",
"chars": 3893,
"preview": "name: \"Quality checks\"\n\non:\n pull_request:\n push:\n branches:\n - master\n\njobs:\n formatting:\n name: \"Formatt"
},
{
"path": ".gitignore",
"chars": 145,
"preview": "**/#*\n**/*~\n**/.#*\n/.history\n/Setup\n/dist/\n/nix-test-eval*\n/nix/\nTAGS\ncabal.project.local\nctags\ndist-newstyle\nresult*\n.g"
},
{
"path": ".gitmodules",
"chars": 0,
"preview": ""
},
{
"path": ".hlint.yaml",
"chars": 81322,
"preview": "- group: {name: generalise, enabled: true}\n- group: {name: future, enabled: true}\n- group: {name: attoparsec, enabled: t"
},
{
"path": "CLAUDE.md",
"chars": 9002,
"preview": "# HNix Codebase Guide for Claude Code\n\nThis guide provides essential context for working with HNix - a Haskell implement"
},
{
"path": "CODEOWNERS",
"chars": 11,
"preview": "/ @jwiegley"
},
{
"path": "ChangeLog.md",
"chars": 29908,
"preview": "\n# ChangeLog\n\n## [(diff)](https://github.com/haskell-nix/hnix/compare/0.16.0...0.17.0#files_bucket) 0.17.0\n\n* Additional"
},
{
"path": "LICENSE.md",
"chars": 1492,
"preview": "Copyright (c) 2014-2025, John Wiegley. All rights reserved.\n\nRedistribution and use in source and binary forms, with or"
},
{
"path": "License",
"chars": 1483,
"preview": "Copyright (c) 2014, John Wiegley All rights reserved.\n\nRedistribution and use in source and binary forms, with or withou"
},
{
"path": "Makefile",
"chars": 68,
"preview": "all: default.nix\n\ndefault.nix: hnix.cabal\n\tcabal2nix --shell . > $@\n"
},
{
"path": "ReadMe.md",
"chars": 8815,
"preview": "[](https://gitter.im/haskell-nix/Lobby)\n[![Hac"
},
{
"path": "benchmarks/Main.hs",
"chars": 153,
"preview": "module Main where\n\nimport Criterion.Main\nimport Nix.Prelude\n\nimport qualified ParserBench\n\nmain :: IO ()\nmain = defaultM"
},
{
"path": "benchmarks/ParserBench.hs",
"chars": 561,
"preview": "module ParserBench (benchmarks) where\n\nimport Nix.Parser\nimport Nix.Prelude\n\nimport Criterion\n\nbenchFile :: Path -> Benc"
},
{
"path": "brittany.yaml",
"chars": 1364,
"preview": "conf_debug:\n dconf_roundtrip_exactprint_only: false\n dconf_dump_bridoc_simpl_par: false\n dconf_dump_ast_unknown: fals"
},
{
"path": "build.sh",
"chars": 5545,
"preview": "#!/usr/bin/env bash\n\n# NOTE: Script to easy import nix-build settings from env, useful for tooling env replication and t"
},
{
"path": "cabal.project",
"chars": 25,
"preview": "packages:\n ./hnix.cabal\n"
},
{
"path": "data/let-comments-multiline.nix",
"chars": 232,
"preview": "let\n b.a = 3; /*\n this is a multiline comment\n /* we can also nest these comments\n */ /*\n */\n b.c = { e = {};"
},
{
"path": "data/let-comments.nix",
"chars": 218,
"preview": "let\n b.a = 3;\n # this is a oneline comment\n # we can also nest these comments\n # #\n #\n #\n b.c = { e = {}; };"
},
{
"path": "data/let.nix",
"chars": 55,
"preview": "let\n b.a = 3;\n b.c = { e = {}; };\n b.c.e.f = 4;\nin b"
},
{
"path": "data/nix/README.md",
"chars": 197,
"preview": "Extracted from https://github.com/NixOS/nix (GPLv2)\ncommit 6c2af1f201a925c2aa632737765685c72b642847\nDate: Mon Nov 8 14"
},
{
"path": "data/nix/tests/lang/data",
"chars": 4,
"preview": "foo\n"
},
{
"path": "data/nix/tests/lang/dir1/a.nix",
"chars": 4,
"preview": "\"a\"\n"
},
{
"path": "data/nix/tests/lang/dir2/a.nix",
"chars": 4,
"preview": "\"X\"\n"
},
{
"path": "data/nix/tests/lang/dir2/b.nix",
"chars": 4,
"preview": "\"b\"\n"
},
{
"path": "data/nix/tests/lang/dir3/a.nix",
"chars": 4,
"preview": "\"X\"\n"
},
{
"path": "data/nix/tests/lang/dir3/b.nix",
"chars": 4,
"preview": "\"X\"\n"
},
{
"path": "data/nix/tests/lang/dir3/c.nix",
"chars": 4,
"preview": "\"c\"\n"
},
{
"path": "data/nix/tests/lang/dir4/a.nix",
"chars": 4,
"preview": "\"X\"\n"
},
{
"path": "data/nix/tests/lang/dir4/c.nix",
"chars": 4,
"preview": "\"X\"\n"
},
{
"path": "data/nix/tests/lang/eval-fail-abort.nix",
"chars": 45,
"preview": "if true then abort \"this should fail\" else 1\n"
},
{
"path": "data/nix/tests/lang/eval-fail-assert.nix",
"chars": 59,
"preview": "let {\n x = arg: assert arg == \"y\"; 123;\n\n body = x \"x\";\n}"
},
{
"path": "data/nix/tests/lang/eval-fail-bad-antiquote-1.nix",
"chars": 10,
"preview": "\"${x: x}\"\n"
},
{
"path": "data/nix/tests/lang/eval-fail-bad-antiquote-2.nix",
"chars": 13,
"preview": "\"${./fnord}\"\n"
},
{
"path": "data/nix/tests/lang/eval-fail-bad-antiquote-3.nix",
"chars": 12,
"preview": "''${x: x}''\n"
},
{
"path": "data/nix/tests/lang/eval-fail-blackhole.nix",
"chars": 38,
"preview": "let {\n body = x;\n x = y;\n y = x;\n}\n"
},
{
"path": "data/nix/tests/lang/eval-fail-deepseq.nix",
"chars": 42,
"preview": "builtins.deepSeq { x = abort \"foo\"; } 456\n"
},
{
"path": "data/nix/tests/lang/eval-fail-hashfile-missing.nix",
"chars": 215,
"preview": "let\n paths = [ ./this-file-is-definitely-not-there-7392097 \"/and/neither/is/this/37293620\" ];\nin\n toString (builtins.c"
},
{
"path": "data/nix/tests/lang/eval-fail-missing-arg.nix",
"chars": 47,
"preview": "({x, y, z}: x + y + z) {x = \"foo\"; z = \"bar\";}\n"
},
{
"path": "data/nix/tests/lang/eval-fail-nonexist-path.nix",
"chars": 180,
"preview": "# This must fail to evaluate, since ./fnord doesn't exist. If it did\n# exist, it would produce \"/nix/store/<hash>-fnord"
},
{
"path": "data/nix/tests/lang/eval-fail-path-slash.nix",
"chars": 263,
"preview": "# Trailing slashes in paths are not allowed.\n# This restriction could be lifted sometime,\n# for example if we make '/' a"
},
{
"path": "data/nix/tests/lang/eval-fail-remove.nix",
"chars": 77,
"preview": "let {\n attrs = {x = 123; y = 456;};\n\n body = (removeAttrs attrs [\"x\"]).x;\n}"
},
{
"path": "data/nix/tests/lang/eval-fail-scope-5.nix",
"chars": 78,
"preview": "let {\n\n x = \"a\";\n y = \"b\";\n\n f = {x ? y, y ? x}: x + y;\n\n body = f {};\n\n}\n"
},
{
"path": "data/nix/tests/lang/eval-fail-seq.nix",
"chars": 29,
"preview": "builtins.seq (abort \"foo\") 2\n"
},
{
"path": "data/nix/tests/lang/eval-fail-substring.nix",
"chars": 44,
"preview": "builtins.substring (builtins.sub 0 1) 1 \"x\"\n"
},
{
"path": "data/nix/tests/lang/eval-fail-to-path.nix",
"chars": 26,
"preview": "builtins.toPath \"foo/bar\"\n"
},
{
"path": "data/nix/tests/lang/eval-fail-undeclared-arg.nix",
"chars": 51,
"preview": "({x, z}: x + z) {x = \"foo\"; y = \"bla\"; z = \"bar\";}\n"
},
{
"path": "data/nix/tests/lang/eval-okay-any-all.exp",
"chars": 47,
"preview": "[ false false true true true true false true ]\n"
},
{
"path": "data/nix/tests/lang/eval-okay-any-all.nix",
"chars": 232,
"preview": "with builtins;\n\n[ (any (x: x == 1) [])\n (any (x: x == 1) [2 3 4])\n (any (x: x == 1) [1 2 3 4])\n (any (x: x == 1) [4 3"
},
{
"path": "data/nix/tests/lang/eval-okay-arithmetic.exp",
"chars": 5,
"preview": "2216\n"
},
{
"path": "data/nix/tests/lang/eval-okay-arithmetic.nix",
"chars": 1359,
"preview": "with import ./lib.nix;\n\nlet {\n\n /* Supposedly tail recursive version:\n\n range_ = accum: first: last:\n if first == l"
},
{
"path": "data/nix/tests/lang/eval-okay-attrnames.exp",
"chars": 15,
"preview": "\"newxfoonewxy\"\n"
},
{
"path": "data/nix/tests/lang/eval-okay-attrnames.nix",
"chars": 261,
"preview": "with import ./lib.nix;\n\nlet\n\n attrs = {y = \"y\"; x = \"x\"; foo = \"foo\";} // rec {x = \"newx\"; bar = x;};\n\n names = builti"
},
{
"path": "data/nix/tests/lang/eval-okay-attrs.exp",
"chars": 4,
"preview": "987\n"
},
{
"path": "data/nix/tests/lang/eval-okay-attrs.nix",
"chars": 126,
"preview": "let {\n as = { x = 123; y = 456; } // { z = 789; } // { z = 987; };\n\n body = if as ? a then as.a else assert as ? z; as"
},
{
"path": "data/nix/tests/lang/eval-okay-attrs2.exp",
"chars": 4,
"preview": "987\n"
},
{
"path": "data/nix/tests/lang/eval-okay-attrs2.nix",
"chars": 231,
"preview": "let {\n as = { x = 123; y = 456; } // { z = 789; } // { z = 987; };\n\n A = \"a\";\n Z = \"z\";\n\n body = if builtins.hasAttr"
},
{
"path": "data/nix/tests/lang/eval-okay-attrs3.exp",
"chars": 21,
"preview": "\"foo 22 80 itchyxac\"\n"
},
{
"path": "data/nix/tests/lang/eval-okay-attrs3.nix",
"chars": 566,
"preview": "let\n\n config = \n {\n services.sshd.enable = true;\n services.sshd.port = 22;\n services.httpd.port = 80;"
},
{
"path": "data/nix/tests/lang/eval-okay-attrs4.exp",
"chars": 49,
"preview": "[ true false true false false true false false ]\n"
},
{
"path": "data/nix/tests/lang/eval-okay-attrs4.nix",
"chars": 159,
"preview": "let\n\n as = { x.y.z = 123; a.b.c = 456; };\n\n bs = null;\n\nin [ (as ? x) (as ? y) (as ? x.y.z) (as ? x.y.z.a) (as ? x.y.a"
},
{
"path": "data/nix/tests/lang/eval-okay-attrs5.exp",
"chars": 49,
"preview": "[ 123 \"foo\" 456 456 \"foo\" \"xyzzy\" \"xyzzy\" true ]\n"
},
{
"path": "data/nix/tests/lang/eval-okay-attrs5.nix",
"chars": 407,
"preview": "with import ./lib.nix;\n\nlet\n\n as = { x.y.z = 123; a.b.c = 456; };\n\n bs = { f-o-o.bar = \"foo\"; };\n\n or = x: y: x || y;"
},
{
"path": "data/nix/tests/lang/eval-okay-attrs6.exp",
"chars": 62,
"preview": "{ __overrides = { bar = \"qux\"; }; bar = \"qux\"; foo = \"bar\"; }\n"
},
{
"path": "data/nix/tests/lang/eval-okay-attrs6.nix",
"chars": 65,
"preview": "rec {\n \"${\"foo\"}\" = \"bar\";\n __overrides = { bar = \"qux\"; };\n}\n"
},
{
"path": "data/nix/tests/lang/eval-okay-autoargs.exp",
"chars": 21,
"preview": "\"xyzzy!xyzzy!foobar\"\n"
},
{
"path": "data/nix/tests/lang/eval-okay-autoargs.flags",
"chars": 63,
"preview": "--arg lib import(lang/lib.nix) --argstr xyzzy xyzzy! -A result\n"
},
{
"path": "data/nix/tests/lang/eval-okay-autoargs.nix",
"chars": 217,
"preview": "let\n\n foobar = \"foobar\";\n\nin\n\n{ xyzzy2 ? xyzzy # mutually recursive args\n, xyzzy ? \"blaat\" # will be overridden by --ar"
},
{
"path": "data/nix/tests/lang/eval-okay-backslash-newline-1.exp",
"chars": 7,
"preview": "\"a\\nb\"\n"
},
{
"path": "data/nix/tests/lang/eval-okay-backslash-newline-1.nix",
"chars": 7,
"preview": "\"a\\\nb\"\n"
},
{
"path": "data/nix/tests/lang/eval-okay-backslash-newline-2.exp",
"chars": 7,
"preview": "\"a\\nb\"\n"
},
{
"path": "data/nix/tests/lang/eval-okay-backslash-newline-2.nix",
"chars": 11,
"preview": "''a''\\\nb''\n"
},
{
"path": "data/nix/tests/lang/eval-okay-builtins-add.exp",
"chars": 29,
"preview": "[ 5 4 \"int\" \"tt\" \"float\" 4 ]\n"
},
{
"path": "data/nix/tests/lang/eval-okay-builtins-add.nix",
"chars": 152,
"preview": "[\n(builtins.add 2 3)\n(builtins.add 2 2)\n(builtins.typeOf (builtins.add 2 2))\n(\"t\" + \"t\")\n(builtins.typeOf (builtins.add"
},
{
"path": "data/nix/tests/lang/eval-okay-builtins.exp",
"chars": 5,
"preview": "/foo\n"
},
{
"path": "data/nix/tests/lang/eval-okay-builtins.nix",
"chars": 225,
"preview": "assert builtins ? currentSystem;\nassert !builtins ? __currentSystem;\n\nlet {\n\n x = if builtins ? dirOf then builtins.dir"
},
{
"path": "data/nix/tests/lang/eval-okay-callable-attrs.exp",
"chars": 5,
"preview": "true\n"
},
{
"path": "data/nix/tests/lang/eval-okay-callable-attrs.nix",
"chars": 79,
"preview": "({ __functor = self: x: self.foo && x; foo = false; } // { foo = true; }) true\n"
},
{
"path": "data/nix/tests/lang/eval-okay-catattrs.exp",
"chars": 8,
"preview": "[ 1 2 ]\n"
},
{
"path": "data/nix/tests/lang/eval-okay-catattrs.nix",
"chars": 59,
"preview": "builtins.catAttrs \"a\" [ { a = 1; } { b = 0; } { a = 2; } ]\n"
},
{
"path": "data/nix/tests/lang/eval-okay-closure.exp.xml",
"chars": 6656,
"preview": "<?xml version='1.0' encoding='utf-8'?>\n<expr>\n <list>\n <attrs>\n <attr name=\"foo\">\n <bool value=\"true\" />"
},
{
"path": "data/nix/tests/lang/eval-okay-closure.nix",
"chars": 335,
"preview": "let\n\n closure = builtins.genericClosure {\n startSet = [{key = 80;}];\n operator = {key, foo ? false}:\n if bui"
},
{
"path": "data/nix/tests/lang/eval-okay-comments.exp",
"chars": 29,
"preview": "\"abcdefghijklmnopqrstuvwxyz\"\n"
},
{
"path": "data/nix/tests/lang/eval-okay-comments.nix",
"chars": 1080,
"preview": "# A simple comment\n\"a\"+ # And another\n## A double comment\n\"b\"+ ## And another\n# Nested # comments #\n\"c\"+ # and # some"
},
{
"path": "data/nix/tests/lang/eval-okay-concat.exp",
"chars": 22,
"preview": "[ 1 2 3 4 5 6 7 8 9 ]\n"
},
{
"path": "data/nix/tests/lang/eval-okay-concat.nix",
"chars": 30,
"preview": "[1 2 3] ++ [4 5 6] ++ [7 8 9]\n"
},
{
"path": "data/nix/tests/lang/eval-okay-concatmap.exp",
"chars": 38,
"preview": "[ [ 1 3 5 7 9 ] [ \"a\" \"z\" \"b\" \"z\" ] ]\n"
},
{
"path": "data/nix/tests/lang/eval-okay-concatmap.nix",
"chars": 155,
"preview": "with import ./lib.nix;\n\n[ (builtins.concatMap (x: if x / 2 * 2 == x then [] else [ x ]) (range 0 10))\n (builtins.concat"
},
{
"path": "data/nix/tests/lang/eval-okay-concatstringssep.exp",
"chars": 48,
"preview": "[ \"\" \"foobarxyzzy\" \"foo, bar, xyzzy\" \"foo\" \"\" ]\n"
},
{
"path": "data/nix/tests/lang/eval-okay-concatstringssep.nix",
"chars": 202,
"preview": "with builtins;\n\n[ (concatStringsSep \"\" [])\n (concatStringsSep \"\" [\"foo\" \"bar\" \"xyzzy\"])\n (concatStringsSep \", \" [\"foo\""
},
{
"path": "data/nix/tests/lang/eval-okay-context-introspection.exp",
"chars": 5,
"preview": "true\n"
},
{
"path": "data/nix/tests/lang/eval-okay-context-introspection.nix",
"chars": 651,
"preview": "let\n drv = derivation {\n name = \"fail\";\n builder = \"/bin/false\";\n system = \"x86_64-linux\";\n outputs = [ \"ou"
},
{
"path": "data/nix/tests/lang/eval-okay-context.exp",
"chars": 32,
"preview": "\"foo eval-okay-context.nix bar\"\n"
},
{
"path": "data/nix/tests/lang/eval-okay-context.nix",
"chars": 218,
"preview": "let s = \"foo ${builtins.substring 33 100 (baseNameOf \"${./eval-okay-context.nix}\")} bar\";\nin\n if s != \"foo eval-okay-co"
},
{
"path": "data/nix/tests/lang/eval-okay-curpos.exp",
"chars": 12,
"preview": "[ 3 7 4 9 ]\n"
},
{
"path": "data/nix/tests/lang/eval-okay-curpos.nix",
"chars": 83,
"preview": "# Bla\nlet\n x = __curPos;\n y = __curPos;\nin [ x.line x.column y.line y.column ]\n"
},
{
"path": "data/nix/tests/lang/eval-okay-deepseq.exp",
"chars": 4,
"preview": "456\n"
},
{
"path": "data/nix/tests/lang/eval-okay-deepseq.nix",
"chars": 60,
"preview": "builtins.deepSeq (let as = { x = 123; y = as; }; in as) 456\n"
},
{
"path": "data/nix/tests/lang/eval-okay-delayed-with-inherit.exp",
"chars": 15,
"preview": "\"b-overridden\"\n"
},
{
"path": "data/nix/tests/lang/eval-okay-delayed-with-inherit.nix",
"chars": 466,
"preview": "let\n pkgs_ = with pkgs; {\n a = derivation {\n name = \"a\";\n system = builtins.currentSystem;\n builder ="
},
{
"path": "data/nix/tests/lang/eval-okay-delayed-with.exp",
"chars": 30,
"preview": "\"b-overridden b-overridden a\"\n"
},
{
"path": "data/nix/tests/lang/eval-okay-delayed-with.nix",
"chars": 593,
"preview": "let\n\n pkgs_ = with pkgs; {\n a = derivation {\n name = \"a\";\n system = builtins.currentSystem;\n builder "
},
{
"path": "data/nix/tests/lang/eval-okay-dynamic-attrs-2.exp",
"chars": 5,
"preview": "true\n"
},
{
"path": "data/nix/tests/lang/eval-okay-dynamic-attrs-2.nix",
"chars": 47,
"preview": "{ a.\"${\"b\"}\" = true; a.\"${\"c\"}\" = false; }.a.b\n"
},
{
"path": "data/nix/tests/lang/eval-okay-dynamic-attrs-bare.exp",
"chars": 113,
"preview": "{ binds = true; hasAttrs = true; multiAttrs = true; recBinds = true; selectAttrs = true; selectOrAttrs = true; }\n"
},
{
"path": "data/nix/tests/lang/eval-okay-dynamic-attrs-bare.nix",
"chars": 348,
"preview": "let\n aString = \"a\";\n\n bString = \"b\";\nin {\n hasAttrs = { a.b = null; } ? ${aString}.b;\n\n selectAttrs = { a.b = true; "
},
{
"path": "data/nix/tests/lang/eval-okay-dynamic-attrs.exp",
"chars": 113,
"preview": "{ binds = true; hasAttrs = true; multiAttrs = true; recBinds = true; selectAttrs = true; selectOrAttrs = true; }\n"
},
{
"path": "data/nix/tests/lang/eval-okay-dynamic-attrs.nix",
"chars": 362,
"preview": "let\n aString = \"a\";\n\n bString = \"b\";\nin {\n hasAttrs = { a.b = null; } ? \"${aString}\".b;\n\n selectAttrs = { a.b = true"
},
{
"path": "data/nix/tests/lang/eval-okay-elem.exp",
"chars": 18,
"preview": "[ true false 30 ]\n"
},
{
"path": "data/nix/tests/lang/eval-okay-elem.nix",
"chars": 123,
"preview": "with import ./lib.nix;\n\nlet xs = range 10 40; in\n\n[ (builtins.elem 23 xs) (builtins.elem 42 xs) (builtins.elemAt xs 20) "
},
{
"path": "data/nix/tests/lang/eval-okay-empty-args.exp",
"chars": 5,
"preview": "\"ab\"\n"
},
{
"path": "data/nix/tests/lang/eval-okay-empty-args.nix",
"chars": 48,
"preview": "({}: {x,y,}: \"${x}${y}\") {} {x = \"a\"; y = \"b\";}\n"
},
{
"path": "data/nix/tests/lang/eval-okay-eq-derivations.exp",
"chars": 25,
"preview": "[ true true true false ]\n"
},
{
"path": "data/nix/tests/lang/eval-okay-eq-derivations.nix",
"chars": 497,
"preview": "let\n\n drvA1 = derivation { name = \"a\"; builder = \"/foo\"; system = \"i686-linux\"; };\n drvA2 = derivation { name = \"a\"; b"
},
{
"path": "data/nix/tests/lang/eval-okay-eq.exp.disabled",
"chars": 11,
"preview": "Bool(True)\n"
},
{
"path": "data/nix/tests/lang/eval-okay-eq.nix",
"chars": 72,
"preview": "[\"foobar\" (rec {x = 1; y = x;})]\n==\n[(\"foo\" + \"bar\") ({x = 1; y = 1;})]\n"
},
{
"path": "data/nix/tests/lang/eval-okay-filter.exp",
"chars": 41,
"preview": "[ 0 2 4 6 8 10 100 102 104 106 108 110 ]\n"
},
{
"path": "data/nix/tests/lang/eval-okay-filter.nix",
"chars": 120,
"preview": "with import ./lib.nix;\n\nbuiltins.filter\n (x: x / 2 * 2 == x)\n (builtins.concatLists [ (range 0 10) (range 100 110) ])\n"
},
{
"path": "data/nix/tests/lang/eval-okay-flatten.exp",
"chars": 10,
"preview": "\"1234567\"\n"
},
{
"path": "data/nix/tests/lang/eval-okay-flatten.nix",
"chars": 106,
"preview": "with import ./lib.nix;\n\nlet {\n\n l = [\"1\" \"2\" [\"3\" [\"4\"] [\"5\" \"6\"]] \"7\"];\n\n body = concat (flatten l);\n}\n"
},
{
"path": "data/nix/tests/lang/eval-okay-float.exp",
"chars": 20,
"preview": "[ 3.4 3.5 2.5 1.5 ]\n"
},
{
"path": "data/nix/tests/lang/eval-okay-float.nix",
"chars": 119,
"preview": "[\n (1.1 + 2.3)\n (builtins.add (0.5 + 0.5) (2.0 + 0.5))\n ((0.5 + 0.5) * (2.0 + 0.5))\n ((1.5 + 1.5) / (0.5 * 4.0))\n]\n"
},
{
"path": "data/nix/tests/lang/eval-okay-floor-ceil.exp",
"chars": 14,
"preview": "\"23;24;23;23\"\n"
},
{
"path": "data/nix/tests/lang/eval-okay-floor-ceil.nix",
"chars": 200,
"preview": "with import ./lib.nix;\n\nlet\n n1 = builtins.floor 23.5;\n n2 = builtins.ceil 23.5;\n n3 = builtins.floor 23;\n n4 = buil"
},
{
"path": "data/nix/tests/lang/eval-okay-foldlStrict.exp",
"chars": 7,
"preview": "500500\n"
},
{
"path": "data/nix/tests/lang/eval-okay-foldlStrict.nix",
"chars": 71,
"preview": "with import ./lib.nix;\n\nbuiltins.foldl' (x: y: x + y) 0 (range 1 1000)\n"
},
{
"path": "data/nix/tests/lang/eval-okay-fromTOML.exp",
"chars": 3387,
"preview": "[ { clients = { data = [ [ \"gamma\" \"delta\" ] [ 1 2 ] ]; hosts = [ \"alpha\" \"omega\" ]; }; database = { connection_max = 50"
},
{
"path": "data/nix/tests/lang/eval-okay-fromTOML.nix",
"chars": 4661,
"preview": "[\n\n (builtins.fromTOML ''\n # This is a TOML document.\n\n title = \"TOML Example\"\n\n [owner]\n name = \"Tom Prest"
},
{
"path": "data/nix/tests/lang/eval-okay-fromjson-escapes.exp",
"chars": 265,
"preview": "\"quote \\\" reverse solidus \\\\ solidus / backspace \b formfeed \f newline \\n carriage return \\r horizontal tab \\t 1 char uni"
},
{
"path": "data/nix/tests/lang/eval-okay-fromjson-escapes.nix",
"chars": 423,
"preview": "# This string contains all supported escapes in a JSON string, per json.org\n# \\b and \\f are not supported by Nix\nbuiltin"
},
{
"path": "data/nix/tests/lang/eval-okay-fromjson.exp",
"chars": 5,
"preview": "true\n"
},
{
"path": "data/nix/tests/lang/eval-okay-fromjson.nix",
"chars": 880,
"preview": "# RFC 7159, section 13.\nbuiltins.fromJSON\n ''\n {\n \"Image\": {\n \"Width\": 800,\n \"Height\": 600,\n"
},
{
"path": "data/nix/tests/lang/eval-okay-functionargs.exp.xml",
"chars": 470,
"preview": "<?xml version='1.0' encoding='utf-8'?>\n<expr>\n <list>\n <string value=\"stdenv\" />\n <string value=\"fetchurl\" />\n "
},
{
"path": "data/nix/tests/lang/eval-okay-functionargs.nix",
"chars": 2523,
"preview": "let\n\n stdenvFun = { }: { name = \"stdenv\"; };\n stdenv2Fun = { }: { name = \"stdenv2\"; };\n fetchurlFun = { stdenv }: ass"
},
{
"path": "data/nix/tests/lang/eval-okay-getattrpos-functionargs.exp",
"chars": 75,
"preview": "{ column = 11; file = \"eval-okay-getattrpos-functionargs.nix\"; line = 2; }\n"
},
{
"path": "data/nix/tests/lang/eval-okay-getattrpos-functionargs.nix",
"chars": 156,
"preview": "let\n fun = { foo }: {};\n pos = builtins.unsafeGetAttrPos \"foo\" (builtins.functionArgs fun);\nin { inherit (pos) column "
},
{
"path": "data/nix/tests/lang/eval-okay-getattrpos-undefined.exp",
"chars": 5,
"preview": "null\n"
},
{
"path": "data/nix/tests/lang/eval-okay-getattrpos-undefined.nix",
"chars": 43,
"preview": "builtins.unsafeGetAttrPos \"abort\" builtins\n"
},
{
"path": "data/nix/tests/lang/eval-okay-getattrpos.exp",
"chars": 61,
"preview": "{ column = 5; file = \"eval-okay-getattrpos.nix\"; line = 3; }\n"
},
{
"path": "data/nix/tests/lang/eval-okay-getattrpos.nix",
"chars": 141,
"preview": "let\n as = {\n foo = \"bar\";\n };\n pos = builtins.unsafeGetAttrPos \"foo\" as;\nin { inherit (pos) column line; file = ba"
},
{
"path": "data/nix/tests/lang/eval-okay-getenv.exp",
"chars": 9,
"preview": "\"foobar\"\n"
},
{
"path": "data/nix/tests/lang/eval-okay-getenv.nix",
"chars": 92,
"preview": "builtins.getEnv \"TEST_VAR\" + (if builtins.getEnv \"NO_SUCH_VAR\" == \"\" then \"bar\" else \"bla\")\n"
},
{
"path": "data/nix/tests/lang/eval-okay-hash.exp",
"chars": 0,
"preview": ""
},
{
"path": "data/nix/tests/lang/eval-okay-hashfile.exp",
"chars": 556,
"preview": "[ \"d3b07384d113edec49eaa6238ad5ff00\" \"0f343b0931126a20f133d67c2b018a3b\" \"f1d2d2f924e986ac86fdf7b36c94bcdf32beec15\" \"60ca"
},
{
"path": "data/nix/tests/lang/eval-okay-hashfile.nix",
"chars": 148,
"preview": "let\n paths = [ ./data ./binary-data ];\nin\n builtins.concatLists (map (hash: map (builtins.hashFile hash) paths) [\"md5\""
},
{
"path": "data/nix/tests/lang/eval-okay-hashstring.exp",
"chars": 832,
"preview": "[ \"d41d8cd98f00b204e9800998ecf8427e\" \"6c69ee7f211c640419d5366cc076ae46\" \"bb3438fbabd460ea6dbd27d153e2233b\" \"da39a3ee5e6b"
},
{
"path": "data/nix/tests/lang/eval-okay-hashstring.nix",
"chars": 154,
"preview": "let\n strings = [ \"\" \"text 1\" \"text 2\" ];\nin\n builtins.concatLists (map (hash: map (builtins.hashString hash) strings) "
},
{
"path": "data/nix/tests/lang/eval-okay-if.exp",
"chars": 2,
"preview": "3\n"
},
{
"path": "data/nix/tests/lang/eval-okay-if.nix",
"chars": 58,
"preview": "if \"foo\" != \"f\" + \"oo\" then 1 else if false then 2 else 3\n"
},
{
"path": "data/nix/tests/lang/eval-okay-import.exp",
"chars": 25,
"preview": "[ 1 2 3 4 5 6 7 8 9 10 ]\n"
},
{
"path": "data/nix/tests/lang/eval-okay-import.nix",
"chars": 240,
"preview": "let\n\n overrides = {\n import = fn: scopedImport overrides fn;\n\n scopedImport = attrs: fn: scopedImport (overrides "
},
{
"path": "data/nix/tests/lang/eval-okay-ind-string.exp",
"chars": 2429,
"preview": "\"This is an indented multi-line string\\nliteral. An amount of whitespace at\\nthe start of each line matching the minimu"
},
{
"path": "data/nix/tests/lang/eval-okay-ind-string.nix",
"chars": 3526,
"preview": "let\n\n s1 = ''\n This is an indented multi-line string\n literal. An amount of whitespace at\n the start of each "
},
{
"path": "data/nix/tests/lang/eval-okay-let.exp",
"chars": 9,
"preview": "\"foobar\"\n"
},
{
"path": "data/nix/tests/lang/eval-okay-let.nix",
"chars": 50,
"preview": "let {\n x = \"foo\";\n y = \"bar\";\n body = x + y;\n}\n"
},
{
"path": "data/nix/tests/lang/eval-okay-list.exp",
"chars": 16,
"preview": "\"foobarblatest\"\n"
},
{
"path": "data/nix/tests/lang/eval-okay-list.nix",
"chars": 81,
"preview": "with import ./lib.nix;\n\nlet {\n\n body = concat [\"foo\" \"bar\" \"bla\" \"test\"];\n \n}"
},
{
"path": "data/nix/tests/lang/eval-okay-listtoattrs.exp",
"chars": 8,
"preview": "\"AAbar\"\n"
},
{
"path": "data/nix/tests/lang/eval-okay-listtoattrs.nix",
"chars": 512,
"preview": "# this test shows how to use listToAttrs and that evaluation is still lazy (throw isn't called)\nwith import ./lib.nix;\n\n"
},
{
"path": "data/nix/tests/lang/eval-okay-logic.exp",
"chars": 2,
"preview": "1\n"
},
{
"path": "data/nix/tests/lang/eval-okay-logic.nix",
"chars": 44,
"preview": "assert !false && (true || false) -> true; 1\n"
},
{
"path": "data/nix/tests/lang/eval-okay-map.exp",
"chars": 23,
"preview": "\"foobarblabarxyzzybar\"\n"
},
{
"path": "data/nix/tests/lang/eval-okay-map.nix",
"chars": 75,
"preview": "with import ./lib.nix;\n\nconcat (map (x: x + \"bar\") [ \"foo\" \"bla\" \"xyzzy\" ])"
},
{
"path": "data/nix/tests/lang/eval-okay-mapattrs.exp",
"chars": 30,
"preview": "{ x = \"x-foo\"; y = \"y-bar\"; }\n"
},
{
"path": "data/nix/tests/lang/eval-okay-mapattrs.nix",
"chars": 102,
"preview": "with import ./lib.nix;\n\nbuiltins.mapAttrs (name: value: name + \"-\" + value) { x = \"foo\"; y = \"bar\"; }\n"
},
{
"path": "data/nix/tests/lang/eval-okay-nested-with.exp",
"chars": 2,
"preview": "2\n"
},
{
"path": "data/nix/tests/lang/eval-okay-nested-with.nix",
"chars": 36,
"preview": "with { x = 1; };\nwith { x = 2; };\nx\n"
},
{
"path": "data/nix/tests/lang/eval-okay-new-let.exp",
"chars": 14,
"preview": "\"xyzzyfoobar\"\n"
},
{
"path": "data/nix/tests/lang/eval-okay-new-let.nix",
"chars": 140,
"preview": "let\n\n f = z: \n\n let\n x = \"foo\";\n y = \"bar\";\n body = 1; # compat test\n in\n z + x + y;\n\n arg ="
},
{
"path": "data/nix/tests/lang/eval-okay-null-dynamic-attrs.exp",
"chars": 5,
"preview": "true\n"
},
{
"path": "data/nix/tests/lang/eval-okay-null-dynamic-attrs.nix",
"chars": 26,
"preview": "{ ${null} = true; } == {}\n"
},
{
"path": "data/nix/tests/lang/eval-okay-overrides.exp",
"chars": 2,
"preview": "2\n"
},
{
"path": "data/nix/tests/lang/eval-okay-overrides.nix",
"chars": 92,
"preview": "let\n\n overrides = { a = 2; };\n\nin (rec {\n __overrides = overrides;\n x = a;\n a = 1;\n}).x\n"
},
{
"path": "data/nix/tests/lang/eval-okay-partition.exp",
"chars": 97,
"preview": "{ right = [ 0 2 4 6 8 10 100 102 104 106 108 110 ]; wrong = [ 1 3 5 7 9 101 103 105 107 109 ]; }\n"
},
{
"path": "data/nix/tests/lang/eval-okay-partition.nix",
"chars": 123,
"preview": "with import ./lib.nix;\n\nbuiltins.partition\n (x: x / 2 * 2 == x)\n (builtins.concatLists [ (range 0 10) (range 100 110) "
},
{
"path": "data/nix/tests/lang/eval-okay-path-antiquotation.nix",
"chars": 202,
"preview": "let\n foo = \"foo\";\nin\n{\n simple = ./${foo};\n surrounded = ./a-${foo}-b;\n absolute = /${foo};\n expr = ./${foo + \"/bar"
},
{
"path": "data/nix/tests/lang/eval-okay-path.nix",
"chars": 195,
"preview": "builtins.path\n { path = ./.;\n filter = path: _: baseNameOf path == \"data\";\n recursive = true;\n sha256 = \"1yhm3"
},
{
"path": "data/nix/tests/lang/eval-okay-pathexists.exp",
"chars": 5,
"preview": "true\n"
},
{
"path": "data/nix/tests/lang/eval-okay-pathexists.nix",
"chars": 258,
"preview": "builtins.pathExists (builtins.toPath ./lib.nix)\n&& builtins.pathExists (builtins.toPath (builtins.toString ./lib.nix))\n&"
},
{
"path": "data/nix/tests/lang/eval-okay-patterns.exp",
"chars": 18,
"preview": "\"abcxyzDDDDEFijk\"\n"
},
{
"path": "data/nix/tests/lang/eval-okay-patterns.nix",
"chars": 346,
"preview": "let\n\n f = args@{x, y, z}: x + args.y + z;\n\n g = {x, y, z}@args: f args;\n\n h = {x ? \"d\", y ? x, z ? args.x}@args: x + "
},
{
"path": "data/nix/tests/lang/eval-okay-readDir.exp",
"chars": 40,
"preview": "{ bar = \"regular\"; foo = \"directory\"; }\n"
},
{
"path": "data/nix/tests/lang/eval-okay-readDir.nix",
"chars": 27,
"preview": "builtins.readDir ./readDir\n"
},
{
"path": "data/nix/tests/lang/eval-okay-readfile.exp",
"chars": 47,
"preview": "\"builtins.readFile ./eval-okay-readfile.nix\\n\"\n"
},
{
"path": "data/nix/tests/lang/eval-okay-readfile.nix",
"chars": 43,
"preview": "builtins.readFile ./eval-okay-readfile.nix\n"
},
{
"path": "data/nix/tests/lang/eval-okay-redefine-builtin.exp",
"chars": 6,
"preview": "false\n"
},
{
"path": "data/nix/tests/lang/eval-okay-redefine-builtin.nix",
"chars": 69,
"preview": "let\n throw = abort \"Error!\";\nin (builtins.tryEval <foobaz>).success\n"
},
{
"path": "data/nix/tests/lang/eval-okay-regex-match.exp",
"chars": 5,
"preview": "true\n"
},
{
"path": "data/nix/tests/lang/eval-okay-regex-match.nix",
"chars": 814,
"preview": "with builtins;\n\nlet\n\n matches = pat: s: match pat s != null;\n\n splitFN = match \"((.*)/)?([^/]*)\\\\.(nix|cc)\";\n\nin\n\nasse"
},
{
"path": "data/nix/tests/lang/eval-okay-regex-split.exp",
"chars": 5,
"preview": "true\n"
},
{
"path": "data/nix/tests/lang/eval-okay-regex-split.nix",
"chars": 1852,
"preview": "with builtins;\n\n# Non capturing regex returns empty lists\nassert split \"foobar\" \"foobar\" == [\"\" [] \"\"];\nassert split "
},
{
"path": "data/nix/tests/lang/eval-okay-remove.exp",
"chars": 4,
"preview": "456\n"
},
{
"path": "data/nix/tests/lang/eval-okay-remove.nix",
"chars": 77,
"preview": "let {\n attrs = {x = 123; y = 456;};\n\n body = (removeAttrs attrs [\"x\"]).y;\n}"
},
{
"path": "data/nix/tests/lang/eval-okay-replacestrings.exp",
"chars": 65,
"preview": "[ \"faabar\" \"fbar\" \"fubar\" \"faboor\" \"fubar\" \"XaXbXcX\" \"X\" \"a_b\" ]\n"
},
{
"path": "data/nix/tests/lang/eval-okay-replacestrings.nix",
"chars": 344,
"preview": "with builtins;\n\n[ (replaceStrings [\"o\"] [\"a\"] \"foobar\")\n (replaceStrings [\"o\"] [\"\"] \"foobar\")\n (replaceStrings [\"oo\"] "
}
]
// ... and 204 more files (download for full content)
About this extraction
This page contains the full source code of the jwiegley/hnix GitHub repository, extracted and formatted as plain text for AI agents and large language models (LLMs). The extraction includes 404 files (1.6 MB), approximately 453.7k tokens. Use this with OpenClaw, Claude, ChatGPT, Cursor, Windsurf, or any other AI tool that accepts text input. You can copy the full output to your clipboard or download it as a .txt file.
Extracted by GitExtract — free GitHub repo to text converter for AI. Built by Nikandr Surkov.