1. Stack: The Project and Dependency Manager
One of the first hurdles in any programming language is managing projects, dependencies, and compiler versions. Haskell has two main build tools: Cabal and Stack. While Cabal is the foundational package management system, Stack provides a more opinionated
and reproducible workflow that is especially welcoming for developers. Stack manages project-specific dependencies and even the exact version of the Glasgow Haskell Compiler (GHC) for you. It achieves this through 'snapshots'—curated sets of packages from the Stackage repository that are guaranteed to work together. This approach effectively solves the infamous 'Cabal hell,' where conflicting package versions could bring a project to a standstill. By defining a specific resolver in a simple `stack.yaml` file, you ensure that anyone on your team can build the project identically, every single time. It automates GHC installation, simplifies project scaffolding with templates, and provides a seamless, batteries-included experience for building, testing, and running your applications.
2. Haskell Language Server (HLS): Your IDE's Best Friend
Modern software development is nearly inseparable from the rich features of an integrated development environment (IDE), like VSCode, Vim, or Emacs. The Haskell Language Server (HLS) is the engine that powers this integration for Haskell. HLS is an implementation of the Language Server Protocol (LSP), which allows a single backend service to provide IDE features to any compatible editor. Once configured, HLS provides on-the-fly error and warning diagnostics from the GHC compiler, autocompletion, and type information on hover. It can jump to a function's definition, find all references to a variable, and offer 'code lenses'—contextual actions that appear directly in your code. Furthermore, HLS integrates with other tools on this list, allowing you to get linting suggestions and apply automatic formatting without ever leaving your editor. This constant, interactive feedback loop is crucial for productivity, turning your text editor into a powerful, Haskell-aware development environment.
3. HLint: The Code Quality Coach
Writing code that works is one thing; writing code that is clean, idiomatic, and efficient is another. HLint is a widely used static analysis tool that scans your Haskell source code and suggests improvements. Originally created as a teaching aid to help beginners, it has become an indispensable tool for professionals. HLint identifies a wide range of common issues, from redundant code and unnecessary parentheses to suggesting more efficient or readable alternative functions. For example, it might suggest rewriting `concat (map f xs)` as the more direct `concatMap f xs`. The suggestions are not just about style; they often point toward a deeper understanding of Haskell's standard libraries. HLint can be run from the command line, and its suggestions can even be applied automatically using its refactoring feature. More importantly, it integrates directly into the Haskell Language Server, providing real-time hints and quick-fix actions within your editor, helping you learn and improve as you code.
4. Ormolu: The Opinionated Code Formatter
Debates over code formatting—indentation, line breaks, and spacing—are a classic source of friction in development teams. An automated, opinionated code formatter eliminates these discussions entirely by enforcing a single, consistent style across the entire codebase. For Haskell, Ormolu is a leading choice for this role. Like popular formatters in other languages (e.g., `rustfmt` or `gofmt`), Ormolu parses your code and reprints it according to its strict, built-in style guide. A key feature of Ormolu is its lack of configuration options; this is intentional, as it guarantees that any code formatted with it will look identical, regardless of who wrote it. Its output is designed to be deterministic and produce minimal changes when code is modified. For those who desire more customization, a fork called Fourmolu exists. Using a formatter like Ormolu, often triggered automatically on save via an editor integration, ensures that code reviews can focus on logic and architecture, not on stylistic squabbles.











