How to script with stack
How to Script with Stack
How to create a stack project
How to Build with Stack
Write bitrot free code with Haskell

 1 2 3 4 5 6 7 8 9  #!/bin/bash export TTY . $HOME/scripts/libraries/bash-library.sh export PATH="$HOME/.local/bin:$(remove_from_path$SCRIPTS)" cabal install Cabal cabal-install cabal update sudo stack upgrade

## Developing cabal packages

• Given a directory of haskell (.hs) files, to turn this into a Cabal package we need two extra files in the project’s root directory:
• proglet.cabal
Containing package metadata and build information.
• Setup.hs
Fsually containing a few standardized lines of code, but can be customized if necessary.
 1  cabal init --interactive

## How to script with stack

### Install ghc

 1 2 3  stack setup # or stack --install-ghc exec -- ghc --version

### Get the ghc version

 1  stack exec -- ghc --version

### Compile a simple program

 1 2  main :: IO () main = putStrLn "Hello World!"
 1  stack exec -- ghc HelloWorld.hs

### Interpret a simple program as a script

 1 2 3  stack exec -- runghc HelloWorld.hs # Or, as you may have guessed: stack runghc -- HelloWorld.hs

 1  hs-import-to-package Network.HTTP.Simple
http-conduit
HTTP-Simple-0.1
http-conduit-2.3.0
http-client
HTTP-4000.3.14
http-streams


Let’s say we want to use a package that doesn’t ship with GHC itself, like http-conduit.

The stack exec command and its shortcuts like stack ghc and stack runghc all take a --package argument indicating that an additional package needs to be present.

So consider this http.hs file:

  1 2 3 4 5 6 7 8 9 10 11 12  {-# LANGUAGE OverloadedStrings #-} import qualified Data.ByteString.Lazy.Char8 as L8 import Network.HTTP.Simple main :: IO () main = do response <- httpLBS "http://httpbin.org/get" putStrLn $"The status code was: " ++ show (getResponseStatusCode response) print$ getResponseHeader "Content-Type" response L8.putStrLn $getResponseBody response  1 2 3 4  NonDet -- backtracking search WriterT -- ReaderT -- StateT -- threads state through a function  1 2  # ensure that it runs with the http-conduit package stack runghc --package http-conduit -- http.hs ### Specify a resolver There’s unfortunately a major downside to everything we’ve seen so far: there are no guarantees given about which version of GHC or libraries will be used. The selection will depend entirely on what Stack deems the most appropriate resolver - or collection of GHC and libraries - when you start using it. If you want to be guaranteed that a specific set of packages will be used, you can set the --resolver on the command line. $ stack --resolver lts-12.21 runghc --package http-conduit http.hs


### Script interpreter

Remembering to pass all of these flags on the command line is very tedious, error prone, and makes it difficult to share scripts with others.

To address this, Stack has a [script interpreter feature](https://docs.ha skellstack.org/en/stable/GUIDE/#script-%20interpreter) which allows these flags to be placed at the top of your script.

Stack also has a dedicated script command which has some nice features like auto- detection of packages you need based on import statements.

If we modify our http.hs to say:

### Testing

Testing is also straightforward:

 1  stack test

As it happens, this is just a convenience shortcut for:

 1  stack build --test

The same applies to stack bench (for benchmarking) and stack haddock (for building Haddock documentation). What this means is that you can compose these flags to build the code, build the docs, run tests, and run benchmarks:

 1  stack build --test --bench --haddock

### Common flags

• --file-watch will run build in file-watch mode, where it will wait for changes to files and then automatically rebuild. This can be very convenient to run in a terminal while simulatenously editing in another window.
• --fast will disable optimizations
• --pedantic turns on -Wall -Werror for GHC (all warnings on, and warnings treated as errors)

So throwing a few of these together:

 1  stack build --test --file-watch --fast --pedantic