hx lint

Run the Haskell linter.

Synopsis

hx lint [OPTIONS] [FILES]...

Description

The lint command runs HLint on your Haskell source files, identifying potential improvements and style issues.

Arguments

FILES...                Files to lint (default: all .hs files)

Options

    --fix               Auto-apply safe suggestions
    --hint <FILE>       Additional hint file
    --ignore <HINT>     Ignore specific hints
    --json              Output as JSON
    --report <FILE>     Generate HTML report
-v, --verbose           Show detailed output

Examples

Lint All Files

hx lint

Lint Specific Files

hx lint src/MyModule.hs

Auto-Fix

hx lint --fix

Ignore Hints

hx lint --ignore "Use newtype instead of data"

JSON Output

hx lint --json

HTML Report

hx lint --report lint-report.html

Sample Output

src/MyLib.hs:15:5: Warning: Use fmap
Found:
  do x <- getLine
     return (f x)
Perhaps:
  f <$> getLine

src/MyLib.hs:23:1: Suggestion: Eta reduce
Found:
  foo x = bar x
Perhaps:
  foo = bar

2 hints

Hint Categories

Error

Must be fixed:

Use otherwise, not True

Warning

Should be fixed:

Use fmap
Use <$>
Redundant bracket

Suggestion

Consider fixing:

Eta reduce
Use when
Use unless

Auto-Fix

hx lint --fix automatically applies safe suggestions:

hx lint --fix

Before:

foo x = bar x

After:

foo = bar

Only suggestions marked as safe are applied automatically.

Configuration

hx.toml

[lint]
# HLint options
extra-hints = [".hlint.yaml"]

# Ignored hints
ignore = [
  "Use camelCase",
  "Reduce duplication"
]

.hlint.yaml

Create custom hints:

# Ignore specific warnings
- ignore: {name: "Use fmap"}
- ignore: {name: "Eta reduce", within: [Tests]}

# Custom hints
- warn: {lhs: "map head (map tail x)", rhs: "map (head . tail) x"}

# Module-specific rules
- modules:
  - {name: Data.Map.Strict, as: Map}
  - {name: Data.Set, as: Set}

Ignoring Hints

In Source Code

{-# HLINT ignore "Use fmap" #-}

-- or for specific expression
foo = bar  {- HLINT ignore -}

In Configuration

# .hlint.yaml
- ignore: {name: "Use fmap"}
- ignore: {name: "Redundant bracket", within: [ParserModule]}

Via Command Line

hx lint --ignore "Use fmap" --ignore "Eta reduce"

Common Hints

HintBeforeAfter
Use fmapdo x <- m; return (f x)f <$> m
Use <$>fmap f mf <$> m
Eta reduce\x -> f xf
Use whenif b then m else pure ()when b m
Use unlessif b then pure () else munless b m
Redundant bracket(f x)f x

CI Integration

- name: Lint
  run: hx lint

# Or fail on warnings
- name: Lint (strict)
  run: hx lint --json | jq '.[] | select(.severity == "Warning")'

Editor Integration

VS Code

HLint integrations show hints inline.

Vim

With ALE:

let g:ale_linters = {'haskell': ['hlint']}

See Also