I heard you want to try out haskell but like me you hesitate because you don’t know how to setup your enviroment for Haskell. Okay, hear me out. Nix can be the solution, I know you have to learn more. However, it’s not that much. At least that’s what I see. Just learn a little bit of nix now and learn as you go!
So if I convinced you to learn a little bit of nix. Go ahead and download it from their website.
Now, instead of worrying what system configuration you have to do, you just do this
mkdir my-project
nix-shell --pure -p ghc cabal-install --run "cabal init"
What’s happening here is you’re telling nix to go get ghc
(compiler) and
cabal-install
(build tool), and run the command cabal init
. This will generate a very small scaffold for a haskell
project. Since we used the flag --pure
it won’t install anything
global in your system.
Your my-project
directory should look like this
my-project
|-- CHANGELOG.md
|-- Main.hs
|-- my-project.cabal
|-- Setup.hs
Main.hs
should contain the Hello World
program. This
is also where you want to write your experiment haskell code.
Since you used ghc
and cabal
in a pure environment you
won’t find them when you try to execute cabal
in the console. So you won’t be
able to run this project as is. What you can do is play with your haskell
project in a nix-shell
. You can do this by first generating a
default.nix
file. This can be done by doing this command in your
project directory
nix-shell --pure -p cabal2nix --run "cabal2nix ." > default.nix
This will generate the default.nix
file and will contain
{ mkDerivation, base, stdenv }:
{
mkDerivation pname = "my-project";
version = "0.1.0.0";
src = ./.;
isLibrary = false;
isExecutable = true;
executableHaskellDepends = [ base ];
license = "unknown";
hydraPlatforms = stdenv.lib.platforms.none;
}
This file describes your project. It’s like a function that takes in nix stuff.
For the last part, write the shell.nix
file.
{ nixpkgs ? import <nixpkgs> {} }:
let
inherit (nixpkgs) pkgs;
inherit (pkgs) haskellPackages;
project = haskellPackages.callPackage ./default.nix {};
in
pkgs.stdenv.mkDerivation {
name = "my-project";
buildInputs = project.env.nativeBuildInputs ++ [
haskellPackages.cabal-install
];
}
When you perform nix-shell --pure
in your project directory. It
will go into a nix environment and you’ll see your command prompt turn like this
[nix-shell:~/my-project]$
In this environment you’ll have access to cabal
. So you can build
and run your project with cabal new-build
and cabal new-run
.
If you want to expirement with a haskell package from hackage like
the text
package, you can add it to your
my-project.cabal
file, in the build-depends
section.
cabal-version: >=1.10
-- Initial package description 'my-project.cabal' generated by 'cabal
-- init'. For further documentation, see
-- http://haskell.org/cabal/users-guide/
name: my-project
version: 0.1.0.0
-- synopsis:
-- description:
-- bug-reports:
-- license:
license-file: LICENSE
-- author:
-- maintainer:
-- copyright:
-- category:
build-type: Simple
extra-source-files: CHANGELOG.md
executable my-project
main-is: Main.hs
-- other-modules:
-- other-extensions:
build-depends: base >=4.13 && <4.14
, text
-- hs-source-dirs:
default-language: Haskell2010
You should also add this to your default.nix
file, so later on when
you do decide to build your project with nix-build
you don’t have to chase
around packages. I’ll probably cover nix-build
in another post.
{ mkDerivation, base, stdenv, text }:
mkDerivation {
pname = "my-project";
version = "0.1.0.0";
src = ./.;
isLibrary = false;
isExecutable = true;
executableHaskellDepends = [ base text ];
license = "unknown";
hydraPlatforms = stdenv.lib.platforms.none;
}