About a month ago, we released our FREE . If you’ve never used Stack before, you should totally check out that course! This article will give you a sneak peak at some of the content in the course. Stack mini-course But if you’re already familiar with the basics of Stack and don’t think you need the course, don’t worry! In this article we’ll be going through another cool tool to streamline your workflow! Most any Haskell project you create will use Cabal under the hood. Cabal performs several important tasks for you. It downloads dependencies for you and locates the code you wrote within the file system. It also links all your code so GHC can compile it. In order for Cabal to do this, you need to create a file describing all these things. It needs to know for instance what libraries each section of your code depends on. You'll also have to specify where the source directories are on your file system. .cabal The organization of a file is a little confusing at times. The syntax can be quite verbose. We can make our lives simpler though if we use the "Hpack" tool. Hpack allows you to specify your project organization in a more concise format. Once you’ve specified everything in Hpack’s format, you can generate the file with a single command. .cabal .cabal Using Hpack The first step to using hpack if of course to download it. This is simple, as you long as you have installed Stack on your system. Use the command: stack install hpack This will install Hpack system wide so you can use it in all your projects. The next step is to specify your code’s organization in a file called . Here’s a simple example: package.yaml name: HpackExampleProject version: 0.1.0.0 ghc-options: -Wall dependencies: - base library: source-dirs: src/ executables: HpackExampleProject-exe: main: Main.hs source-dirs: app/ dependencies: HpackExampleProject tests: HpackExampleProject-test: main: Spec.hs source-dirs: test/ dependencies: HpackExampleProject This example will generate a very simple cabal file. It’ll look a lot like the default template of running . There are a few basic fields, like the name, version and compiler options for our project. We can specify details about our code library, executables, and any test suites we have, just as we can in a file. Each of these components can have their own dependencies. We can also specify global dependencies. stack new HpackExampleProject .cabal Once we have created this file, all we need to do is run the command from the directory containing this file. This will generate our file: hpack .cabal >> hpackgenerated HpackExampleProject.cabal What problems does Hpack solve? One big problem hpack solves is module inference. Your file should specify all Haskell modules which are part of your library. You'll always have two groups: “exposed” modules and “other” modules. It can be quite annoying to list every one of these modules, and the list can get quite long as your library gets bigger! Worse, you'll sometimes get confusing errors when you create a new module but forget to add it to the .cabal file. With Hpack, you don't need to remember to add most new files! It looks at your file system and determines what modules are present for you. Suppose you have organized your files like so in your source directory: .cabal src/Lib.hssrc/API.hssrc/Internal/Helper.hssrc/Internal/Types.hs Using the normal . approach, you would need to list these modules by hand. But without listing anything in the package.yaml file, you’ll get all your modules listed in the .cabal file: cabal exposed-modules: API Internal.Helper Internal.Types Lib Now, you might not want all your modules exposed. You can make a simple modification to the package file: library: source-dirs: src/ exposed-modules: - API - Lib And hpack will correct the file. .cabal exposed-modules: API Libother-modules: Internal.Helper Internal.Types From this point, Hpack will infer all new Haskell modules as “other” modules. You’ll only need to list “exposed” modules in package.yaml. There’s only one thing to remember! You need to run each time you add new modules, or else Cabal will not know where your code is. This is still much easier than modifying the file each time. The file itself will still contain a long list of module names. But most of them won’t be present in the file, which is your main point of interaction. hpack .cabal .cabal package.yaml Another big benefit of using hpack is global dependencies. Notice in the example how we have a “dependencies” field above all the other sections. This means our library, executables, and test-suites will all get base as a dependency for free. Without hpack, we would need to specify base as a dependency in each individual section. There is also plenty of other syntactic sugar available with hpack. One simple example is the github specification. You can put the following single line in your package file: github: username/reponame And you’ll get the following lines for free in your file. .cabal homepage: https://github.com/username/reponame#readmebug-reports: https://github.com/username/reponame/issues Summary Once you move beyond toy projects, maintenance of your package will be non-trivial. If you use hpack, you’ll have an easier time organizing your first big project. The syntax is cleaner. The organization is more intuitive. Finally, you will save yourself the stress of performing many repetitive tasks. Constant edits to the file will interrupt your flow and build process. So avoiding them should make you a lot more productive. .cabal Now if you haven’t used Stack or Cabal at all before, there was a lot to grasp here. But hopefully you’re convinced that there are easy ways to organize your Haskell code! If you’re intrigued at learning how, sign up for our FREE ! You’ll learn all about the simple approaches to organizing a Haskell project. Stack mini-course If you’ve never used Haskell at all and are totally confused by all this, no need to fret! Download our and you’ll be well on your way to learning Haskell! Getting Started Checklist