A developers' guide to creating a new Haskell project or program, and working in the Haskell developer ecosystem.

+

+

''Note: for learning the Haskell language itself we recommend [http://haskell.org/haskellwiki/Tutorials#Introductions_to_Haskell these resources].''

== Recommended tools ==

== Recommended tools ==

Line 10:

Line 12:

=== Revision control ===

=== Revision control ===

−

Use [http://git-scm.com/ git] or [http://darcs.net darcs] unless you have a specific reason not to. Both are lightweight distributed revision control systems (and darcs is written in Haskell). Both have massive market share in the Haskell world, if you want to encourage contributions from other Haskell hackers git or darcs are the best. Darcs hosting is available on [http://code.haskell.org code.haskell.org] and [http://patch-tag.com patch-tag]. [http://github.com/ github] for git is very popular.

+

Use [http://git-scm.com/ git] or [http://darcs.net darcs] unless you have a specific reason not to. Both are lightweight distributed revision control systems (and darcs is written in Haskell). Both have massive market share in the Haskell world. If you want to encourage contributions from other Haskell hackers then git or darcs are the best. Darcs hosting is available on [http://hub.darcs.net/ hub.darcs.net]. For git, [http://github.com/ github] is very popular.

=== Build system ===

=== Build system ===

Line 17:

Line 19:

Use [http://haskell.org/cabal/ Cabal].

Use [http://haskell.org/cabal/ Cabal].

−

You should read at least the start of section 2 of the [http://www.haskell.org/ghc/docs/latest/html/Cabal/index.html Cabal User's Guide].

+

You should read at least the start of section 2 of the [http://www.haskell.org/cabal/users-guide/ Cabal User's Guide].

−

You probably also want to use [http://haskell.org/cabal/download.html cabal-install] as a front-end for the Cabal library. Cabal-install provides commands not only for building libraries but also for installing them from and uploading them to Hackage. As a bonus, for almost all programs, it's faster than using Setup.hs scripts directly, since no time is wasted compiling the scripts. (This does not apply for programs that use custom Setup.hs scripts, since those need to be compiled even when using cabal-install.)

+

You should use [http://haskell.org/cabal/download.html cabal-install] as a front-end for installing your Cabal library. Cabal-install provides commands not only for building libraries but also for installing them from, and uploading them to, Hackage. As a bonus, for almost all programs, it's faster than using Setup.hs scripts directly, since no time is wasted compiling the scripts. (This does not apply for programs that use custom Setup.hs scripts, since those need to be compiled even when using cabal-install.)

+

+

cabal-install is widely available, as part of the [http://haskell.org/platform Haskell Platform], so you can probably assume your users will have it too.

=== Documentation ===

=== Documentation ===

For libraries, use [http://haskell.org/haddock/ Haddock]. We recommend

For libraries, use [http://haskell.org/haddock/ Haddock]. We recommend

−

using the latest version of Haddock.

+

using the version of Haddock that ships with the Haskell Platform. Haddock generates [http://hackage.haskell.org/packages/archive/base/4.3.1.0/doc/html/Prelude.html nice markup], with links to source.

=== Testing ===

=== Testing ===

−

You can use [http://www.md.chalmers.se/~rjmh/QuickCheck/ QuickCheck] or [http://www.mail-archive.com/haskell@haskell.org/msg19215.html SmallCheck] to test pure code. To test impure code, use [http://hackage.haskell.org/cgi-bin/hackage-scripts/package/HUnit HUnit].

+

You can use [http://hackage.haskell.org/package/QuickCheck QuickCheck] or [http://www.mail-archive.com/haskell@haskell.org/msg19215.html SmallCheck] to test pure code. To test impure code, use [http://hackage.haskell.org/cgi-bin/hackage-scripts/package/HUnit HUnit]. See [http://hackage.haskell.org/packages/archive/hashable/1.1.2.2/hashable.cabal this Cabal file] for an example of how to include tests in your Cabal package.

To get started, try [[Introduction to QuickCheck]]. For a slightly more advanced introduction, [http://blog.codersbase.com/2006/09/simple-unit-testing-in-haskell.html Simple Unit Testing in Haskell] is a blog article about creating a testing framework for QuickCheck using some Template Haskell. For HUnit, see [[HUnit 1.0 User's Guide]]

To get started, try [[Introduction to QuickCheck]]. For a slightly more advanced introduction, [http://blog.codersbase.com/2006/09/simple-unit-testing-in-haskell.html Simple Unit Testing in Haskell] is a blog article about creating a testing framework for QuickCheck using some Template Haskell. For HUnit, see [[HUnit 1.0 User's Guide]]

Line 37:

Line 41:

applications is [http://hackage.haskell.org/packages/hackage.html Hackage]. Hackage can

applications is [http://hackage.haskell.org/packages/hackage.html Hackage]. Hackage can

If at all possible, depend on libraries that are provided by the [http://haskell.org/platform Haskell Platform], and libraries that in turn build against the Haskell Platform. This set of libraries is designed to be widely available, so your end users will be able to build your software.

== Structure of a simple project ==

== Structure of a simple project ==

Line 59:

Line 67:

install it and release.

install it and release.

−

The new tool "cabal init" automates all this for you, but you should

+

''Note'': The new tool "cabal init" automates all this for you, but you should

understand all the parts even so.

understand all the parts even so.

Line 93:

Line 101:

</haskell>

</haskell>

−

=== Stick it in darcs ===

+

=== Stick it in version control ===

Place the source under revision control (you may need to enter your e-mail address first, to identify you as maintainer of this source):

Place the source under revision control (you may need to enter your e-mail address first, to identify you as maintainer of this source):

Line 241:

Line 249:

=== (Optional) Improve your code: HLint ===

=== (Optional) Improve your code: HLint ===

−

[[HLint]] can be a valuable tool for improving your coding style, particularly if you're new to Haskell. Let's run it now.

+

[http://hackage.haskell.org/package/hlint HLint] can be a valuable tool for improving your coding style, particularly if you're new to Haskell. Let's run it now.

<code>

<code>

Line 361:

Line 369:

=== Running the test suite from darcs ===

=== Running the test suite from darcs ===

−

We can arrange for darcs to run the test suite on every commit:

+

We can arrange for darcs to run the test suite on every commit that is run with the flag --test:

<code>

<code>

Line 380:

Line 388:

<code>

<code>

$ darcs add Tests.hs

$ darcs add Tests.hs

−

$ darcs record --all

+

$ darcs record --all --test

What is the patch name? Add testsuite

What is the patch name? Add testsuite

Do you want to add a long comment? [yn]n

Do you want to add a long comment? [yn]n

Line 391:

Line 399:

</code>

</code>

−

Excellent: now, patches must pass the test suite before they can be committed.

+

Excellent: now, patches must pass the test suite before they can be committed provided the --test flag is passed.

=== Tag the stable version, create a tarball, and sell it! ===

=== Tag the stable version, create a tarball, and sell it! ===

Line 544:

Line 552:

You can also set up Cabal to run configure scripts, among other features. For more information consult the

You can also set up Cabal to run configure scripts, among other features. For more information consult the

1 Recommended tools

Almost all new Haskell projects use the following tools. Each is
intrinsically useful, but using a set of common tools also helps
everyone by increasing productivity, and you're more likely to get
patches.

1.1 Revision control

Use git or darcs unless you have a specific reason not to. Both are lightweight distributed revision control systems (and darcs is written in Haskell). Both have massive market share in the Haskell world. If you want to encourage contributions from other Haskell hackers then git or darcs are the best. Darcs hosting is available on hub.darcs.net. For git, github is very popular.

1.2 Build system

You should use cabal-install as a front-end for installing your Cabal library. Cabal-install provides commands not only for building libraries but also for installing them from, and uploading them to, Hackage. As a bonus, for almost all programs, it's faster than using Setup.hs scripts directly, since no time is wasted compiling the scripts. (This does not apply for programs that use custom Setup.hs scripts, since those need to be compiled even when using cabal-install.)

cabal-install is widely available, as part of the Haskell Platform, so you can probably assume your users will have it too.

1.3 Documentation

For libraries, use Haddock. We recommend
using the version of Haddock that ships with the Haskell Platform. Haddock generates nice markup, with links to source.

1.5 Distribution

The standard mechanism for distributing Haskell libraries and
applications is Hackage. Hackage can
host your cabalised tarball releases, and link to any library
dependencies your code has. Users will find and install your packages via "cabal install", and your package will be integrated into Haskell search engines, like hoogle

1.6 Target Environment

If at all possible, depend on libraries that are provided by the Haskell Platform, and libraries that in turn build against the Haskell Platform. This set of libraries is designed to be widely available, so your end users will be able to build your software.

2 Structure of a simple project

The basic structure of a new Haskell project can be adopted from
HNop, the minimal Haskell project. It
consists of the following files, for the mythical project "haq".

Haq.hs -- the main haskell source file

haq.cabal -- the cabal build description

Setup.hs -- build script itself

_darcs -- revision control

README -- info

LICENSE -- license

Of course, you can elaborate on this, with subdirectories and multiple
modules. See Structure of a Haskell project for an example of a larger project's directory structure.

Here is a transcript that shows how you'd create a minimal darcs and cabalised
Haskell project for the cool new Haskell program "haq", build it,
install it and release.

Note: The new tool "cabal init" automates all this for you, but you should
understand all the parts even so.

We will now walk through the creation of the infrastructure for a simple
Haskell executable. Advice for libraries follows after.

2.10 Running the test suite from darcs

will run the full set of QuickChecks.
If your test requires it, you may need to ensure other things are built too -- for example:darcs setpref test "alex Tokens.x;happy Grammar.y;runhaskell Tests.hs".
You will encounter that this way a darcs patch is also accepted if a QuickCheck test fails.
You have two choices to work around this:

Use

quickCheck'

from the package QuickCheck-2 and call

exitWithFailure

if it return

False

.

Keep the test program as it is, and implement the failure on the shell level:

This has the advantage that Cabal will do a bit more checking, and
ensure that the tarball has the structure that HackageDB expects.
Note that it does require the LICENSE file to exist.
It packages up the files needed to build the project; to include other files (such as Test.hs in the above example, and our README), we need to add:

extra-source-files: Tests.hs README

to the .cabal file to have everything included.

2.11.1.2 Using darcs

Alternatively, you can use darcs:

$ darcs dist -d haq-0.0
Created dist as haq-0.0.tar.gz

And you're all set up!

2.11.2 Check that your source package is complete

Just to make sure everything works, try building the source package in some temporary directory:

$ tar xzf haq-0.0.tar.gz
$ cd haq-0.0
$ cabal configure
$ cabal build

and for packages containing libraries,

$ cabal haddock

2.11.3 Upload your package to Hackage

Whichever of the above methods you've used to create your package, you can upload it to the Hackage package collection via a web interface.
You may wish to use the package checking interface there first, and fix things it warns about, before uploading your package.

2.12 Summary

The following files were created:

$ ls
Haq.hs Tests.hs dist haq.cabal
Setup.hs _darcs haq-0.0.tar.gz

3 Libraries

The process for creating a Haskell library is almost identical. The differences
are as follows, for the hypothetical "ltree" library:

3.1 Hierarchical source

The source should live under a directory path that fits into the
existing module layout guide.
So we would create the following directory structure, for the module
Data.LTree:

$ mkdir Data
$ cat > Data/LTree.hs
module Data.LTree where

So our Data.LTree module lives in Data/LTree.hs

3.2 The Cabal file

Cabal files for libraries list the publically visible modules, and have
no executable section:

5 Licenses

Code for the common base library package must be BSD licensed. Otherwise, it
is entirely up to you as the author.
Choose a licence (inspired by this).
Check the licences of things you use (both other Haskell packages and C
libraries), since these may impose conditions you must follow.
Use the same licence as related projects, where possible. The Haskell community is
split into 2 camps, roughly: those who release everything under BSD, and
(L)GPLers. Some Haskellers recommend avoiding LGPL, due to cross-module optimisation
issues. Like many licensing questions, this advice is controversial. Several Haskell projects
(wxHaskell, HaXml, etc) use the LGPL with an extra permissive clause which gets round the
cross-module optimisation problem.

Each of these steps can pose potential road blocks, and code authors can
do a lot to help code users avoid such blocks. Steps 1..2 may be easy enough, and many coders and users are mainly concerned with step 5. Steps 3..4 are the ones that often get in the way. In particular, the
following questions should have clear answers:

Which is the latest version?

What state is it in?

What are its aims?

Where is the documentation?

Which is the right version for given OS and Haskell implementation?

How is it packaged, and what tools are needed to get and unpack it?

How is it installed, and what tools are needed to install it?

How do we handle dependencies?

How do we provide/acquire the knowledge and tool-chains needed?

The best place to answer these questions is a README file,
distributed with the library or application, and often accompanied with
similar text on a more extensive web page.

9.2 Tutorials

Generated haddock documentation is usually not enough to help new
programmers learn how to use a library. You must also provide accompanying examples, and even tutorials about the library.

Please consider providing example code for your library or application. The code should be type-correct and well-commented.

10 Program structure

Monad transformers are very useful for programming in the large,
encapsulating state, and controlling side effects. To learn more about this approach, try Monad Transformers Step by Step.

11 Publicity

The best code in the world is meaningless if nobody knows about it. The
process to follow once you've tagged and released your code is:

11.1 Join the community

If you haven't already, join the community. The best way to do this is to subscribe to at least haskell-cafe@ and haskell@ mailing lists. Joining the #haskell IRC channel is also an excellent idea.

11.2 Announce your project on haskell@

Most important: announce your project releases to the haskell@haskell.org mailing list. Tag your email subject line with "ANNOUNCE: ...". This ensure it will then make it into the Haskell Weekly News. To be doubly sure, you can email the release text to the HWN editor.

11.3 Add your code to the public collections

Add your library or application to the Libraries and tools page, under the relevant category, so people can find it.

If your release is a Cabal package, add it to the Hackage database (Haskell's CPAN wanna-be).

11.4 Blog about it

Blog about it! Blog about your new code on Planet Haskell.
Write about your project in your blog, then email the Planet Haskell maintainer (ibid on #haskell) the RSS feed url for your blog