Skip to content

feat(haskell): add tree-sitter-haskell language support#1439

Open
alexbiehl wants to merge 1 commit into
Graphify-Labs:v8from
alexbiehl:feat/haskell-support
Open

feat(haskell): add tree-sitter-haskell language support#1439
alexbiehl wants to merge 1 commit into
Graphify-Labs:v8from
alexbiehl:feat/haskell-support

Conversation

@alexbiehl

Copy link
Copy Markdown

Adds Haskell (.hs) as a first-class extracted language, following the existing LanguageConfig/_extract_generic pattern (modeled on Kotlin).

What's included

  • tree-sitter-haskell>=0.23,<0.24 as a core dependency (abi3 wheels exist for all platforms).
  • _HASKELL_CONFIG — maps data_type/newtype/type_synomym/class/instance → containers, function/bind → functions, import → imports, apply/variable/qualified → calls.
  • _import_haskell — reads the import node's module field (Haskell-specific; Kotlin uses path).
  • A Haskell branch in walk_calls — Haskell application nests (f x yapply(apply(f, x), y)), so it descends the leftmost function field for the direct callee, and also treats bare variable/qualified leaves as calls so higher-order uses (the area in map area xs) attribute to the caller.
  • extract_haskell, .hs in _DISPATCH, .hs in detect.CODE_EXTENSIONS.
  • Fixture tests/fixtures/sample.hs + 7 tests (skipif when the grammar is absent).

Two grammar gotchas handled

  1. In tree-sitter-haskell a function type (Shape -> Double) is also a function node (nested under signature). A naïve config emits a spurious Double() "function". Fixed by name_fallback_child_types=() so type-level nodes (which lack a name field) are skipped. Regression test included.
  2. type_synomym is the grammar's real (misspelled) node-type string — kept verbatim, not "corrected".

Verification

  • 7 Haskell tests pass; full test_languages.py = 257 passed, 13 skipped (optional tree-sitter-dm), no regressions.
  • Exercised on a large real Haskell codebase (~470 .hs files): clean parse, with data types, classes, functions, imports, and cross-function call edges (e.g. updateS7TagMonitor → resolveUpdateDataType).

🤖 Generated with Claude Code

Wire Haskell (.hs) into the extractor: _HASKELL_CONFIG, _import_haskell, a
Haskell branch in walk_calls for nested `apply` application + higher-order
references, extract_haskell, _DISPATCH/.hs registration, CODE_EXTENSIONS, the
tree-sitter-haskell core dep, a fixture, and 7 tests.

Verified on the pulse repo: 471/472 real .hs files extract cleanly (the lone
gap, Password.hs, is a pre-existing file-node-id collision bug under
investigation, not a Haskell-extractor issue).

Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant