Last updated: 2019-06-28 15:35:39 +0100
Upstream URL: git clone http://chriswarbo.net/git/nix-eval.git
Contents of README.md follows
This Haskell package is a crude implementation of <code>eval</code>, as found in dynamic languages like Lisp, Python, Javascript, etc. It lets us construct Haskell code programatically (either at run time, or in Template Haskell), and attempt to evaluate it.
What sets this package apart from other <code>eval</code> implementations, is the ability to control which packages and modules are available during evaluation. This is achieved by calling out to the Nix package manager.
<code>Expr</code> is the type of expressions, which contains a list of package names, a list of modules to import, a list of compiler flags, a list of <code>String</code>s to put in the generated module and a <code>String</code> of Haskell code to evaluate. All of these are just <code>String</code>s internally, but we use wrappers to prevent accidentally using packages as modules, etc.
A few combinators are provided for common manipulations, for example <code>qualified "Foo" "bar"</code> will produce the expression <code>"Foo.bar"</code> with <code>"Foo"</code> in its module list. The <code>OverloadedStrings</code> extension allows packages, modules, flags and expressions to be written as literals. Note that literal expressions are given an empty context; you will have to specify any required modules, packages, etc. separately.
When evaluated, the Haskell code is prefixed by an import of each module, the “preamble” strings (if any) and wrapped in <code>main = putStr (..)</code>. This code is piped into <code>runhaskell</code>. If any flags are specified, they are appended as arguments to the <code>runhaskell</code> command.
The <code>runhaskell</code> process itself is invoked via the <code>nix-shell</code> command, which provides all of the required packages via the <code>ghcWithPackages</code> mechanism of nixpkgs. Packages are taken from nixpkgs’s <code>haskellPackages</code> set by default, which can be overridden by setting the <code>NIX_EVAL_HASKELL_PKGS</code> environment variable to the path of a Nix file. Note that the package names used in your Haskell code should correspond to the keys in this package set, which might differ from those used on Hackage.
If the process exits successfully, its stdout will be returned wrapped in <code>Just</code>; otherwise <code>Nothing</code> is returned. If you wish to alter the <code>main</code> implementation, use <code>Language.Eval.Internal.eval'</code>
This implementation is a little rough; for example, you may prefer to use <code>Text</code> rather than <code>String</code>; use a better representation like the syntax trees from TemplateHaskell or <code>haskell-src-exts</code> instead; or accumulate packages and modules monadically.
The intention of this library is to provide a simple, minimal base to support such design choices, and <code>String</code> is the lowest common denominator. You’re welcome, and encouraged, to build more sophisticated APIs; as long as you can pretty-print to a <code>String</code>, they should work out of the box.
This is also why we return the contents of stdout, rather than trying to parse it into a more appropriate type: it’s not our place to choose how the result should be parsed, so we avoid the problem; by that point, our job is done.