Skip to content

Industrial-grade Haskell project template for mission-critical systems. Features formal verification (LiquidHaskell), robust error handling, hexagonal architecture, TDD, and AI-assistant rules (Cursor)

License

Notifications You must be signed in to change notification settings

rbeauchamp/industrial-haskell-template

Repository files navigation

Industrial-Grade Haskell Project Template

A rigorously structured, formally verified Haskell project template designed for mission-critical industrial applications. This template provides a comprehensive foundation for projects requiring high reliability, mathematical correctness, strong compile-time guarantees, and systematic error handling.

Template Philosophy

This template embodies industrial best practices for Haskell development:

  • Formal Verification: Mathematical correctness through LiquidHaskell refinement types
  • Comprehensive Type Safety: Advanced GHC features and strict type checking
  • Systematic Error Handling: Explicit, type-safe error handling with complete context
  • Clean Architecture: Hexagonal design with pure domain core and effectful boundaries
  • Domain-Driven Design: Business logic expressed in types with strong invariants
  • Production Readiness: Industry-tested patterns for robust, maintainable systems

Its primary goal is to provide a reliable starting point for developers building new mission-critical Haskell applications where correctness and maintainability are paramount.

Core Features

1. Formal Verification & Type Safety

  • LiquidHaskell Integration: Refinement types for compile-time property verification
  • Extensive Static Checking: Advanced GHC options with -Wall and custom warnings
  • Linear Types: Resource tracking and consumption verification
  • Domain Invariants: Business rules encoded at the type level

2. Idiomatic Error Handling

  • Type-First Error Handling: Explicitly typed errors in all operations
  • Rich Error Context: Complete debugging information in structured error types
  • No Partial Functions: Total functions with explicit failure cases
  • Error Boundaries: Clear separation between pure validation and effectful error handling

3. Architectural Framework

  • Hexagonal Architecture: Pure domain core with adapters at boundaries
  • Module Hierarchy: Structured organization of domain, components, and infrastructure
  • Component Isolation: Well-defined interfaces with proper encapsulation
  • Effect Separation: Pure core with effects isolated to boundaries

4. Documentation Templates

  • Mission Statement: Template for defining project purpose and commitments
  • Operational Context: Framework for defining operational scope and constraints
  • User Experience Specification: Structure for comprehensive UX documentation
  • Technical Guides: Templates for implementation details and standards

5. Testing Infrastructure

  • Property-Based Testing: QuickCheck for mathematical property verification
  • Error Path Testing: Comprehensive testing of error conditions and handling
  • Environment Generators: Test utilities for component environments
  • Error Assertions: Custom matchers for error validation in tests

6. Development Toolchain

  • GHC 9.10.1: Latest Glasgow Haskell Compiler with GHC2024 language standard
  • Cabal 3.14.1.1: Modern build system and package manager
  • HLS 2.9.0.1: Haskell Language Server with IDE integration
  • Z3 SMT Solver: For LiquidHaskell verification

7. AI-Assisted Development (Cursor Integration)

  • Cursor IDE Rules: Includes a comprehensive set of rules in .cursor/rules/ specifically designed to guide AI assistants within the Cursor IDE.
  • Enforced Standards: These rules ensure AI contributions adhere to the template's strict standards for code quality, architecture, formal verification, error handling, and documentation.
  • Consistent Development: Promotes consistent, high-quality, AI-assisted development aligned with the project's rigorous requirements.

Getting Started

  1. Ensure you have GHCup installed to manage the Haskell toolchain.

  2. Install required tools (exact versions required for reproducible builds):

    # Core toolchain
    ghcup install ghc 9.10.1
    ghcup install cabal 3.14.1.1
    ghcup install hls 2.9.0.1
    
    # Build tools
    cabal install happy-2.1.5  # Parser generator for LiquidHaskell
    cabal install alex-3.5.2.0 # Lexer generator
    cabal install hspec-discover # Test discovery tool
  3. Verify Z3 installation (required for LiquidHaskell):

    z3 --version  # Should output version 4.14.0 or later

    If Z3 is not installed, follow your system's package manager instructions or download from Z3's releases page.

  4. Clone and customize the template:

    git clone https://github.com/rbeauchamp/industrial-haskell-template.git my-project
    cd my-project
  5. Initial Project Customization Checklist

    After cloning, please complete the following steps to tailor the template to your project:

    • Rename Project:
      • Update name: in package.yaml (e.g., my-awesome-project).
      • Update executable name (industrial-haskell-template-exe:) in package.yaml (e.g., my-awesome-project-exe:).
      • Update library reference in executable dependencies (industrial-haskell-template) in package.yaml if you changed the library name.
      • Consider renaming the .cabal file (after running hpack) if desired.
    • Update Metadata (package.yaml):
      • Set version: appropriately (e.g., 0.1.0.0).
      • Verify license: matches your intended license (currently Unlicense).
      • Replace author: placeholder.
      • Replace maintainer: placeholder.
      • Update copyright: placeholder.
      • Update git: URL placeholder (e.g., to https://github.com/your-username/your-repo-name.git).
      • Update description: placeholder (ensure link points to your final repo URL).
    • Core Documentation:
      • Adapt/replace docs/mission-statement-template.md with your project's mission. (Consider renaming the file).
      • Adapt/replace docs/operational-context-template.md with your project's context. (Consider renaming the file).
      • Adapt/replace docs/user-experience-spec-template.md with your project's UX spec. (Consider renaming the file).
    • Review Configuration (Optional but Recommended):
      • Review dependency versions in package.yaml.
      • Review enabled GHC extensions in package.yaml.
      • Review ghc-options in package.yaml for library, executable, and tests.
      • Review linting rules in hlint.yaml.
  6. Build the project:

    cabal build
  7. Run the test suite:

    # On Windows
    test.bat
    
    # On Linux/macOS
    ./test.sh

Project Structure

project-root/
├── app/
│   └── Main.hs                  - Application entry point
├── src/                           - Source code
│   ├── Control/                   - Effect management and error handling
│   │   └── Error.hs              - Unified error handling framework
│   ├── Data/                      - Core data types and pure implementations
│   │   ├── NonEmptyText.hs       - Non-empty text type with compile-time verification
│   │   └── VerifiedText.hs       - Example of runtime validation for refined types (NonEmptyText)
│   ├── Domain/                    - Domain types with business rule validation
│   └── Config/                    - Application environment and configuration
│       ├── AppEnv.hs             - Environment composition
│       └── AppM.hs               - Application monad with error handling
├── test/                          - Test suite
│   ├── Spec.hs                    - Test entry point
│   ├── Control/                   - Tests for effect management
│   ├── Data/                      - Tests for data types
│   ├── Config/                    - Tests for configuration
│   └── TestUtils/                 - Test utilities and generators
│       ├── AppEnvGenerator.hs     - Test environment generators
│       └── ErrorAssertions.hs     - Error testing utilities
├── docs/                          - Documentation
│   ├── mission-statement-template.md   - Project purpose template
│   ├── operational-context-template.md - System constraints template
│   ├── user-experience-spec-template.md - User experience specification
│   └── guides/                    - Implementation guides
│       ├── idiomatic-error-handling-guide.md - Error handling patterns
│       └── math-notation-guide.md - Mathematical documentation standards
├── .cursor/rules/                 - Cursor AI coding assistant rules
│   ├── code-quality.mdc           - Code quality standards
│   ├── formal-verification.mdc    - Verification requirements
│   ├── idiomatic-error-handling.mdc - Error handling patterns
│   ├── module-architecture.mdc    - Module organization rules
│   └── no-linter-suppressions.mdc - Linter compliance requirements
├── .vscode/                       - VS Code configuration
│   ├── settings.json              - Editor settings
│   └── launch.json                - Debugger configuration
├── package.yaml                   - Package definition (source of truth)
├── cabal.project                  - Cabal project configuration
├── hlint.yaml                     - HLint configuration
├── test.bat                       - Windows test script
└── test.sh                        - Linux/macOS test script

Development Workflow

Build Commands

# Build all components
cabal build

# Run tests (important: use the test scripts for proper .tix file handling)
# On Windows:
test.bat
# On Linux/macOS:
./test.sh

# Interactive development with REPL
cabal repl

Testing

The project uses Hspec for testing with support for property-based tests via QuickCheck. The recommended way to run the full test suite is using the provided scripts: # On Windows: test.bat # On Linux/macOS: ./test.sh

For more specific test runs, you can use cabal test directly:

# Run tests with detailed output
cabal test --test-show-details=direct

# Run specific tests with pattern matching
cabal test --test-option='--match' --test-option="PATTERN"

# Run only focused specs (marked with 'fit' or 'focus')
cabal test --test-option='--focused-only'

# Rerun failed tests
cabal test --test-option='--rerun'

# Reproducible test runs with specific seed
cabal test --test-option='--seed' --test-option=SEED_NUMBER

Core Template Components

Error Handling System

The template implements a robust error handling approach that:

  • Makes errors explicit in function signatures
  • Provides rich context for debugging
  • Maintains pure error handling in domain logic
  • Preserves referential transparency
-- Core error type with rich context
data AppError = AppError
  { errorMessage :: !Text        -- Human-readable message
  , errorContext :: !Text        -- Function or operation name
  , errorDetails :: !(Map Text Text) -- Additional debugging info
  , errorCallStack :: !CallStack -- Source location tracking
  }

-- Application monad with error handling
type AppM a = ExceptT AppError IO a

-- Pure validation with explicit errors
validateInput :: Input -> Either AppError ValidInput

Formal Verification

LiquidHaskell refinement types express invariants at compile time:

-- Example refinement types
{-@ type NonNegative a = {v:a | v >= 0} @-}
{-@ type Percentage = {v:Double | 0.0 <= v && v <= 1.0} @-}
{-@ type SizedList a n = {v:[a] | len v == n} @-}

-- Functions with refinement type specifications
{-@ dividePositive :: Positive Double -> Positive Double -> Positive Double @-}
dividePositive :: Double -> Double -> Double
dividePositive x y = x / y

Domain-Driven Design

Domain types with built-in validation:

-- Smart constructor with validation
mkEntityId :: Text -> Either AppError EntityId
mkEntityId txt =
  if isValidEntityId txt
    then Right (EntityId txt)
    else Left $ mkAppError "Invalid entity ID" "mkEntityId"
           (Map.singleton "value" txt)

Extending the Template

To adapt this template for your specific domain:

  1. Define your domain types in the src/Domain/ directory

    • Use smart constructors with validation
    • Apply LiquidHaskell refinements for invariants
    • Follow the error handling patterns
  2. Create components following the module architecture

    • Domain components for pure business logic
    • Integration components for external systems
    • Follow the hexagonal architecture pattern
  3. Implement test coverage for all components

    • Unit tests for basic functionality
    • Property tests for mathematical properties
    • Consider state machine testing for complex behaviors
  4. Document architectural decisions

    • Update the mission statement with your project's purpose
    • Define your operational context
    • Specify your user experience requirements

Documentation and Standards

This template includes comprehensive documentation:

  • Mission Statement Template: Define your project's purpose and goals
  • Operational Context Template: Specify your system's constraints and boundaries
  • User Experience Specification Template: Document interaction patterns and interfaces
  • Idiomatic Error Handling Guide: Learn best practices for error management
  • Mathematics Notation Guide: Standards for mathematical documentation
  • Code Quality Rules: Comprehensive standards for code quality
  • Module Architecture Rules: Guidelines for module organization

License

This project is released into the public domain under the Unlicense - see the LICENSE file for details.

About

Industrial-grade Haskell project template for mission-critical systems. Features formal verification (LiquidHaskell), robust error handling, hexagonal architecture, TDD, and AI-assistant rules (Cursor)

Topics

Resources

License

Stars

Watchers

Forks

Languages