Merge pull request #886 from dhall-lang/gabriel/dhall_nix
Merge `dhall-nix` into `dhall-haskell`
This commit is contained in:
commit
505bd9240d
|
@ -0,0 +1,76 @@
|
|||
# This file has been generated -- see https://github.com/hvr/multi-ghc-travis
|
||||
language: c
|
||||
sudo: false
|
||||
|
||||
cache:
|
||||
directories:
|
||||
- $HOME/.cabsnap
|
||||
- $HOME/.cabal/packages
|
||||
|
||||
before_cache:
|
||||
- rm -fv $HOME/.cabal/packages/hackage.haskell.org/build-reports.log
|
||||
- rm -fv $HOME/.cabal/packages/hackage.haskell.org/00-index.tar
|
||||
|
||||
matrix:
|
||||
include:
|
||||
- env: CABALVER=1.24 GHCVER=8.0.1
|
||||
compiler: ": #GHC 8.0.1"
|
||||
addons: {apt: {packages: [cabal-install-1.24,ghc-8.0.1], sources: [hvr-ghc]}}
|
||||
|
||||
before_install:
|
||||
- unset CC
|
||||
- export PATH=/opt/ghc/$GHCVER/bin:/opt/cabal/$CABALVER/bin:$PATH
|
||||
|
||||
install:
|
||||
- cabal --version
|
||||
- echo "$(ghc --version) [$(ghc --print-project-git-commit-id 2> /dev/null || echo '?')]"
|
||||
- if [ -f $HOME/.cabal/packages/hackage.haskell.org/00-index.tar.gz ];
|
||||
then
|
||||
zcat $HOME/.cabal/packages/hackage.haskell.org/00-index.tar.gz >
|
||||
$HOME/.cabal/packages/hackage.haskell.org/00-index.tar;
|
||||
fi
|
||||
- travis_retry cabal update -v
|
||||
- sed -i 's/^jobs:/-- jobs:/' ${HOME}/.cabal/config
|
||||
- cabal install --only-dependencies --enable-tests --enable-benchmarks --dry -v > installplan.txt
|
||||
- sed -i -e '1,/^Resolving /d' installplan.txt; cat installplan.txt
|
||||
|
||||
# check whether current requested install-plan matches cached package-db snapshot
|
||||
- if diff -u $HOME/.cabsnap/installplan.txt installplan.txt;
|
||||
then
|
||||
echo "cabal build-cache HIT";
|
||||
rm -rfv .ghc;
|
||||
cp -a $HOME/.cabsnap/ghc $HOME/.ghc;
|
||||
cp -a $HOME/.cabsnap/lib $HOME/.cabsnap/share $HOME/.cabsnap/bin $HOME/.cabal/;
|
||||
else
|
||||
echo "cabal build-cache MISS";
|
||||
rm -rf $HOME/.cabsnap;
|
||||
mkdir -p $HOME/.ghc $HOME/.cabal/lib $HOME/.cabal/share $HOME/.cabal/bin;
|
||||
cabal install --only-dependencies --enable-tests --enable-benchmarks;
|
||||
fi
|
||||
|
||||
# snapshot package-db on cache miss
|
||||
- if [ ! -d $HOME/.cabsnap ];
|
||||
then
|
||||
echo "snapshotting package-db to build-cache";
|
||||
mkdir $HOME/.cabsnap;
|
||||
cp -a $HOME/.ghc $HOME/.cabsnap/ghc;
|
||||
cp -a $HOME/.cabal/lib $HOME/.cabal/share $HOME/.cabal/bin installplan.txt $HOME/.cabsnap/;
|
||||
fi
|
||||
|
||||
# Here starts the actual work to be performed for the package under test;
|
||||
# any command which exits with a non-zero exit code causes the build to fail.
|
||||
script:
|
||||
- if [ -f configure.ac ]; then autoreconf -i; fi
|
||||
- cabal configure --enable-tests --enable-benchmarks -v2 # -v2 provides useful information for debugging
|
||||
- cabal build # this builds all libraries and executables (including tests/benchmarks)
|
||||
- cabal test
|
||||
- cabal check
|
||||
- cabal sdist # tests that a source-distribution can be generated
|
||||
|
||||
# Check that the resulting source distribution can be built & installed.
|
||||
# If there are no other `.tar.gz` files in `dist`, this can be even simpler:
|
||||
# `cabal install --force-reinstalls dist/*-*.tar.gz`
|
||||
- SRC_TGZ=$(cabal info . | awk '{print $2;exit}').tar.gz &&
|
||||
(cd dist && cabal install --force-reinstalls "$SRC_TGZ")
|
||||
|
||||
# EOF
|
|
@ -0,0 +1,24 @@
|
|||
Copyright (c) 2017 Gabriel Gonzalez
|
||||
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 Gabriel Gonzalez nor the names of other contributors
|
||||
may be used to endorse or promote products derived from this software
|
||||
without specific prior written permission.
|
||||
|
||||
THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND
|
||||
ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
|
||||
WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
|
||||
DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR
|
||||
ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
|
||||
(INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
|
||||
LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON
|
||||
ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
|
||||
(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
|
||||
SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
|
@ -0,0 +1,81 @@
|
|||
# `dhall-nix 1.1.6`
|
||||
|
||||
This `dhall-nix` package provides a Dhall to Nix compiler. You can use this
|
||||
compiler to program Nix using the Dhall language. This package targets people
|
||||
who wish Nix had a type system.
|
||||
|
||||
## Quick start
|
||||
|
||||
If you have Nix installed then you can build and run this package using:
|
||||
|
||||
```bash
|
||||
$ nix-build -A dhall-nix release.nix
|
||||
$ result/bin/dhall-to-nix <<< "λ(x : Bool) → x == False"
|
||||
x: x == false
|
||||
$ result/bin/dhall-to-nix <<< "{ foo = 1, bar = True }"
|
||||
{ bar = true; foo = 1; }
|
||||
$ result/bin/dhall-to-nix <<< "< Left = 2 | Right : Natural >"
|
||||
{ Left, Right }: Left 2
|
||||
```
|
||||
|
||||
However, this package is also designed to be used directly from Nix. You can
|
||||
use the following `dhallToNix` utility to translate Dhall source code to the
|
||||
corresponding Nix expression directly within Nix:
|
||||
|
||||
```nix
|
||||
dhallToNix = code :
|
||||
let
|
||||
file = builtins.toFile "dhall-expr" code;
|
||||
|
||||
drv = pkgs.stdenv.mkDerivation {
|
||||
name = "dhall-expr-as-nix";
|
||||
|
||||
buildCommand = ''
|
||||
dhall-to-nix <<< "${file}" > $out
|
||||
'';
|
||||
|
||||
buildInputs = [ pkgs.haskellPackages.dhall-nix ];
|
||||
};
|
||||
in
|
||||
import "${drv}";
|
||||
```
|
||||
|
||||
The above `dhallToNix` utility is now in `nixpkgs` so you can use `pkgs.dhallToNix`
|
||||
to transform Dhall expressions to Nix expressions
|
||||
|
||||
## Development status
|
||||
|
||||
[![Build Status](https://travis-ci.org/Gabriel439/Haskell-Dhall-Nix-Library.png)](https://travis-ci.org/Gabriel439/Haskell-Dhall-Nix-Library)
|
||||
|
||||
I don't expect this library to change unless:
|
||||
|
||||
* ... the Dhall language changes, which is possible but not very likely
|
||||
* ... there are bugs, but the test suite in [release.nix](./release.nix) should
|
||||
protect against this
|
||||
|
||||
## License (BSD 3-clause)
|
||||
|
||||
Copyright (c) 2017 Gabriel Gonzalez
|
||||
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 Gabriel Gonzalez nor the names of other contributors
|
||||
may be used to endorse or promote products derived from this software
|
||||
without specific prior written permission.
|
||||
|
||||
THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND
|
||||
ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
|
||||
WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
|
||||
DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR
|
||||
ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
|
||||
(INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
|
||||
LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON
|
||||
ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
|
||||
(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
|
||||
SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
|
@ -0,0 +1,2 @@
|
|||
import Distribution.Simple
|
||||
main = defaultMain
|
|
@ -0,0 +1,51 @@
|
|||
Name: dhall-nix
|
||||
Version: 1.1.6
|
||||
Cabal-Version: >=1.8.0.2
|
||||
Build-Type: Simple
|
||||
Tested-With: GHC == 8.0.1
|
||||
License: BSD3
|
||||
License-File: LICENSE
|
||||
Copyright: 2017 Gabriel Gonzalez
|
||||
Author: Gabriel Gonzalez
|
||||
Maintainer: Gabriel439@gmail.com
|
||||
Bug-Reports: https://github.com/Gabriel439/Haskell-Dhall-Nix-Library/issues
|
||||
Synopsis: Dhall to Nix compiler
|
||||
Description:
|
||||
Use this package if you want to compile Dhall expressions to the Nix language.
|
||||
You can use this package as a library or an executable:
|
||||
.
|
||||
* See the "Dhall.Nix" module if you want to use this package as a library
|
||||
.
|
||||
* Use the @dhall-to-nix@ program from this package if you want an executable
|
||||
.
|
||||
The "Dhall.Nix" module also contains instructions for how to use this package
|
||||
Category: Compiler
|
||||
Source-Repository head
|
||||
Type: git
|
||||
Location: https://github.com/Gabriel439/Haskell-Dhall-Nix-Library
|
||||
|
||||
Library
|
||||
Hs-Source-Dirs: src
|
||||
Build-Depends:
|
||||
base >= 4.8.0.0 && < 5 ,
|
||||
containers < 0.7 ,
|
||||
data-fix < 0.3 ,
|
||||
dhall >= 1.19 && < 1.22,
|
||||
hnix >= 0.5 && < 0.7 ,
|
||||
neat-interpolation < 0.4 ,
|
||||
text >= 0.8.0.0 && < 1.3
|
||||
Exposed-Modules:
|
||||
Dhall.Nix
|
||||
GHC-Options: -Wall
|
||||
|
||||
Executable dhall-to-nix
|
||||
Hs-Source-Dirs: exec
|
||||
Main-Is: Main.hs
|
||||
Build-Depends:
|
||||
base ,
|
||||
dhall ,
|
||||
dhall-nix ,
|
||||
hnix ,
|
||||
optparse-generic >= 1.1.1 && < 1.4,
|
||||
text
|
||||
GHC-Options: -Wall
|
|
@ -0,0 +1,52 @@
|
|||
{-# LANGUAGE OverloadedStrings #-}
|
||||
|
||||
module Main where
|
||||
|
||||
import Control.Exception (SomeException)
|
||||
import System.Exit (ExitCode(..))
|
||||
|
||||
import qualified Control.Exception
|
||||
import qualified Data.Text.IO
|
||||
import qualified Dhall
|
||||
import qualified Dhall.Import
|
||||
import qualified Dhall.Nix
|
||||
import qualified Dhall.Parser
|
||||
import qualified Dhall.TypeCheck
|
||||
import qualified GHC.IO.Encoding
|
||||
import qualified Nix.Pretty
|
||||
import qualified Options.Generic
|
||||
import qualified System.Exit
|
||||
import qualified System.IO
|
||||
|
||||
main :: IO ()
|
||||
main = handle (Dhall.detailed (do
|
||||
GHC.IO.Encoding.setLocaleEncoding GHC.IO.Encoding.utf8
|
||||
() <- Options.Generic.getRecord "Compile Dhall to Nix"
|
||||
|
||||
inText <- Data.Text.IO.getContents
|
||||
|
||||
expr <- case Dhall.Parser.exprFromText "(stdin)" inText of
|
||||
Left err -> Control.Exception.throwIO err
|
||||
Right expr -> return expr
|
||||
|
||||
expr' <- Dhall.Import.load expr
|
||||
case Dhall.TypeCheck.typeOf expr' of
|
||||
Left err -> Control.Exception.throwIO err
|
||||
Right _ -> return ()
|
||||
|
||||
nix <- case Dhall.Nix.dhallToNix expr' of
|
||||
Left err -> Control.Exception.throwIO err
|
||||
Right nix -> return nix
|
||||
print (Nix.Pretty.prettyNix nix) ))
|
||||
|
||||
handle :: IO a -> IO a
|
||||
handle = Control.Exception.handle handler
|
||||
where
|
||||
handler :: SomeException -> IO a
|
||||
handler e = case Control.Exception.fromException e of
|
||||
Just ExitSuccess -> do
|
||||
Control.Exception.throwIO e
|
||||
_ -> do
|
||||
System.IO.hPutStrLn System.IO.stderr ""
|
||||
System.IO.hPrint System.IO.stderr e
|
||||
System.Exit.exitFailure
|
|
@ -0,0 +1,18 @@
|
|||
{ mkDerivation, base, containers, deepseq, erf, process, random
|
||||
, stdenv, template-haskell, tf-random, transformers
|
||||
}:
|
||||
mkDerivation {
|
||||
pname = "QuickCheck";
|
||||
version = "2.12.6.1";
|
||||
sha256 = "0b2aa7f5c625b5875c36f5f548926fcdaedf4311bd3a4c291fcf10b8d7faa170";
|
||||
revision = "1";
|
||||
editedCabalFile = "0w5gygp6pmyjzjjx5irfflcbx586zfnqidq669ssqqfsadf944xv";
|
||||
libraryHaskellDepends = [
|
||||
base containers deepseq erf random template-haskell tf-random
|
||||
transformers
|
||||
];
|
||||
testHaskellDepends = [ base deepseq process ];
|
||||
homepage = "https://github.com/nick8325/quickcheck";
|
||||
description = "Automatic testing of Haskell programs";
|
||||
license = stdenv.lib.licenses.bsd3;
|
||||
}
|
|
@ -0,0 +1,33 @@
|
|||
{ mkDerivation, attoparsec, base, base-compat, base-orphans
|
||||
, base16-bytestring, bytestring, containers, contravariant, deepseq
|
||||
, directory, dlist, filepath, generic-deriving, ghc-prim, hashable
|
||||
, hashable-time, integer-logarithms, primitive, QuickCheck
|
||||
, quickcheck-instances, scientific, stdenv, tagged, tasty
|
||||
, tasty-hunit, tasty-quickcheck, template-haskell, text
|
||||
, th-abstraction, time, time-locale-compat, unordered-containers
|
||||
, uuid-types, vector
|
||||
}:
|
||||
mkDerivation {
|
||||
pname = "aeson";
|
||||
version = "1.4.2.0";
|
||||
sha256 = "75ce71814a33d5e5568208e6806a8847e7ba47fea74d30f6a8b1b56ecb318bd0";
|
||||
revision = "1";
|
||||
editedCabalFile = "067y82gq86740j2zj4y6v7z9b5860ncg2g9lfnrpsnb9jqm7arl1";
|
||||
libraryHaskellDepends = [
|
||||
attoparsec base base-compat bytestring containers contravariant
|
||||
deepseq dlist ghc-prim hashable primitive scientific tagged
|
||||
template-haskell text th-abstraction time time-locale-compat
|
||||
unordered-containers uuid-types vector
|
||||
];
|
||||
testHaskellDepends = [
|
||||
attoparsec base base-compat base-orphans base16-bytestring
|
||||
bytestring containers directory dlist filepath generic-deriving
|
||||
ghc-prim hashable hashable-time integer-logarithms QuickCheck
|
||||
quickcheck-instances scientific tagged tasty tasty-hunit
|
||||
tasty-quickcheck template-haskell text time time-locale-compat
|
||||
unordered-containers uuid-types vector
|
||||
];
|
||||
homepage = "https://github.com/bos/aeson";
|
||||
description = "Fast JSON parsing and encoding";
|
||||
license = stdenv.lib.licenses.bsd3;
|
||||
}
|
|
@ -0,0 +1,9 @@
|
|||
{ mkDerivation, base, stdenv, unix }:
|
||||
mkDerivation {
|
||||
pname = "base-compat";
|
||||
version = "0.10.5";
|
||||
sha256 = "990aea21568956d44ab018c5dbfbaea014b9a0d5295d29ca7550149419a6fb41";
|
||||
libraryHaskellDepends = [ base unix ];
|
||||
description = "A compatibility layer for base";
|
||||
license = stdenv.lib.licenses.mit;
|
||||
}
|
|
@ -0,0 +1,14 @@
|
|||
{ mkDerivation, base, ghc-prim, hspec, hspec-discover, QuickCheck
|
||||
, stdenv
|
||||
}:
|
||||
mkDerivation {
|
||||
pname = "base-orphans";
|
||||
version = "0.8.1";
|
||||
sha256 = "442bd63aed102e753b2fed15df8ae19f35ee07af26590da63837c523b64a99db";
|
||||
libraryHaskellDepends = [ base ghc-prim ];
|
||||
testHaskellDepends = [ base hspec QuickCheck ];
|
||||
testToolDepends = [ hspec-discover ];
|
||||
homepage = "https://github.com/haskell-compat/base-orphans#readme";
|
||||
description = "Backwards-compatible orphan instances for base";
|
||||
license = stdenv.lib.licenses.mit;
|
||||
}
|
|
@ -0,0 +1,15 @@
|
|||
{ mkDerivation, aeson, aeson-pretty, base, cborg, scientific
|
||||
, stdenv, text, unordered-containers, vector
|
||||
}:
|
||||
mkDerivation {
|
||||
pname = "cborg-json";
|
||||
version = "0.2.1.0";
|
||||
sha256 = "3fb6b54e6ddd322880689fb461f7911aca45b9758482c9f9949619c7d7b52006";
|
||||
libraryHaskellDepends = [
|
||||
aeson aeson-pretty base cborg scientific text unordered-containers
|
||||
vector
|
||||
];
|
||||
homepage = "https://github.com/well-typed/cborg";
|
||||
description = "A library for encoding JSON as CBOR";
|
||||
license = stdenv.lib.licenses.bsd3;
|
||||
}
|
|
@ -0,0 +1,10 @@
|
|||
{ mkDerivation, base, StateVar, stdenv, transformers }:
|
||||
mkDerivation {
|
||||
pname = "contravariant";
|
||||
version = "1.5";
|
||||
sha256 = "6ef067b692ad69ffff294b953aa85f3ded459d4ae133c37896222a09280fc3c2";
|
||||
libraryHaskellDepends = [ base StateVar transformers ];
|
||||
homepage = "http://github.com/ekmett/contravariant/";
|
||||
description = "Contravariant functors";
|
||||
license = stdenv.lib.licenses.bsd3;
|
||||
}
|
|
@ -0,0 +1,18 @@
|
|||
{ mkDerivation, base, containers, data-fix, dhall, hnix
|
||||
, neat-interpolation, optparse-generic, stdenv, text
|
||||
}:
|
||||
mkDerivation {
|
||||
pname = "dhall-nix";
|
||||
version = "1.1.6";
|
||||
src = ./..;
|
||||
isLibrary = true;
|
||||
isExecutable = true;
|
||||
libraryHaskellDepends = [
|
||||
base containers data-fix dhall hnix neat-interpolation text
|
||||
];
|
||||
executableHaskellDepends = [
|
||||
base dhall hnix optparse-generic text
|
||||
];
|
||||
description = "Dhall to Nix compiler";
|
||||
license = stdenv.lib.licenses.bsd3;
|
||||
}
|
|
@ -0,0 +1,41 @@
|
|||
{ mkDerivation, aeson, aeson-pretty, ansi-terminal, base
|
||||
, bytestring, case-insensitive, cborg, cborg-json, containers
|
||||
, contravariant, criterion, cryptonite, deepseq, Diff, directory
|
||||
, doctest, dotgen, exceptions, filepath, haskeline, http-client
|
||||
, http-client-tls, http-types, lens-family-core, megaparsec, memory
|
||||
, mockery, mtl, optparse-applicative, parsers, prettyprinter
|
||||
, prettyprinter-ansi-terminal, QuickCheck, quickcheck-instances
|
||||
, repline, scientific, serialise, stdenv, tasty, tasty-hunit
|
||||
, tasty-quickcheck, template-haskell, text, transformers
|
||||
, unordered-containers, uri-encode, vector
|
||||
}:
|
||||
mkDerivation {
|
||||
pname = "dhall";
|
||||
version = "1.21.0";
|
||||
sha256 = "9b22cc6f7694ef2f5d5d6fa66727044622b9905b2a9da0cdf376c75ad3b9df0e";
|
||||
revision = "1";
|
||||
editedCabalFile = "0ap1490jks9hmwf73vlrj7bsfrf4m5yvgqxx3ix57w23ia5gy662";
|
||||
isLibrary = true;
|
||||
isExecutable = true;
|
||||
libraryHaskellDepends = [
|
||||
aeson aeson-pretty ansi-terminal base bytestring case-insensitive
|
||||
cborg cborg-json containers contravariant cryptonite Diff directory
|
||||
dotgen exceptions filepath haskeline http-client http-client-tls
|
||||
http-types lens-family-core megaparsec memory mtl
|
||||
optparse-applicative parsers prettyprinter
|
||||
prettyprinter-ansi-terminal repline scientific serialise
|
||||
template-haskell text transformers unordered-containers uri-encode
|
||||
vector
|
||||
];
|
||||
executableHaskellDepends = [ base ];
|
||||
testHaskellDepends = [
|
||||
base bytestring cborg containers deepseq directory doctest filepath
|
||||
mockery prettyprinter QuickCheck quickcheck-instances serialise
|
||||
tasty tasty-hunit tasty-quickcheck text transformers vector
|
||||
];
|
||||
benchmarkHaskellDepends = [
|
||||
base bytestring containers criterion directory serialise text
|
||||
];
|
||||
description = "A configuration language guaranteed to terminate";
|
||||
license = stdenv.lib.licenses.bsd3;
|
||||
}
|
|
@ -0,0 +1,49 @@
|
|||
{ rev # The Git revision of nixpkgs to fetch
|
||||
, sha256 # The SHA256 of the downloaded data
|
||||
, outputSha256 ? null # The SHA256 fixed-output hash
|
||||
, system ? builtins.currentSystem # This is overridable if necessary
|
||||
}:
|
||||
|
||||
if (0 <= builtins.compareVersions builtins.nixVersion "1.12")
|
||||
|
||||
# In Nix 1.12, we can just give a `sha256` to `builtins.fetchTarball`.
|
||||
then (
|
||||
builtins.fetchTarball {
|
||||
url = "https://github.com/NixOS/nixpkgs/archive/${rev}.tar.gz";
|
||||
sha256 = outputSha256;
|
||||
})
|
||||
|
||||
# This hack should at least work for Nix 1.11
|
||||
else (
|
||||
(rec {
|
||||
tarball = import <nix/fetchurl.nix> {
|
||||
url = "https://github.com/NixOS/nixpkgs/archive/${rev}.tar.gz";
|
||||
inherit sha256;
|
||||
};
|
||||
|
||||
builtin-paths = import <nix/config.nix>;
|
||||
|
||||
script = builtins.toFile "nixpkgs-unpacker" ''
|
||||
"$coreutils/mkdir" "$out"
|
||||
cd "$out"
|
||||
"$gzip" --decompress < "$tarball" | "$tar" -x --strip-components=1
|
||||
'';
|
||||
|
||||
nixpkgs = builtins.derivation ({
|
||||
name = "nixpkgs-${builtins.substring 0 6 rev}";
|
||||
|
||||
builder = builtins.storePath builtin-paths.shell;
|
||||
|
||||
args = [ script ];
|
||||
|
||||
inherit tarball system;
|
||||
|
||||
tar = builtins.storePath builtin-paths.tar;
|
||||
gzip = builtins.storePath builtin-paths.gzip;
|
||||
coreutils = builtins.storePath builtin-paths.coreutils;
|
||||
} // (if null == outputSha256 then { } else {
|
||||
outputHashMode = "recursive";
|
||||
outputHashAlgo = "sha256";
|
||||
outputHash = outputSha256;
|
||||
}));
|
||||
}).nixpkgs)
|
|
@ -0,0 +1,16 @@
|
|||
{ mkDerivation, base, comonad, containers, distributive, exceptions
|
||||
, mtl, profunctors, semigroupoids, stdenv, template-haskell
|
||||
, transformers, transformers-base
|
||||
}:
|
||||
mkDerivation {
|
||||
pname = "free";
|
||||
version = "5.1";
|
||||
sha256 = "70424d5c82dea36a0a29c4f5f6bc047597a947ad46f3d66312e47bbee2eeea84";
|
||||
libraryHaskellDepends = [
|
||||
base comonad containers distributive exceptions mtl profunctors
|
||||
semigroupoids template-haskell transformers transformers-base
|
||||
];
|
||||
homepage = "http://github.com/ekmett/free/";
|
||||
description = "Monads for free";
|
||||
license = stdenv.lib.licenses.bsd3;
|
||||
}
|
|
@ -0,0 +1,26 @@
|
|||
{ mkDerivation, base, base16-bytestring, base64-bytestring, binary
|
||||
, bytestring, containers, cryptohash-md5, cryptohash-sha1
|
||||
, cryptohash-sha256, directory, filepath, hashable, mtl, process
|
||||
, regex-base, regex-tdfa-text, stdenv, tasty, tasty-discover
|
||||
, tasty-hspec, tasty-hunit, tasty-quickcheck, temporary, text, unix
|
||||
, unordered-containers, vector
|
||||
}:
|
||||
mkDerivation {
|
||||
pname = "hnix-store-core";
|
||||
version = "0.1.0.0";
|
||||
sha256 = "878c9a1dcb535b76efb7af392f9a9e75b954ce4ebb75acac91036a6c3c1d3df7";
|
||||
libraryHaskellDepends = [
|
||||
base base16-bytestring binary bytestring containers cryptohash-md5
|
||||
cryptohash-sha1 cryptohash-sha256 directory filepath hashable mtl
|
||||
regex-base regex-tdfa-text text unix unordered-containers vector
|
||||
];
|
||||
testHaskellDepends = [
|
||||
base base64-bytestring binary bytestring containers directory
|
||||
process tasty tasty-discover tasty-hspec tasty-hunit
|
||||
tasty-quickcheck temporary text
|
||||
];
|
||||
testToolDepends = [ tasty-discover ];
|
||||
homepage = "https://github.com/haskell-nix/hnix-store";
|
||||
description = "Core effects for interacting with the Nix store";
|
||||
license = stdenv.lib.licenses.asl20;
|
||||
}
|
|
@ -0,0 +1,67 @@
|
|||
{ mkDerivation, aeson, array, base, base16-bytestring, binary
|
||||
, bytestring, comonad, containers, contravariant, criterion
|
||||
, cryptohash-md5, cryptohash-sha1, cryptohash-sha256
|
||||
, cryptohash-sha512, data-fix, deepseq, dependent-sum
|
||||
, deriving-compat, Diff, directory, exceptions, fetchgit, filepath
|
||||
, free, generic-random, Glob, hashable, hashing, haskeline
|
||||
, hedgehog, hnix-store-core, http-client, http-client-tls
|
||||
, http-types, interpolate, lens-family, lens-family-core
|
||||
, lens-family-th, logict, megaparsec, monad-control, monadlist, mtl
|
||||
, optparse-applicative, parser-combinators, pretty-show
|
||||
, prettyprinter, process, ref-tf, regex-tdfa, regex-tdfa-text
|
||||
, repline, scientific, semigroups, serialise, split, stdenv, syb
|
||||
, tasty, tasty-hedgehog, tasty-hunit, tasty-quickcheck, tasty-th
|
||||
, template-haskell, text, these, time, transformers
|
||||
, transformers-base, unix, unordered-containers, vector, xml
|
||||
}:
|
||||
mkDerivation {
|
||||
pname = "hnix";
|
||||
version = "0.6.0";
|
||||
src = fetchgit {
|
||||
url = "https://github.com/haskell-nix/hnix.git";
|
||||
sha256 = "15g4brrl8qj5dhx54x0rc4212q11bljvv4wh5qz199p2pk7gbqwk";
|
||||
rev = "3d89159ee425bf4671a6e4a610c1527d7ce251a9";
|
||||
};
|
||||
isLibrary = true;
|
||||
isExecutable = true;
|
||||
libraryHaskellDepends = [
|
||||
aeson array base base16-bytestring binary bytestring comonad
|
||||
containers contravariant cryptohash-md5 cryptohash-sha1
|
||||
cryptohash-sha256 cryptohash-sha512 data-fix deepseq dependent-sum
|
||||
deriving-compat directory exceptions filepath free hashable hashing
|
||||
haskeline hnix-store-core http-client http-client-tls http-types
|
||||
interpolate lens-family lens-family-core lens-family-th logict
|
||||
megaparsec monad-control monadlist mtl optparse-applicative
|
||||
parser-combinators pretty-show prettyprinter process ref-tf
|
||||
regex-tdfa regex-tdfa-text scientific semigroups serialise split
|
||||
syb template-haskell text these time transformers transformers-base
|
||||
unix unordered-containers vector xml
|
||||
];
|
||||
executableHaskellDepends = [
|
||||
aeson base base16-bytestring bytestring comonad containers
|
||||
cryptohash-md5 cryptohash-sha1 cryptohash-sha256 cryptohash-sha512
|
||||
data-fix deepseq exceptions filepath free hashing haskeline mtl
|
||||
optparse-applicative pretty-show prettyprinter ref-tf repline
|
||||
serialise template-haskell text time transformers
|
||||
unordered-containers
|
||||
];
|
||||
testHaskellDepends = [
|
||||
base base16-bytestring bytestring containers cryptohash-md5
|
||||
cryptohash-sha1 cryptohash-sha256 cryptohash-sha512 data-fix
|
||||
deepseq dependent-sum Diff directory exceptions filepath
|
||||
generic-random Glob hashing hedgehog interpolate megaparsec mtl
|
||||
optparse-applicative pretty-show prettyprinter process serialise
|
||||
split tasty tasty-hedgehog tasty-hunit tasty-quickcheck tasty-th
|
||||
template-haskell text time transformers unix unordered-containers
|
||||
];
|
||||
benchmarkHaskellDepends = [
|
||||
base base16-bytestring bytestring containers criterion
|
||||
cryptohash-md5 cryptohash-sha1 cryptohash-sha256 cryptohash-sha512
|
||||
data-fix deepseq exceptions filepath hashing mtl
|
||||
optparse-applicative serialise template-haskell text time
|
||||
transformers unordered-containers
|
||||
];
|
||||
homepage = "https://github.com/haskell-nix/hnix#readme";
|
||||
description = "Haskell implementation of the Nix language";
|
||||
license = stdenv.lib.licenses.bsd3;
|
||||
}
|
|
@ -0,0 +1,28 @@
|
|||
{ mkDerivation, array, async, base, blaze-builder, bytestring
|
||||
, case-insensitive, containers, cookie, deepseq, directory
|
||||
, exceptions, filepath, ghc-prim, hspec, http-types, memory
|
||||
, mime-types, monad-control, network, network-uri, random, stdenv
|
||||
, stm, streaming-commons, text, time, transformers, zlib
|
||||
}:
|
||||
mkDerivation {
|
||||
pname = "http-client";
|
||||
version = "0.5.14";
|
||||
sha256 = "8e50409704021c51a8955b2d03bfec900ebc3e11fbaebf973f2e654d7bde3647";
|
||||
revision = "1";
|
||||
editedCabalFile = "0xw5ac4cvcd4hcwl7j12adi7sgffjryqhk0x992k3qs1cxyv5028";
|
||||
libraryHaskellDepends = [
|
||||
array base blaze-builder bytestring case-insensitive containers
|
||||
cookie deepseq exceptions filepath ghc-prim http-types memory
|
||||
mime-types network network-uri random stm streaming-commons text
|
||||
time transformers
|
||||
];
|
||||
testHaskellDepends = [
|
||||
async base blaze-builder bytestring case-insensitive containers
|
||||
deepseq directory hspec http-types monad-control network
|
||||
network-uri streaming-commons text time transformers zlib
|
||||
];
|
||||
doCheck = false;
|
||||
homepage = "https://github.com/snoyberg/http-client";
|
||||
description = "An HTTP client engine";
|
||||
license = stdenv.lib.licenses.mit;
|
||||
}
|
|
@ -0,0 +1,17 @@
|
|||
{ mkDerivation, array, base, bytestring, case-insensitive, doctest
|
||||
, hspec, QuickCheck, quickcheck-instances, stdenv, text
|
||||
}:
|
||||
mkDerivation {
|
||||
pname = "http-types";
|
||||
version = "0.12.3";
|
||||
sha256 = "4e8a4a66477459fa436a331c75e46857ec8026283df984d54f90576cd3024016";
|
||||
libraryHaskellDepends = [
|
||||
array base bytestring case-insensitive text
|
||||
];
|
||||
testHaskellDepends = [
|
||||
base bytestring doctest hspec QuickCheck quickcheck-instances text
|
||||
];
|
||||
homepage = "https://github.com/aristidb/http-types";
|
||||
description = "Generic HTTP types for Haskell (for both client and server code)";
|
||||
license = stdenv.lib.licenses.bsd3;
|
||||
}
|
|
@ -0,0 +1,39 @@
|
|||
{ mkDerivation, array, base, base-orphans, bifunctors, bytestring
|
||||
, Cabal, cabal-doctest, call-stack, comonad, containers
|
||||
, contravariant, criterion, deepseq, directory, distributive
|
||||
, doctest, exceptions, filepath, free, generic-deriving, ghc-prim
|
||||
, hashable, HUnit, kan-extensions, mtl, nats, parallel, profunctors
|
||||
, QuickCheck, reflection, semigroupoids, semigroups, simple-reflect
|
||||
, stdenv, tagged, template-haskell, test-framework
|
||||
, test-framework-hunit, test-framework-quickcheck2
|
||||
, test-framework-th, text, th-abstraction, transformers
|
||||
, transformers-compat, unordered-containers, vector, void
|
||||
}:
|
||||
mkDerivation {
|
||||
pname = "lens";
|
||||
version = "4.17";
|
||||
sha256 = "473664de541023bef44aa29105abbb1e35542e9254cdc846963183e0dd3f08cc";
|
||||
setupHaskellDepends = [ base Cabal cabal-doctest filepath ];
|
||||
libraryHaskellDepends = [
|
||||
array base base-orphans bifunctors bytestring call-stack comonad
|
||||
containers contravariant distributive exceptions filepath free
|
||||
ghc-prim hashable kan-extensions mtl parallel profunctors
|
||||
reflection semigroupoids semigroups tagged template-haskell text
|
||||
th-abstraction transformers transformers-compat
|
||||
unordered-containers vector void
|
||||
];
|
||||
testHaskellDepends = [
|
||||
base bytestring containers deepseq directory doctest filepath
|
||||
generic-deriving HUnit mtl nats parallel QuickCheck semigroups
|
||||
simple-reflect test-framework test-framework-hunit
|
||||
test-framework-quickcheck2 test-framework-th text transformers
|
||||
unordered-containers vector
|
||||
];
|
||||
benchmarkHaskellDepends = [
|
||||
base bytestring comonad containers criterion deepseq
|
||||
generic-deriving transformers unordered-containers vector
|
||||
];
|
||||
homepage = "http://github.com/ekmett/lens/";
|
||||
description = "Lenses, Folds and Traversals";
|
||||
license = stdenv.lib.licenses.bsd2;
|
||||
}
|
|
@ -0,0 +1,25 @@
|
|||
{ mkDerivation, base, bytestring, case-insensitive, containers
|
||||
, criterion, deepseq, hspec, hspec-expectations, mtl
|
||||
, parser-combinators, QuickCheck, scientific, stdenv, text
|
||||
, transformers, weigh
|
||||
}:
|
||||
mkDerivation {
|
||||
pname = "megaparsec";
|
||||
version = "7.0.4";
|
||||
sha256 = "325ba5cee8cdef91e351fb2db0b38562f8345b0bcdfed97045671357501de8c1";
|
||||
libraryHaskellDepends = [
|
||||
base bytestring case-insensitive containers deepseq mtl
|
||||
parser-combinators scientific text transformers
|
||||
];
|
||||
testHaskellDepends = [
|
||||
base bytestring case-insensitive containers hspec
|
||||
hspec-expectations mtl parser-combinators QuickCheck scientific
|
||||
text transformers
|
||||
];
|
||||
benchmarkHaskellDepends = [
|
||||
base containers criterion deepseq text weigh
|
||||
];
|
||||
homepage = "https://github.com/mrkkrp/megaparsec";
|
||||
description = "Monadic parser combinators";
|
||||
license = stdenv.lib.licenses.bsd2;
|
||||
}
|
|
@ -0,0 +1,15 @@
|
|||
{ mkDerivation, base, base-prelude, HTF, megaparsec, stdenv
|
||||
, template-haskell, text
|
||||
}:
|
||||
mkDerivation {
|
||||
pname = "neat-interpolation";
|
||||
version = "0.3.2.4";
|
||||
sha256 = "de7370d938ffd8c7b52d732f4f088387ed8216cf9767d818e99b7ec827931752";
|
||||
libraryHaskellDepends = [
|
||||
base base-prelude megaparsec template-haskell text
|
||||
];
|
||||
testHaskellDepends = [ base-prelude HTF ];
|
||||
homepage = "https://github.com/nikita-volkov/neat-interpolation";
|
||||
description = "A quasiquoter for neat and simple multiline text interpolation";
|
||||
license = stdenv.lib.licenses.mit;
|
||||
}
|
|
@ -0,0 +1,15 @@
|
|||
{ mkDerivation, ansi-wl-pprint, base, bytestring, process
|
||||
, QuickCheck, stdenv, transformers, transformers-compat
|
||||
}:
|
||||
mkDerivation {
|
||||
pname = "optparse-applicative";
|
||||
version = "0.14.3.0";
|
||||
sha256 = "72476302fe555a508917b2d7d6121c7b58ea5434cdc08aeb5d4b652e8f0e7663";
|
||||
libraryHaskellDepends = [
|
||||
ansi-wl-pprint base process transformers transformers-compat
|
||||
];
|
||||
testHaskellDepends = [ base bytestring QuickCheck ];
|
||||
homepage = "https://github.com/pcapriotti/optparse-applicative";
|
||||
description = "Utilities and combinators for parsing command line options";
|
||||
license = stdenv.lib.licenses.bsd3;
|
||||
}
|
|
@ -0,0 +1,10 @@
|
|||
{ mkDerivation, base, stdenv }:
|
||||
mkDerivation {
|
||||
pname = "parser-combinators";
|
||||
version = "1.0.1";
|
||||
sha256 = "edf5ab8fa69a04334baa8707252036563a8339a96a86956c90febe93830cea32";
|
||||
libraryHaskellDepends = [ base ];
|
||||
homepage = "https://github.com/mrkkrp/parser-combinators";
|
||||
description = "Lightweight package providing commonly useful parser combinators";
|
||||
license = stdenv.lib.licenses.bsd3;
|
||||
}
|
|
@ -0,0 +1,19 @@
|
|||
{ mkDerivation, array, base, filepath, ghc-prim, happy
|
||||
, haskell-lexer, pretty, stdenv, text
|
||||
}:
|
||||
mkDerivation {
|
||||
pname = "pretty-show";
|
||||
version = "1.9.5";
|
||||
sha256 = "b095bebb79951d2e25a543a591844fb638165672d7b95d325844611297ba423f";
|
||||
isLibrary = true;
|
||||
isExecutable = true;
|
||||
enableSeparateDataOutput = true;
|
||||
libraryHaskellDepends = [
|
||||
array base filepath ghc-prim haskell-lexer pretty text
|
||||
];
|
||||
libraryToolDepends = [ happy ];
|
||||
executableHaskellDepends = [ base ];
|
||||
homepage = "http://wiki.github.com/yav/pretty-show";
|
||||
description = "Tools for working with derived `Show` instances and generic inspection of values";
|
||||
license = stdenv.lib.licenses.mit;
|
||||
}
|
|
@ -0,0 +1,11 @@
|
|||
{ mkDerivation, base, containers, haskeline, mtl, process, stdenv
|
||||
}:
|
||||
mkDerivation {
|
||||
pname = "repline";
|
||||
version = "0.2.0.0";
|
||||
sha256 = "ecc72092d0340b896ee6bf96bf6645694dbcd33361725a2cd28c5ab5d60c02de";
|
||||
libraryHaskellDepends = [ base containers haskeline mtl process ];
|
||||
homepage = "https://github.com/sdiehl/repline";
|
||||
description = "Haskeline wrapper for GHCi-like REPL interfaces";
|
||||
license = stdenv.lib.licenses.mit;
|
||||
}
|
|
@ -0,0 +1,20 @@
|
|||
{ mkDerivation, base, base-orphans, bifunctors, Cabal
|
||||
, cabal-doctest, comonad, containers, contravariant, distributive
|
||||
, doctest, hashable, stdenv, tagged, template-haskell, transformers
|
||||
, transformers-compat, unordered-containers
|
||||
}:
|
||||
mkDerivation {
|
||||
pname = "semigroupoids";
|
||||
version = "5.3.2";
|
||||
sha256 = "61a8213df437ee96a20b1c6dec8b5c573e4e0f338eb2061739a67f471d6b9d05";
|
||||
setupHaskellDepends = [ base Cabal cabal-doctest ];
|
||||
libraryHaskellDepends = [
|
||||
base base-orphans bifunctors comonad containers contravariant
|
||||
distributive hashable tagged template-haskell transformers
|
||||
transformers-compat unordered-containers
|
||||
];
|
||||
testHaskellDepends = [ base doctest ];
|
||||
homepage = "http://github.com/ekmett/semigroupoids";
|
||||
description = "Semigroupoids: Category sans id";
|
||||
license = stdenv.lib.licenses.bsd3;
|
||||
}
|
|
@ -0,0 +1,29 @@
|
|||
{ mkDerivation, aeson, array, base, binary, bytestring, cborg
|
||||
, cereal, cereal-vector, containers, criterion, deepseq, directory
|
||||
, filepath, ghc-prim, half, hashable, pretty, primitive, QuickCheck
|
||||
, quickcheck-instances, semigroups, stdenv, store, tar, tasty
|
||||
, tasty-hunit, tasty-quickcheck, text, time, unordered-containers
|
||||
, vector, zlib
|
||||
}:
|
||||
mkDerivation {
|
||||
pname = "serialise";
|
||||
version = "0.2.1.0";
|
||||
sha256 = "043efc1130b4202f080c5b7d2c319098df032b060655d8193f1fcdbfa3f159a5";
|
||||
libraryHaskellDepends = [
|
||||
array base bytestring cborg containers ghc-prim half hashable
|
||||
primitive text time unordered-containers vector
|
||||
];
|
||||
testHaskellDepends = [
|
||||
base bytestring cborg containers directory filepath primitive
|
||||
QuickCheck quickcheck-instances tasty tasty-hunit tasty-quickcheck
|
||||
text time unordered-containers vector
|
||||
];
|
||||
benchmarkHaskellDepends = [
|
||||
aeson array base binary bytestring cborg cereal cereal-vector
|
||||
containers criterion deepseq directory filepath ghc-prim half
|
||||
pretty semigroups store tar text time vector zlib
|
||||
];
|
||||
homepage = "https://github.com/well-typed/cborg";
|
||||
description = "A binary serialisation library for Haskell values";
|
||||
license = stdenv.lib.licenses.bsd3;
|
||||
}
|
|
@ -0,0 +1,25 @@
|
|||
{ mkDerivation, aeson, base, base-compat, bifunctors, binary
|
||||
, containers, data-default-class, deepseq, hashable, keys, lens
|
||||
, mtl, QuickCheck, quickcheck-instances, semigroupoids, stdenv
|
||||
, tasty, tasty-quickcheck, transformers, transformers-compat
|
||||
, unordered-containers, vector, vector-instances
|
||||
}:
|
||||
mkDerivation {
|
||||
pname = "these";
|
||||
version = "0.7.6";
|
||||
sha256 = "9464b83d98e626360a8ad9836ba77e5201cd1e9c89b95b1b11a28ef3c23ac746";
|
||||
libraryHaskellDepends = [
|
||||
aeson base base-compat bifunctors binary containers
|
||||
data-default-class deepseq hashable keys lens mtl QuickCheck
|
||||
semigroupoids transformers transformers-compat unordered-containers
|
||||
vector vector-instances
|
||||
];
|
||||
testHaskellDepends = [
|
||||
aeson base base-compat bifunctors binary containers hashable lens
|
||||
QuickCheck quickcheck-instances tasty tasty-quickcheck transformers
|
||||
unordered-containers vector
|
||||
];
|
||||
homepage = "https://github.com/isomorphism/these";
|
||||
description = "An either-or-both data type & a generalized 'zip with padding' typeclass";
|
||||
license = stdenv.lib.licenses.bsd3;
|
||||
}
|
|
@ -0,0 +1,10 @@
|
|||
{ mkDerivation, base, old-locale, stdenv, time }:
|
||||
mkDerivation {
|
||||
pname = "time-locale-compat";
|
||||
version = "0.1.1.5";
|
||||
sha256 = "07ff1566de7d851423a843b2de385442319348c621d4f779b3d365ce91ac502c";
|
||||
libraryHaskellDepends = [ base old-locale time ];
|
||||
homepage = "https://github.com/khibino/haskell-time-locale-compat";
|
||||
description = "Compatibile module for time-format locale";
|
||||
license = stdenv.lib.licenses.bsd3;
|
||||
}
|
|
@ -0,0 +1,19 @@
|
|||
{ mkDerivation, base, base-orphans, deepseq, ghc-prim, HUnit
|
||||
, primitive, QuickCheck, random, stdenv, template-haskell
|
||||
, test-framework, test-framework-hunit, test-framework-quickcheck2
|
||||
, transformers
|
||||
}:
|
||||
mkDerivation {
|
||||
pname = "vector";
|
||||
version = "0.12.0.2";
|
||||
sha256 = "52e89dacaff10bedb8653181963cae928f9674a099bb706713dae83994bbc0f3";
|
||||
libraryHaskellDepends = [ base deepseq ghc-prim primitive ];
|
||||
testHaskellDepends = [
|
||||
base base-orphans HUnit primitive QuickCheck random
|
||||
template-haskell test-framework test-framework-hunit
|
||||
test-framework-quickcheck2 transformers
|
||||
];
|
||||
homepage = "https://github.com/haskell/vector";
|
||||
description = "Efficient Arrays";
|
||||
license = stdenv.lib.licenses.bsd3;
|
||||
}
|
|
@ -0,0 +1,304 @@
|
|||
let
|
||||
fetchNixpkgs = import ./nix/fetchNixpkgs.nix;
|
||||
|
||||
nixpkgs = fetchNixpkgs {
|
||||
rev = "1d4de0d552ae9aa66a5b8dee5fb0650a4372d148";
|
||||
|
||||
sha256 = "09qx58dp1kbj7cpzp8ahbqfbbab1frb12sh1qng87rybcaz0dz01";
|
||||
|
||||
outputSha256 = "0xpqc1fhkvvv5dv1zmas2j1q27mi7j7dgyjcdh82mlgl1q63i660";
|
||||
};
|
||||
|
||||
mass = function: names: haskellPackagesNew: haskellPackagesOld:
|
||||
let
|
||||
toNameValue = name: {
|
||||
inherit name;
|
||||
|
||||
value = function haskellPackagesOld."${name}";
|
||||
};
|
||||
|
||||
in
|
||||
builtins.listToAttrs (map toNameValue names);
|
||||
|
||||
config = {
|
||||
packageOverrides = pkgs: {
|
||||
haskellPackages = pkgs.haskellPackages.override (old: {
|
||||
overrides =
|
||||
let
|
||||
dontCheck =
|
||||
mass pkgs.haskell.lib.dontCheck [
|
||||
"adjunctions"
|
||||
"base-orphans"
|
||||
"base64-bytestring"
|
||||
"cereal"
|
||||
"blaze-builder"
|
||||
"neat-interpolation"
|
||||
"pureMD5"
|
||||
"pem"
|
||||
"lens"
|
||||
"th-orphans"
|
||||
"mockery"
|
||||
"megaparsec"
|
||||
"lens-family-th"
|
||||
"network-uri"
|
||||
"invariant"
|
||||
"interpolate"
|
||||
"http-types"
|
||||
"parsers"
|
||||
"dhall"
|
||||
"aeson"
|
||||
"half"
|
||||
"generic-deriving"
|
||||
"distributive"
|
||||
"deriving-compat"
|
||||
"monad-control"
|
||||
"logging-facade"
|
||||
"bifunctors"
|
||||
"exceptions"
|
||||
"cborg-json"
|
||||
"cryptohash-sha512"
|
||||
"Diff"
|
||||
"hashable"
|
||||
"hnix"
|
||||
"hnix-store-core"
|
||||
"optparse-generic"
|
||||
"serialise"
|
||||
"SHA"
|
||||
"these"
|
||||
"unordered-containers"
|
||||
"vector"
|
||||
];
|
||||
|
||||
extension = haskellPackagesNew: haskellPackagesOld: {
|
||||
dhall-nix =
|
||||
pkgs.haskell.lib.failOnAllWarnings
|
||||
(pkgs.haskell.lib.justStaticExecutables
|
||||
haskellPackagesOld.dhall-nix
|
||||
);
|
||||
};
|
||||
|
||||
in
|
||||
pkgs.lib.fold
|
||||
pkgs.lib.composeExtensions
|
||||
(old.overrides or (_: _: {}))
|
||||
[ (pkgs.haskell.lib.packagesFromDirectory { directory = ./nix; })
|
||||
dontCheck
|
||||
extension
|
||||
];
|
||||
}
|
||||
);
|
||||
};
|
||||
};
|
||||
|
||||
pkgs =
|
||||
import nixpkgs { inherit config; };
|
||||
|
||||
inherit (pkgs) dhallToNix;
|
||||
|
||||
in
|
||||
{ dhall-nix = pkgs.haskellPackages.dhall-nix;
|
||||
|
||||
shell = pkgs.haskellPackages.dhall-nix.env;
|
||||
|
||||
# Test that various Dhall to Nix conversions work
|
||||
tests =
|
||||
let
|
||||
testConst = dhallToNix "Type";
|
||||
testLam = dhallToNix "λ(x : Bool) → x";
|
||||
testPi = dhallToNix "Bool → Bool";
|
||||
testApp = dhallToNix "λ(f : Bool → Bool) → λ(x : Bool) → f x";
|
||||
testLet = dhallToNix "λ(b : Bool) → let x = b in x";
|
||||
testAnnot = dhallToNix "True : Bool";
|
||||
testBool = dhallToNix "Bool";
|
||||
testBoolLit = dhallToNix "True";
|
||||
testBoolAnd = dhallToNix "λ(l : Bool) → λ(r : Bool) → l && r";
|
||||
testBoolOr = dhallToNix "λ(l : Bool) → λ(r : Bool) → l || r";
|
||||
testBoolEQ = dhallToNix "λ(l : Bool) → λ(r : Bool) → l == r";
|
||||
testBoolNE = dhallToNix "λ(l : Bool) → λ(r : Bool) → l != r";
|
||||
testBoolIf = dhallToNix "λ(x : Bool) → if x then True else False";
|
||||
testNatural = dhallToNix "Natural";
|
||||
testNaturalLit = dhallToNix "123";
|
||||
testNaturalFold = dhallToNix ''
|
||||
λ(x : Natural)
|
||||
→ Natural/fold x Natural (λ(n : Natural) → 2 + n) 0
|
||||
'';
|
||||
testNaturalBuild = dhallToNix ''
|
||||
λ(b : Bool)
|
||||
→ Natural/build
|
||||
( λ(natural : Type)
|
||||
→ λ(succ : natural → natural)
|
||||
→ λ(zero : natural)
|
||||
→ if b then succ zero else zero
|
||||
)
|
||||
'';
|
||||
testNaturalIsZero = dhallToNix "Natural/isZero";
|
||||
testNaturalEven = dhallToNix "Natural/even";
|
||||
testNaturalOdd = dhallToNix "Natural/odd";
|
||||
testNaturalToInteger = dhallToNix "Natural/toInteger";
|
||||
testNaturalShow = dhallToNix "Natural/show";
|
||||
testNaturalPlus = dhallToNix "λ(x : Natural) → λ(y : Natural) → x + y";
|
||||
testNaturalTimes = dhallToNix "λ(x : Natural) → λ(y : Natural) → x * y";
|
||||
testInteger = dhallToNix "Integer";
|
||||
testIntegerLit = dhallToNix "+123";
|
||||
testIntegerShow = dhallToNix "Integer/show";
|
||||
testDouble = dhallToNix "Double";
|
||||
testTextLit = dhallToNix ''"ABC"'';
|
||||
testInterpolation = dhallToNix ''λ(x : Text) → "ABC''${x}GHI"'' "DEF";
|
||||
testTextAppend = dhallToNix "λ(x : Text) → λ(y : Text) → x ++ y";
|
||||
testList = dhallToNix "List Natural";
|
||||
testListLit = dhallToNix "[1, 2, 3] : List Natural";
|
||||
testListAppend = dhallToNix ''
|
||||
λ(xs : List Natural) → λ(ys : List Natural) → xs # ys
|
||||
'';
|
||||
testListBuild = dhallToNix ''
|
||||
λ(b : Bool)
|
||||
→ List/build
|
||||
Natural
|
||||
( λ(list : Type)
|
||||
→ λ(cons : Natural → list → list)
|
||||
→ λ(nil : list)
|
||||
→ if b then cons 1 (cons 2 (cons 3 nil)) else nil
|
||||
)
|
||||
'';
|
||||
testListFold = dhallToNix ''
|
||||
List/fold
|
||||
Natural
|
||||
([1, 2, 3] : List Natural)
|
||||
Natural
|
||||
'';
|
||||
testListLength = dhallToNix "List/length Natural";
|
||||
testListHead = dhallToNix "List/head Natural";
|
||||
testListLast = dhallToNix "List/last Natural";
|
||||
testListIndexed = dhallToNix "List/indexed Natural";
|
||||
testListReverse = dhallToNix "List/reverse Natural";
|
||||
testOptional = dhallToNix "Optional";
|
||||
testOptionalLit = dhallToNix ''
|
||||
λ(b : Bool)
|
||||
→ if b
|
||||
then ([0] : Optional Natural)
|
||||
else ([] : Optional Natural)
|
||||
'';
|
||||
testOptionalFold = dhallToNix ''
|
||||
Optional/fold
|
||||
Natural
|
||||
([1] : Optional Natural)
|
||||
Natural
|
||||
'';
|
||||
testOptionalBuild = dhallToNix ''
|
||||
λ(b : Bool)
|
||||
→ Optional/build
|
||||
Natural
|
||||
( λ(optional : Type)
|
||||
→ λ(just : Natural → optional)
|
||||
→ λ(nothing : optional)
|
||||
→ if b then just 1 else nothing
|
||||
)
|
||||
'';
|
||||
testNone = dhallToNix "None Natural";
|
||||
testSome = dhallToNix "Some 4";
|
||||
testRecord = dhallToNix "{}";
|
||||
testRecordLit = dhallToNix "{ foo = 1, bar = True}";
|
||||
testUnion = dhallToNix "< Left : Natural | Right : Bool >";
|
||||
testUnionLit = dhallToNix "< Left = 2 | Right : Bool >";
|
||||
testCombine = dhallToNix ''
|
||||
λ(x : { foo : { bar : Text } })
|
||||
→ λ(y : { foo : { baz : Bool } })
|
||||
→ x ∧ y
|
||||
'';
|
||||
testCombineTypes = dhallToNix ''
|
||||
{ foo : Text } ⩓ { bar : Bool, baz : Natural }
|
||||
'';
|
||||
testMerge = dhallToNix ''
|
||||
λ(r : < Left : Natural | Right : Bool >)
|
||||
→ merge
|
||||
{ Left = Natural/isZero, Right = λ(b : Bool) → b }
|
||||
r : Bool
|
||||
'';
|
||||
testField = dhallToNix "λ(r : { foo : Bool, bar : Text }) → r.foo";
|
||||
testProject = dhallToNix ''
|
||||
λ(r : { foo : Bool, bar : Text, baz : Natural }) → r.{ foo, bar }
|
||||
'';
|
||||
in
|
||||
assert (testConst == {});
|
||||
assert (testLam true == true);
|
||||
assert (testPi == {});
|
||||
assert (testApp (b : b) true == true);
|
||||
assert (testLet true == true);
|
||||
assert (testAnnot == true);
|
||||
assert (testBool == {});
|
||||
assert (testBoolLit == true);
|
||||
assert (testBoolAnd true false == false);
|
||||
assert (testBoolOr true false == true);
|
||||
assert (testBoolEQ true false == false);
|
||||
assert (testBoolNE true false == true);
|
||||
assert (testBoolIf true == true);
|
||||
assert (testNatural == {});
|
||||
assert (testNaturalLit == 123);
|
||||
assert (testNaturalFold 123 == 246);
|
||||
assert (testNaturalBuild true == 1);
|
||||
assert (testNaturalBuild false == 0);
|
||||
assert (testNaturalIsZero 0 == true);
|
||||
assert (testNaturalIsZero 3 == false);
|
||||
assert (testNaturalEven 2 == true);
|
||||
assert (testNaturalEven 3 == false);
|
||||
assert (testNaturalOdd 2 == false);
|
||||
assert (testNaturalToInteger 2 == 2);
|
||||
assert (testNaturalShow 2 == "2");
|
||||
assert (testNaturalOdd 3 == true);
|
||||
assert (testNaturalPlus 2 3 == 5);
|
||||
assert (testNaturalTimes 2 3 == 6);
|
||||
assert (testInteger == {});
|
||||
assert (testIntegerLit == 123);
|
||||
assert (testIntegerShow 2 == "+2");
|
||||
assert (testIntegerShow (-3) == "-3");
|
||||
assert (testDouble == {});
|
||||
assert (testTextLit == "ABC");
|
||||
assert (testInterpolation == "ABCDEFGHI");
|
||||
assert (testTextAppend "ABC" "DEF" == "ABCDEF");
|
||||
assert (testList == {});
|
||||
assert (testListLit == [1 2 3]);
|
||||
assert (testListAppend [1 2 3] [4 5 6] == [1 2 3 4 5 6]);
|
||||
assert (testListBuild false == []);
|
||||
assert (testListBuild true == [1 2 3]);
|
||||
assert (testListFold (x : y: x + y) 0 == 6);
|
||||
assert (testListLength [1 2 3] == 3);
|
||||
assert (testListLength [] == 0);
|
||||
assert (testListHead [1 2 3] == 1);
|
||||
assert (testListHead [] == null);
|
||||
assert (testListLast [1 2 3] == 3);
|
||||
assert (testListLast [] == null);
|
||||
assert (testListIndexed [2 3 5] == [
|
||||
{ index = 0; value = 2; }
|
||||
{ index = 1; value = 3; }
|
||||
{ index = 2; value = 5; }
|
||||
]);
|
||||
assert (testListReverse [1 2 3] == [3 2 1]);
|
||||
assert (testOptional {} == {});
|
||||
assert (testOptionalLit true == 0);
|
||||
assert (testOptionalLit false == null);
|
||||
assert (testOptionalFold (n : n) 0 == 1);
|
||||
assert (testOptionalBuild true == 1);
|
||||
assert (testOptionalBuild false == null);
|
||||
assert (testRecord == {});
|
||||
assert (testRecordLit == { foo = 1; bar = true; });
|
||||
assert (testUnion == {});
|
||||
assert (testUnionLit { Left = n : n == 0; Right = b : b; } == false);
|
||||
assert ((testCombine { foo.baz = true; } { foo.bar = "ABC"; }) == {
|
||||
foo = {
|
||||
baz = true;
|
||||
bar = "ABC";
|
||||
};
|
||||
});
|
||||
assert (testCombineTypes == {});
|
||||
assert (testMerge ({ Left, Right }: Left 2) == false);
|
||||
assert (testField { foo = true; bar = "ABC"; } == true);
|
||||
assert (testProject { foo = true; bar = "ABC"; baz = 1; } == {
|
||||
foo = true;
|
||||
bar = "ABC";
|
||||
});
|
||||
pkgs.stdenv.mkDerivation {
|
||||
name = "tests-pass";
|
||||
|
||||
buildCommand = "touch $out";
|
||||
};
|
||||
}
|
|
@ -0,0 +1 @@
|
|||
(import ./release.nix).shell
|
|
@ -0,0 +1,500 @@
|
|||
{-# LANGUAGE DeriveDataTypeable #-}
|
||||
{-# LANGUAGE OverloadedStrings #-}
|
||||
{-# LANGUAGE OverloadedLists #-}
|
||||
{-# LANGUAGE QuasiQuotes #-}
|
||||
{-# LANGUAGE TypeFamilies #-}
|
||||
|
||||
{-| This library only exports a single `dhallToNix` function for translating a
|
||||
Dhall syntax tree to a Nix syntax tree for the @hnix@ library
|
||||
|
||||
See the @dhall@ package if you would like to transform Dhall source code
|
||||
into a Dhall syntax tree. Similarly, see the @hnix@ package if you would
|
||||
like to translate a Nix syntax tree into Nix source code.
|
||||
|
||||
This package also provides a @dhall-to-nix@ executable which you can use to
|
||||
compile Dhall source code directly to Nix source code for your convenience.
|
||||
|
||||
Any Dhall expression can be converted into an equivalent Nix expression.
|
||||
For example, Dhall records can be converted into Nix records:
|
||||
|
||||
> $ dhall-to-nix <<< "{ foo = 1, bar = True }"
|
||||
> { bar = true; foo = 1; }
|
||||
|
||||
... and you can also convert Dhall functions to Nix functions, too:
|
||||
|
||||
> $ dhall-to-nix <<< "λ(x : Bool) → x == False"
|
||||
> x: x == false
|
||||
|
||||
Many Dhall expressions have a straightforward translation to Nix expressions
|
||||
but there are some translations that are not as obvious. The following
|
||||
section documents these trickier conversions:
|
||||
|
||||
First, all Dhall types translate to an empty record:
|
||||
|
||||
> $ dhall-to-nix <<< "Integer"
|
||||
> {}
|
||||
|
||||
Polymorphic Dhall functions translate to Nix functions that ignore their
|
||||
type argument:
|
||||
|
||||
> $ dhall-to-nix <<< "List/head"
|
||||
> t: xs: if xs == []
|
||||
> then null
|
||||
> else builtins.head xs
|
||||
|
||||
`Optional` values translate to @null@ if missing or the unwrapped value if
|
||||
present:
|
||||
|
||||
> $ dhall-to-nix <<< "[] : Optional Integer"
|
||||
> null
|
||||
|
||||
> $ dhall-to-nix <<< "[1] : Optional Integer"
|
||||
> 1
|
||||
|
||||
Unions are Church-encoded:
|
||||
|
||||
> $ dhall-to-nix <<< "< Left = True | Right : Natural >"
|
||||
> { Left, Right }: Left true
|
||||
|
||||
Also, all Dhall expressions are normalized before translation to Nix:
|
||||
|
||||
> $ dhall-to-nix <<< "True == False"
|
||||
> false
|
||||
|
||||
You can use the @dhall-to-nix@ executable within Nix to assemble Nix
|
||||
expressions from Dhall expressions using the following @dhallToNix@ utility
|
||||
function:
|
||||
|
||||
> dhallToNix = code :
|
||||
> let
|
||||
> file = builtins.toFile "dhall-expr" code;
|
||||
>
|
||||
> drv = pkgs.stdenv.mkDerivation {
|
||||
> name = "dhall-expr-as-nix";
|
||||
>
|
||||
> buildCommand = ''
|
||||
> dhall-to-nix <<< "${file}" > $out
|
||||
> '';
|
||||
>
|
||||
> buildInputs = [ pkgs.haskellPackages.dhall-nix ];
|
||||
> };
|
||||
> in
|
||||
> import "${drv}";
|
||||
-}
|
||||
|
||||
module Dhall.Nix (
|
||||
-- * Dhall to Nix
|
||||
dhallToNix
|
||||
|
||||
-- * Exceptions
|
||||
, CompileError(..)
|
||||
) where
|
||||
|
||||
import Control.Applicative (empty)
|
||||
import Control.Exception (Exception)
|
||||
import Data.Foldable (toList)
|
||||
import Data.Fix (Fix(..))
|
||||
import Data.Traversable (for)
|
||||
import Data.Typeable (Typeable)
|
||||
import Dhall.Core (Chunks(..), Const(..), Expr(..), Var(..))
|
||||
import Dhall.TypeCheck (X(..))
|
||||
import Nix.Atoms (NAtom(..))
|
||||
import Nix.Expr
|
||||
( Antiquoted(..)
|
||||
, Binding(..)
|
||||
, NBinaryOp(..)
|
||||
, NExprF(..)
|
||||
, NKeyName(..)
|
||||
, NString(..)
|
||||
, Params(..)
|
||||
, (@@)
|
||||
, (==>)
|
||||
, ($+)
|
||||
)
|
||||
|
||||
import qualified Data.Text
|
||||
import qualified Dhall.Core
|
||||
import qualified Dhall.Map
|
||||
import qualified NeatInterpolation
|
||||
import qualified Nix
|
||||
|
||||
{-| This is the exception type for all possible errors that might arise when
|
||||
translating the Dhall syntax tree to the Nix syntax tree
|
||||
-}
|
||||
data CompileError
|
||||
= CannotReferenceShadowedVariable Var
|
||||
-- ^ Nix does not provide a way to reference a shadowed variable
|
||||
deriving (Typeable)
|
||||
|
||||
instance Show CompileError where
|
||||
show (CannotReferenceShadowedVariable v) =
|
||||
Data.Text.unpack [NeatInterpolation.text|
|
||||
$_ERROR: Cannot reference shadowed variable
|
||||
|
||||
Explanation: Whenever you introduce two variables of the same name, the latter
|
||||
variable takes precedence:
|
||||
|
||||
|
||||
This ❰x❱ ...
|
||||
⇩
|
||||
┌───────────────────────────────┐
|
||||
│ λ(x : Text) → λ(x : Text) → x │
|
||||
└───────────────────────────────┘
|
||||
⇧
|
||||
... refers to this ❰x❱
|
||||
|
||||
|
||||
The former variable is "shadowed":
|
||||
|
||||
|
||||
┌───────────────────────────────┐
|
||||
│ λ(x : Text) → λ(x : Text) → x │
|
||||
└───────────────────────────────┘
|
||||
⇧
|
||||
This ❰x❱ is shadowed
|
||||
|
||||
|
||||
... and Dhall lets you reference shadowed variables using the ❰@❱ notation:
|
||||
|
||||
|
||||
This ❰x❱ ...
|
||||
⇩
|
||||
┌─────────────────────────────────┐
|
||||
│ λ(x : Text) → λ(x : Text) → x@1 │
|
||||
└─────────────────────────────────┘
|
||||
⇧
|
||||
... now refers to this ❰x❱
|
||||
|
||||
|
||||
However, the Nix language does not let you reference shadowed variables and
|
||||
there is nothing analogous to ❰@❱ in Nix
|
||||
|
||||
Your code contains the following expression:
|
||||
|
||||
↳ $txt
|
||||
|
||||
... which references a shadowed variable and therefore cannot be translated to
|
||||
Nix
|
||||
|]
|
||||
where
|
||||
txt = Dhall.Core.pretty v
|
||||
|
||||
_ERROR :: Data.Text.Text
|
||||
_ERROR = "\ESC[1;31mError\ESC[0m"
|
||||
|
||||
instance Exception CompileError
|
||||
|
||||
{-| Convert a Dhall expression to the equivalent Nix expression
|
||||
|
||||
>>> :set -XOverloadedStrings
|
||||
>>> dhallToNix (Lam "x" Natural (Lam "y" Natural (NaturalPlus "x" "y")))
|
||||
Right (NAbs (Param "x") (NAbs (Param "y") (NBinary NPlus (NSym "x") (NSym "y"))))
|
||||
>>> fmap Nix.Pretty.prettyNix it
|
||||
Right x: y: x + y
|
||||
|
||||
Precondition: You must first type-check the Dhall expression before passing
|
||||
the expression to `dhallToNix`
|
||||
-}
|
||||
dhallToNix :: Expr s X -> Either CompileError (Fix NExprF)
|
||||
dhallToNix e = loop (Dhall.Core.normalize e)
|
||||
where
|
||||
loop (Const _) = return (Fix (NSet []))
|
||||
loop (Var (V a 0)) = return (Fix (NSym a))
|
||||
loop (Var a ) = Left (CannotReferenceShadowedVariable a)
|
||||
loop (Lam a _ c) = do
|
||||
c' <- loop c
|
||||
return (Fix (NAbs (Param a) c'))
|
||||
loop (Pi _ _ _) = return (Fix (NSet []))
|
||||
-- None needs a type to convert to an Optional
|
||||
loop (App None _) = do
|
||||
return (Fix (NConstant NNull))
|
||||
loop (App a b) = do
|
||||
a' <- loop a
|
||||
b' <- loop b
|
||||
return (Fix (NBinary NApp a' b'))
|
||||
loop (Let as b) = do
|
||||
as' <- for as $ \a -> do
|
||||
val <- loop $ Dhall.Core.value a
|
||||
pure $ NamedVar [StaticKey $ Dhall.Core.variable a] val Nix.nullPos
|
||||
b' <- loop b
|
||||
return (Fix (NLet (toList as') b'))
|
||||
loop (Annot a _) = loop a
|
||||
loop Bool = return (Fix (NSet []))
|
||||
loop (BoolLit b) = return (Fix (NConstant (NBool b)))
|
||||
loop (BoolAnd a b) = do
|
||||
a' <- loop a
|
||||
b' <- loop b
|
||||
return (Fix (NBinary NAnd a' b'))
|
||||
loop (BoolOr a b) = do
|
||||
a' <- loop a
|
||||
b' <- loop b
|
||||
return (Fix (NBinary NOr a' b'))
|
||||
loop (BoolEQ a b) = do
|
||||
a' <- loop a
|
||||
b' <- loop b
|
||||
return (Fix (NBinary NEq a' b'))
|
||||
loop (BoolNE a b) = do
|
||||
a' <- loop a
|
||||
b' <- loop b
|
||||
return (Fix (NBinary NNEq a' b'))
|
||||
loop (BoolIf a b c) = do
|
||||
a' <- loop a
|
||||
b' <- loop b
|
||||
c' <- loop c
|
||||
return (Fix (NIf a' b' c'))
|
||||
loop Natural = return (Fix (NSet []))
|
||||
loop (NaturalLit n) = return (Fix (NConstant (NInt (fromIntegral n))))
|
||||
loop NaturalFold = do
|
||||
let e0 = Fix (NBinary NMinus "n" (Fix (NConstant (NInt 1))))
|
||||
let e1 = Fix (NBinary NApp (Fix (NBinary NApp (Fix (NBinary NApp "naturalFold" e0)) "t")) "succ")
|
||||
let e2 = Fix (NBinary NApp "succ" (Fix (NBinary NApp e1 "zero")))
|
||||
let e3 = Fix (NBinary NLte "n" (Fix (NConstant (NInt 0))))
|
||||
let e4 = Fix (NAbs "succ" (Fix (NAbs "zero" (Fix (NIf e3 "zero" e2)))))
|
||||
let e5 = Fix (NAbs "n" (Fix (NAbs "t" e4)))
|
||||
return (Fix (NLet [NamedVar ["naturalFold"] e5 Nix.nullPos] "naturalFold"))
|
||||
loop NaturalBuild = do
|
||||
let e0 = Fix (NBinary NPlus "n" (Fix (NConstant (NInt 1))))
|
||||
let e1 = Fix (NBinary NApp (Fix (NBinary NApp "k" (Fix (NSet [])))) (Fix (NAbs "n" e0)))
|
||||
return (Fix (NAbs "k" (Fix (NBinary NApp e1 (Fix (NConstant (NInt 0)))))))
|
||||
loop NaturalIsZero = do
|
||||
let e0 = Fix (NBinary NEq "n" (Fix (NConstant (NInt 0))))
|
||||
return (Fix (NAbs "n" e0))
|
||||
loop NaturalEven = do
|
||||
let e0 = Fix (NBinary NMinus "n" (Fix (NConstant (NInt 2))))
|
||||
let e1 = Fix (NBinary NApp "naturalEven" e0)
|
||||
let e2 = Fix (NBinary NNEq "n" (Fix (NConstant (NInt 1))))
|
||||
let e3 = Fix (NBinary NEq "n" (Fix (NConstant (NInt 0))))
|
||||
let e4 = Fix (NBinary NOr e3 (Fix (NBinary NAnd e2 e1)))
|
||||
let e5 = NamedVar ["naturalEven"] (Fix (NAbs "n" e4)) Nix.nullPos
|
||||
let e6 = Fix (NBinary NMinus (Fix (NConstant (NInt 0))) "n")
|
||||
let e7 = Fix (NBinary NLte "n" (Fix (NConstant (NInt 0))))
|
||||
let e8 = Fix (NAbs "n" (Fix (NBinary NApp "naturalEven" (Fix (NIf e7 e6 "n")))))
|
||||
return (Fix (NLet [e5] e8))
|
||||
loop NaturalOdd = do
|
||||
let e0 = Fix (NBinary NMinus "n" (Fix (NConstant (NInt 2))))
|
||||
let e1 = Fix (NBinary NApp "naturalOdd" e0)
|
||||
let e2 = Fix (NBinary NNEq "n" (Fix (NConstant (NInt 0))))
|
||||
let e3 = Fix (NBinary NEq "n" (Fix (NConstant (NInt 1))))
|
||||
let e4 = Fix (NBinary NOr e3 (Fix (NBinary NAnd e2 e1)))
|
||||
let e5 = NamedVar ["naturalOdd"] (Fix (NAbs "n" e4)) Nix.nullPos
|
||||
let e6 = Fix (NBinary NMinus (Fix (NConstant (NInt 0))) "n")
|
||||
let e7 = Fix (NBinary NLte "n" (Fix (NConstant (NInt 0))))
|
||||
let e8 = Fix (NAbs "n" (Fix (NBinary NApp "naturalOdd" (Fix (NIf e7 e6 "n")))))
|
||||
return (Fix (NLet [e5] e8))
|
||||
loop NaturalShow = do
|
||||
return "toString"
|
||||
loop NaturalToInteger = do
|
||||
return (Fix (NAbs "n" "n"))
|
||||
loop (NaturalPlus a b) = do
|
||||
a' <- loop a
|
||||
b' <- loop b
|
||||
return (Fix (NBinary NPlus a' b'))
|
||||
loop (NaturalTimes a b) = do
|
||||
a' <- loop a
|
||||
b' <- loop b
|
||||
return (Fix (NBinary NMult a' b'))
|
||||
loop Integer = return (Fix (NSet []))
|
||||
loop (IntegerLit n) = return (Fix (NConstant (NInt (fromIntegral n))))
|
||||
loop IntegerShow = do
|
||||
let e0 = Fix (NBinary NApp "toString" "x")
|
||||
let e1 = Fix (NBinary NPlus (Fix (NStr "+")) e0)
|
||||
let e2 = Fix (NBinary NLte (Fix (NConstant (NInt 0))) "x")
|
||||
let e3 = Fix (NAbs "x" (Fix (NIf e2 e1 e0)))
|
||||
return e3
|
||||
loop IntegerToDouble = do
|
||||
return (Fix (NAbs "x" "x"))
|
||||
loop Double = return (Fix (NSet []))
|
||||
loop (DoubleLit n) = return (Fix (NConstant (NFloat (realToFrac n))))
|
||||
loop DoubleShow = do
|
||||
return "toString"
|
||||
loop Text = return (Fix (NSet []))
|
||||
loop (TextLit (Chunks abs_ c)) = do
|
||||
let process (a, b) = do
|
||||
b' <- loop b
|
||||
return [Plain a, Antiquoted b']
|
||||
abs' <- mapM process abs_
|
||||
|
||||
let chunks = concat abs' ++ [Plain c]
|
||||
return (Fix (NStr (DoubleQuoted chunks)))
|
||||
loop (TextAppend a b) = do
|
||||
a' <- loop a
|
||||
b' <- loop b
|
||||
return (Fix (NBinary NPlus a' b'))
|
||||
loop TextShow = do
|
||||
let from =
|
||||
Nix.mkList
|
||||
[ Nix.mkStr "\""
|
||||
, Nix.mkStr "$"
|
||||
, Nix.mkStr "\\"
|
||||
-- Nix doesn't support \b and \f
|
||||
-- , Nix.mkStr "\b"
|
||||
-- , Nix.mkStr "\f"
|
||||
, Nix.mkStr "\n"
|
||||
, Nix.mkStr "\r"
|
||||
, Nix.mkStr "\t"
|
||||
]
|
||||
|
||||
let to =
|
||||
Nix.mkList
|
||||
[ Nix.mkStr "\\\""
|
||||
, Nix.mkStr "\\u0024"
|
||||
, Nix.mkStr "\\\\"
|
||||
-- , Nix.mkStr "\\b"
|
||||
-- , Nix.mkStr "\\f"
|
||||
, Nix.mkStr "\\n"
|
||||
, Nix.mkStr "\\r"
|
||||
, Nix.mkStr "\\t"
|
||||
]
|
||||
|
||||
let replaced = "builtins.replaceStrings" @@ from @@ to @@ "t"
|
||||
|
||||
let quoted = Nix.mkStr "\"" $+ replaced $+ Nix.mkStr "\""
|
||||
|
||||
return ("t" ==> quoted)
|
||||
loop List = return (Fix (NAbs "t" (Fix (NSet []))))
|
||||
loop (ListAppend a b) = do
|
||||
a' <- loop a
|
||||
b' <- loop b
|
||||
return (Fix (NBinary NConcat a' b'))
|
||||
loop (ListLit _ bs) = do
|
||||
bs' <- mapM loop (toList bs)
|
||||
return (Fix (NList bs'))
|
||||
loop ListBuild = do
|
||||
let e0 = Fix (NBinary NApp "k" (Fix (NSet [])))
|
||||
let e1 = Fix (NBinary NConcat (Fix (NList ["x"])) "xs")
|
||||
let e2 = Fix (NBinary NApp e0 (Fix (NAbs "x" (Fix (NAbs "xs" e1)))))
|
||||
let e3 = Fix (NAbs "k" (Fix (NBinary NApp e2 (Fix (NList [])))))
|
||||
return (Fix (NAbs "t" e3))
|
||||
loop ListFold = do
|
||||
let e0 = Fix (NBinary NApp "f" (Fix (NBinary NApp (Fix (NBinary NApp "cons" "y")) "ys")))
|
||||
let e1 = Fix (NAbs "f" (Fix (NAbs "y" (Fix (NAbs "ys" e0)))))
|
||||
let e2 = Fix (NBinary NApp "builtins.foldl'" e1)
|
||||
let e3 = Fix (NBinary NApp (Fix (NBinary NApp e2 (Fix (NAbs "ys" "ys")))) "xs")
|
||||
let e4 = Fix (NAbs "xs" (Fix (NAbs "t" (Fix (NAbs "cons" e3)))))
|
||||
return (Fix (NAbs "t" e4))
|
||||
loop ListLength = return (Fix (NAbs "t" "builtins.length"))
|
||||
loop ListHead = do
|
||||
let e0 = Fix (NBinary NApp "builtins.head" "xs")
|
||||
let e1 = Fix (NBinary NEq "xs" (Fix (NList [])))
|
||||
let e2 = Fix (NAbs "xs" (Fix (NIf e1 (Fix (NConstant NNull)) e0)))
|
||||
return (Fix (NAbs "t" e2))
|
||||
loop ListLast = do
|
||||
let e0 = Fix (NBinary NApp "builtins.length" "xs")
|
||||
let e1 = Fix (NBinary NMinus e0 (Fix (NConstant (NInt 1))))
|
||||
let e2 = Fix (NBinary NApp (Fix (NBinary NApp "builtins.elemAt" "xs")) e1)
|
||||
let e3 = Fix (NBinary NEq "xs" (Fix (NList [])))
|
||||
let e4 = Fix (NAbs "xs" (Fix (NIf e3 (Fix (NConstant NNull)) e2)))
|
||||
return (Fix (NAbs "t" e4))
|
||||
loop ListIndexed = do
|
||||
let e0 = Fix (NBinary NApp "builtins.length" "xs")
|
||||
let e1 = Fix (NBinary NApp (Fix (NBinary NApp "builtins.elemAt" "xs")) "i")
|
||||
let e2 =
|
||||
[ NamedVar ["index"] "i" Nix.nullPos
|
||||
, NamedVar ["value"] e1 Nix.nullPos
|
||||
]
|
||||
let e3 = Fix (NBinary NApp "builtins.genList" (Fix (NAbs "i" (Fix (NSet e2)))))
|
||||
return (Fix (NAbs "t" (Fix (NAbs "xs" (Fix (NBinary NApp e3 e0))))))
|
||||
loop ListReverse = do
|
||||
let e0 = Fix (NBinary NMinus "n" "i")
|
||||
let e1 = Fix (NBinary NMinus e0 (Fix (NConstant (NInt 1))))
|
||||
let e2 = Fix (NBinary NApp (Fix (NBinary NApp "builtins.elemAt" "xs")) e1)
|
||||
let e3 = Fix (NBinary NApp "builtins.genList" (Fix (NAbs "i" e2)))
|
||||
let e4 = Fix (NBinary NApp e3 "n")
|
||||
let e5 = Fix (NBinary NApp "builtins.length" "xs")
|
||||
let e6 = Fix (NAbs "xs" (Fix (NLet [NamedVar ["n"] e5 Nix.nullPos] e4)))
|
||||
return (Fix (NAbs "t" e6))
|
||||
loop Optional = return (Fix (NAbs "t" (Fix (NSet []))))
|
||||
loop (OptionalLit _ b) =
|
||||
case b of
|
||||
Nothing -> return (Fix (NConstant NNull))
|
||||
Just c -> loop c
|
||||
loop (Some a) = loop a
|
||||
loop None = return (Fix (NConstant NNull))
|
||||
loop OptionalFold = do
|
||||
let e0 = Fix (NBinary NEq "x" (Fix (NConstant NNull)))
|
||||
let e1 = Fix (NIf e0 "nothing" (Fix (NBinary NApp "just" "x")))
|
||||
let e2 = Fix (NAbs "t" (Fix (NAbs "just" (Fix (NAbs "nothing" e1)))))
|
||||
return (Fix (NAbs "t" (Fix (NAbs "x" e2))))
|
||||
loop OptionalBuild = do
|
||||
let e0 = Pi "nothing" "optional" "optional"
|
||||
let e1 = Pi "just" (Pi "_" "a" "optional") e0
|
||||
let e2 = Pi "optional" (Const Type) e1
|
||||
let e3 = OptionalLit "a" empty
|
||||
let e4 = Lam "x" "a" (OptionalLit "a" (pure "x"))
|
||||
let e5 = App (App (App "f" (App Optional "a")) e4) e3
|
||||
loop (Lam "a" (Const Type) (Lam "f" e2 e5))
|
||||
loop (Record _) = return (Fix (NSet []))
|
||||
loop (RecordLit a) = do
|
||||
a' <- traverse loop a
|
||||
let a'' = do
|
||||
(k, v) <- Dhall.Map.toList a'
|
||||
return (NamedVar [StaticKey k] v Nix.nullPos)
|
||||
return (Fix (NSet a''))
|
||||
loop (Union _) = return (Fix (NSet []))
|
||||
loop (UnionLit k v kts) = do
|
||||
v' <- loop v
|
||||
let e0 = do
|
||||
k' <- k : Dhall.Map.keys kts
|
||||
return (k', Nothing)
|
||||
let e2 = Fix (NBinary NApp (Fix (NSym k)) v')
|
||||
return (Fix (NAbs (ParamSet e0 False Nothing) e2))
|
||||
loop (Combine a b) = do
|
||||
a' <- loop a
|
||||
b' <- loop b
|
||||
let e0 = Fix (NBinary NApp (Fix (NBinary NApp "map" "toKeyVals")) "ks")
|
||||
let e1 = Fix (NBinary NApp "builtins.concatLists" e0)
|
||||
let e2 = Fix (NBinary NApp "builtins.listToAttrs" e1)
|
||||
|
||||
let defL = Fix (NBinary NApp (Fix (NBinary NApp "builtins.hasAttr" "k")) "kvsL")
|
||||
let defR = Fix (NBinary NApp (Fix (NBinary NApp "builtins.hasAttr" "k")) "kvsR")
|
||||
let valL = Fix (NBinary NApp (Fix (NBinary NApp "builtins.getAttr" "k")) "kvsL")
|
||||
let valR = Fix (NBinary NApp (Fix (NBinary NApp "builtins.getAttr" "k")) "kvsR")
|
||||
|
||||
let empty_ = Fix (NList [])
|
||||
let toNameValue v =
|
||||
let bindings =
|
||||
[ NamedVar ["name" ] "k" Nix.nullPos
|
||||
, NamedVar ["value"] v Nix.nullPos
|
||||
]
|
||||
in Fix (NList [Fix (NSet bindings)])
|
||||
|
||||
let e3 = Fix (NBinary NApp (Fix (NBinary NApp "combine" valL)) valR)
|
||||
let e4 = Fix (NBinary NApp "builtins.isAttrs" valL)
|
||||
let e5 = Fix (NBinary NApp "builtins.isAttrs" valR)
|
||||
let e6 = Fix (NBinary NAnd e4 e5)
|
||||
let e7 = Fix (NIf e6 (toNameValue e3) (toNameValue valR))
|
||||
let e8 = Fix (NIf defR e7 (toNameValue valL))
|
||||
let e9 = Fix (NIf defR (toNameValue valR) empty_)
|
||||
let toKeyVals = Fix (NAbs "k" (Fix (NIf defL e8 e9)))
|
||||
|
||||
let ksL = Fix (NBinary NApp "builtins.attrNames" "kvsL")
|
||||
let ksR = Fix (NBinary NApp "builtins.attrNames" "kvsR")
|
||||
let ks = Fix (NBinary NConcat ksL ksR)
|
||||
|
||||
let e10 =
|
||||
[ NamedVar ["ks" ] ks Nix.nullPos
|
||||
, NamedVar ["toKeyVals"] toKeyVals Nix.nullPos
|
||||
]
|
||||
let combine = Fix (NAbs "kvsL" (Fix (NAbs "kvsR" (Fix (NLet e10 e2)))))
|
||||
|
||||
let e11 = Fix (NBinary NApp (Fix (NBinary NApp "combine" a')) b')
|
||||
return (Fix (NLet [NamedVar ["combine"] combine Nix.nullPos] e11))
|
||||
loop (CombineTypes _ _) = return (Fix (NSet []))
|
||||
loop (Merge a b _) = do
|
||||
a' <- loop a
|
||||
b' <- loop b
|
||||
return (Fix (NBinary NApp b' a'))
|
||||
loop (Prefer a b) = do
|
||||
a' <- loop a
|
||||
b' <- loop b
|
||||
return (Fix (NBinary NUpdate a' b'))
|
||||
loop (Field a b) = do
|
||||
a' <- loop a
|
||||
return (Fix (NSelect a' [StaticKey b] Nothing))
|
||||
loop (Project a b) = do
|
||||
a' <- loop a
|
||||
let b' = fmap StaticKey (toList b)
|
||||
return (Fix (NSet [Inherit (Just a') b' Nix.nullPos]))
|
||||
loop (ImportAlt a _) = loop a
|
||||
loop (Note _ b) = loop b
|
||||
loop (Embed (X x)) = x
|
Loading…
Reference in New Issue