Skip to content

NoRedInk/haskell-libraries

Repository files navigation

NoRedInk/haskell-libraries

A monorepo of our opensourced Haskell libraries.

For those interested in learning more about our reasons for developing these libraries, we invite you to check out our blog post titled "Haskell for the Elm Enthusiast" available at https://blog.noredink.com/post/658510851000713216/haskell-for-the-elm-enthusiast. This post provides insights into the motivations behind our efforts.

Developing

To set up the development environment for this project first install Nix and Direnv. Note that the first time setup will take some time (~1 hour). Then run:

direnv allow

Some useful shell commands when working on these libraries:

cabal build nri-prelude           # build the library
cabal test nri-prelude            # run the tests
hpack nri-prelude                 # generate nri-prelude.cabal from package.yaml
ghcid -c "cabal repl nri-prelude" # start a code watcher
ormolu -i <file>                  # Format a source file
cabal haddock nri-prelude         # Run documentation generation
ormolu -i **/*.hs                 # Format everything
cabal build all                   # build everything
cabal test all                    # test everything

We use Ormolu for code formatting.

Documentation comments use the Haddock format to ensure they are rendered correctly on package websites.

Testing compilation against GHC 8.10

Our default shell.nix sets up an environment around GHC version 8.10. CI also runs tests against GHC 9.0. To test using this version locally:

cachix use nri-open-source       # set up cache so the next step goes faster
nix-shell shell-ghc-9-0.nix

This starts a special shell in which you can run any of the commands above.

Tips for adding dependencies

To allow these libraries to be in Stackage we're limited to dependencies that are themselves in Stackage. Being in stackage indicates a package has an active maintainer, who keeps the package compatible with the latest versions of its dependencies. This means that while using stackage dependencies only limits us it also saves us time.

When we add a dependency we need to give it a lower and upper version bound. Here's some tips for finding reasonable initial values.

For the lower bound we can use a known-compatible version. If we're adding a dependency on tropical-fruits to nri-prelude, we can go into the project making use of nri-prelude and getting the version of tropical-fruits already in use there, by running:

$ ghc-pkg list | grep tropical-fruits
tropical-fruits-2.6.2.0

The output above would translate into a lower bound of >= 2.6.2.0.

For the upper bound we can go one major version above the last released version of the dependency. Were tropical-fruits a real package we could find it's latest version at: https://hackage.haskell.org/package/tropical-fruits

Once we have the latest version we can make an upper bound of that by keeping the first two digits and incrementing the second of those by one. For example: if the latest release is 2.7.1.1 our upper bound will be < 2.8. This works because the first two digits together make up the major version in the PVP versioning scheme used on hackage.

Publishing

Hackage (the Haskell package repository) uses a versioning scheme called PVP. It's like the 'semantic versioning' used by NPM, Elm, and others, but differs in having two major version digits rather than one:

MAJOR.MAJOR.MINOR.PATCH

To keep things simple for those familiar with semantic versioning this repository uses the convention of keeping the first major number zero. When creating a new version change the other version digits as you would using semantic versioning.

To publish the new version run the release.sh script for the package you want to publish:

./release.sh nri-prelude

Note: this requires an account on hackage.org with rights to publish the library. These are the steps to creating such an account:

  1. Fill the registration form.
  2. Send an email to hackage-trustees@haskell.org to requesting upload access for your account.
  3. Login to hackage using the shared NoRedInk account (NRI engineers can find the password in the usual place).
  4. Using the NoRedInk account add your new own hackage account to the maintainer groups of the NRI libraries.

Stackage is a repository built on top of hackage. Stackage runs nightly builds checking the latest version of packages are compiling against each other.

We registered the libraries in this repository with Stackage here. Stackage will find new versions of these libraries pushed to hackage.

To remain in stackage these libraries need to up-to-date with the latest versions of their dependencies. When a dependency releases a new version not accepted by the version bounds of a package in this library then we need to do a new release to support the new version of the dependency. To get notifications when we need to do an update like that, join the Haskell Open Source Maintainers NRI mailing group.