This is the thirtieth edition of our Haskell ecosystem activities report, which describes the work Well-Typed are doing on GHC, Cabal, HLS and other parts of the core Haskell toolchain. The current edition covers roughly the months of December 2025 to February 2026.
You can find the previous editions collected under the haskell-ecosystem-report tag.
Sponsorship
We offer Haskell Ecosystem Support Packages to provide commercial users with support from Well-Typed’s experts while investing in the Haskell community and its technical ecosystem including through the work described in this report. To find out more, read our announcement of these packages in partnership with the Haskell Foundation. We need funding to continue this essential maintenance work!
Many thanks to our Haskell Ecosystem Supporters: Standard Chartered, Channable and QBayLogic, as well as to our other clients who also contribute to making this work possible: Anduril, Juspay and Mercury; and to the HLS Open Collective for supporting HLS release management.
Team
Matthew Pickering announced that he will be leaving the company and moving to a non-Haskell
role at the end of March.
Working with Matt has been a joy – more than his deep technical insight
or sharp intuition, it’s the warmth of his vision for how to work together and
his generosity that has made him such a force within the team.
He was also a beacon that could rally the community in difficult times, perhaps
most memorably with his technical and social contributions in consolidating
Haskell IDEs with the creation of the Haskell Language Server.
His dedication to tooling has also been an inspiration, with his work on
ghc-debug and on profiling an invaluable contribution to our understanding
of memory usage of Haskell programs.
The Haskell toolchain team at Well-Typed currently includes:
- Andreas Klebinger
- Hannes Siebenhandl
- Magnus Viernickel
- Mikolaj Konarski
- Rodrigo Mesquita
- Sam Derbyshire
- Zubin Duggal
In addition, many others within Well-Typed contribute to GHC, Cabal, HLS and other open source Haskell libraries and tools. This report includes contributions from Alex Washburn, Duncan Coutts, Wen Kokke and Wolfgang Jeltsch in particular.
We are active participants in community efforts for developing the Haskell language and libraries. Rodrigo joined the GHC Steering Committee in December, alongside Adam Gundry. Wolfgang joined the Core Libraries Committee in February.
Highlights
Interactive step-through debugging
The Haskell Debugger (hdb) has been made more robust and more features were implemented by Rodrigo, Matthew, and Hannes.
Most notably, the debugger now:
- Displays stack traces for bytecode and compiled code frames (provided the program and dependencies were compiled with
-finfo-table-mapfor the latter) - Displays source locations and callstacks for exception breakpoints
- Uses the external interpreter by default
- Can be run on GHC itself!
To run hdb you need to use GHC 9.14 and to configure the IDE accordingly. Please refer to the installation instructions. Apart from that, if HLS just works on your codebase, so should the debugger!
Live monitoring using the eventlog
GHC’s eventlog already lets Haskell programs emit rich runtime telemetry, but
the workflow has historically been to run the program to completion and inspect
the eventlog afterwards. eventlog-live
allows us instead to monitor the program as it is running. Wen continued work on
this project, taking significant steps towards making it production-ready, including:
extending
eventlog-livewith support for the OpenTelemetry protocol (#119),bringing the underlying
eventlog-socketlibrary closer to being ready for general use, by adding a testsuite (#27). fixing a litany of issues with the C code (#38), and finalising the user-facing API (#43),adding support for custom commands in
eventlog-socket(#36).
Trees That Grow
The Language.Haskell.Syntax module hierarchy is intended to be a stable,
public API for the Haskell AST — one that external tools could eventually depend
on without coupling themselves to GHC internals, reducing ecosystem breakage.
Right now, that goal is undermined by lingering dependencies on internal modules
under the GHC hierarchy.
Alex, with help from Rodrigo, has been systematically removing these edges in the dependency graph:
Language.Haskell.Syntax.Typeno longer dependsGHC.Utils.Panic(!15134, #26626).Language.Haskell.Syntax.Declsno longer depends onGHC.Unit.Module.Warnings(!15146, #26636), nor onGHC.Types.ForeignCall(!15477, #26700) orGHC.Types.Basic(!15265, #26699).Language.Haskell.Syntax.Bindsno longer depends onGHC.Types.Basic(!15187, #26670).
Once this work is done, it will be possible to consider moving the AST into a separate package, and taking further steps towards increasing modularity of the compiler.
Towards a standalone base package
Historically, the base package was used as both the user-facing standard
library and a repository of GHC-specific internals, with much special treatment
in the compiler. This means GHC and base versions are tightly coupled, and
makes upgrading to new compiler versions unnecessarily difficult.
GHC developers have made significant progress towards making base a normal Haskell
package: ghc-internal has been split out as a separate library, base no
longer has a privileged unit-id in the compiler, and Cabal now allows
reinstalling it.
Matt posted a summary of progress and outlined possible next steps to seek community consensus on the direction of travel. The reinstallable-base repository collects documents and discussion on the effort.
Wolfgang continued various pieces of technical groundwork:
cleaning up many unused known-key names in the compiler (!15184, !15190, !15211, !15213, !15217, !15218, !15219, !15215),
finishing the process of removing
GHC.Desugarfrombase(!15433),refining the import list of
System.IO.OSto aid in modularity (!15567).
Wolfgang improved the public API of base relating to OS handles, to make the
API more stable across platforms and avoid the need for users to depend on
GHC-internal implementation details (!14732, !14905). While in the area, he
fixed a bug in the implementation of hIsReadable and hIsWritable for duplex
handles (#26479, !15227), and a mistake in the documentation of hIsClosed
(!15228).
Incorrect absence analysis in GHC
GHC bug #26416 has occupied the attention of the team for quite some time. Initially thought to be an issue with specialisation, a reproducer that Sam and Magnus created showed that the issue is in fact a bug in absence analysis — an optimisation that identifies and removes unused function arguments — in which GHC would erroneously conclude that a used argument was in fact absent.
Andreas helped investigate the root cause, before Zubin finally took the torch and put up a solution (!15238).
GHC changelogs
GHC’s changelogs have not always been as complete or reliable as the community deserves. Keeping changelogs accurate across backports has also been a major source of frustration for release managers.
This is why, after a discussion initiated by Teo Camarasu in #26002, we have decided
to adopt the changelog.d system —
already in use by the Cabal project — in which each change is a separate file
in the changelog directory.
This eliminates the merge conflicts that make backporting painful, and makes it
easier to associate MRs with changelog entries.
Zubin has been spearheading the effort, with the intention to switch to this new method of changelog generation right after the fork date for GHC 10.0.
GHC
GHC Releases
- Zubin worked on 9.12.3, backporting patches and preparing release candidates, with a final release on the 27th of December.
- Magnus and Zubin worked on backports for 9.12.4.
- Zubin worked on 9.14.1, putting out the final release on the 19th of December.
Frontend
Sam reviewed the implementation of the
QualifiedStringsextension by Brandon Chinn (!14975). This allows string literals of the formModName."foo"(interpreted asModName.fromString ("foo" :: String)).Sam made several changes to the treatment of
Coercibleconstraints in the typechecker (!14100):- Defaulting of representational equalities to nominal equalities, functionality previously added to GHC by Sam, is now more robust (#25825).
- Error messages involving unsolved
Coercibleconstraints are greatly improved, an oft-requested improvement (#15850, #20289, #23731, #26137). Error messages now consistently mention relevant out-of-scope data constructors, provide import suggestions, and include additional explanations about roles (when relevant).
Magnus implemented several fixes to the implementation of
ExplicitLevelImports:Sam improved the reporting of “valid hole fits”, adding support for suggesting bidirectional pattern synonyms (#26339) and properly dealing with data constructors with linear arguments (#26338).
Sam investigated a typechecking regression starting in GHC 9.2 with the introduction of the
Asserttype family to improve error messages involving comparison of type-level literals (#26190), posting his analysis to the ticket. To tackle this, he opened GHC proposal #735, which is still in need of further community feedback.Sam minimised a bug with rewrite rules (#26682), which allowed Simon Peyton Jones to identify and fix the bug (!15208).
Sam improved how existential variables are displayed in Haddock documentation (!15099, #26252).
Determinism
- Matt identified and fixed several ways in which GHC compilation was not deterministic:
- an issue with non-deterministic documentation information (#26858, !15482).
- non-determinism of constraint solving impacting generated
Typeableevidence (#26846, !15442). - issues with the Template Haskell machinery of the
singletonslibrary producing non-deterministic names (singletons#629,th-desugar#240).
Plugins
Sam finished up and landed a long-standing MR by Chris Wendt (!10133) which fixed a plugin-related issue.
Sam fixed a regression in
ghc-typelits-natnormalisein which the plugin would cause GHC to fall into an infinite loop (ghc-typelits-natnormalise#116, #118).
Backend
Rodrigo announced that work described in #23218 evolved into the POPL 2026 paper “Lazy Linearity for a Core Functional Language”, which presents a way to type linearity in GHC Core that is robust to almost all GHC optimisations, together with a GHC plugin validating programs at each optimisation stage.
With the oversight of Andreas, Sam carefully reconsidered the treatment of register formats in the register allocator and liveness analysis. This culminated in !15121:
- Keep track of register formats in liveness analysis (#26526).
- Use the right format when reloading spilled register (#26411).
- Enforce the invariant that writes to a register re-defined the format that
this register is used at for the purposes of liveness analysis, fixing another
bug reported by
@aratamizukion !15121.
Sam put up a small fix for the mapping of registers to stack slots, fixing an oversight in the case that registers start off small and are subsequently written at larger widths (#26668, !15185).
Sam reviewed a GHC contribution by
@sgillespieadding SIMD primops forabsandsqrtoperations (!15236), suggesting more efficient implementations of certain operations.Andreas investigated potential missed specialisations, which allowed Simon Peyton Jones to make further progress in improving the specialiser (#26831, !15441).
Sam investigated several bugs to do with the interactions of join points with ticks (#14242, #26157, #26642, #26693) and casts (#14610, #21716, #26422). He fixed the main bug (#26642, !15538), which was due to incorrect transformations in
mergeCaseAlts. He also undertook a general refactor of the area and, pinning down the overall handling of casts and ticks under join points in a Note.
Runtime system and linker
Matt fixed a decoding failure for
stg_dummy_retby usingINFO_TABLE_CONSTRfor its closure (#26745, !15303).Duncan fixed long-standing inconsistencies in eventlog
STOP_THREADstatus codes (#26867, !15522).Andreas improved the documentation of the
-KRTS flag in !15365 (#26354).
Exception backtraces, stack annotations and stack decoding
Matt and Hannes improved the reporting of backtraces when using
error(!15306, !15395, #26751). This involved opening two CLC proposals (CLC #383, CLC #387).Hannes continued working on the implementation of stack annotations and stack decoding (#26218), including:
- integrating
ghc-stack-profiler, a profiler that relies on stack annotations instead of heavier profiling mechanisms, with theeventlog-socketlibrary; and - working on the
ghc-stack-annotationscompatibility library for annotating the stack.
- integrating
Rodrigo removed an incorrect assertion that fired when decoding a BCO whose bitmap has no payload (#26640, !15136).
Build system and packaging
Zubin fixed a GHC 9.14.1 build issue due to missing
.cabalfiles forghc-experimentalandghc-internalin the source tarball (#26738, !15391).Andreas investigated the use of Cabal’s
--semaphorefeature to speed up GHC builds slightly (#26876, !15483). There are some issues preventing us from enabling this unconditionally (#26977,Cabal#11557).
CI and testing
Magnus ensured the user’s guide can be generated with old versions of Python to fix CI build failures on some older containers (!15127).
Magnus updated the Debian images used for CI (
ci-images!183, !178).Sam finished up the work of Sven Tennie on testing floating point expressions in the
test-primopstest framework for GHC (test-primops!19). This is preparatory work for improving the robustness of GHC’s handling of floating point (#26919).Andreas updated the
nofibGHC benchmarking suite to fix issues that Sam ran into when trying to use it, updating the CI in the process (nofib!81, !82, !83).
Infrastructure
Magnus worked on the infrastructure for the GitLab instance used for the GHC project, bringing up new runners for CI and switching to a new verification system to approve new users which makes it easier for new contributors to open issues.
Magnus and Andreas helped the Haskell infrastructure team address Gitlab outages on short notice in order to improve availability of the GHC Gitlab instance.
Andreas and Magnus organized temporary CI capabilities sponsored by WT during a temporary outage of one of GHC’s CI runners.
Cabal
Sam added support for setting the logging handle via the library interface of
Cabal, a significant milestone in updatingcabal-installto compile packages with theCaballibrary without invoking external processes (Cabal#11077).Matt helped Matthías Páll Gissurarson to fix a bug in which
cabal haddockwas looking for files in the wrong directory (Cabal#11475, #11476).Matt fixed a bug with broken Haddocks locally due to non-expanded
${pkgroot}variable (Cabal#11217, #11218).Matt fixed some issues with
cabal replsilently failing (Cabal#11107, #11237).
HLS
In collaboration with Zubin and Andreas, Hannes investigated the root cause of HLS issue #4674, posting his analysis in this comment. In short, the problem was that the
hlintplugin was using an incompatible version ofghc-lib-parser, and a version mismatch in this library was causing segfaults due to changes to theGHC.Data.FastStringimplementation between the versions. Hannes disabled thehlintplugin on GHC 9.10 to work around this issue (HLS PR #4767).Hannes reviewed and assisted with HLS PR #4856 by
@vidit-od. This PR makes HLS use the stored server-side diagnostics for code actions, in order to make them more responsive. This fixes HLS issue #4805.Hannes helped land long-running HLS PR #4445 by
@soulomoon, which allows files to be loaded concurrently in batches in order to improve responsiveness of HLS.Zubin and Hannes worked together to update HLS to work with GHC 9.14 (HLS PR #4780).
Hannes worked on general maintenance of the HLS project:
- Prepared release 2.13.0.0 (HLS PR #4785)
- Tackled various CI issues (HLS PR #4863, HLS PR #4812, HLS PR #4811)
- Updated the advertised range of supported GHC versions (HLS PR #4801, HLS PR #4799)
Hannes and Zubin implemented some fixes to Windows CI (HLS PR #4800, HLS PR #4768).
Hannes merged the
hls-module-name-pluginintohls-rename-pluginin HLS PR #4847.Hannes improved the robustness of the
hls-call-hierarchy-plugin-testsin HLS PR #4834 by usingVirtualFileTree.Hannes also worked on
hie-bios:- Preparing release 0.18.0.0 (
hie-biosPR #496) - Updated the supported GHC versions (
hie-biosPR #495) - Adapted to GHC migrating some parts of its codebase to use
OsPath(hie-biosPR #493)
- Preparing release 0.18.0.0 (
Haskell Debugger
Rodrigo continued work on the new Haskell Debugger.
Matt and Rodrigo introduced a DSL for evaluation on the remote process, which allows the debuggee to be queried from a custom instance, making it possible to implement visualisations which rely on e.g. evaluatedness of a term (#139).
Matt improved support for exceptions: break-on-exception breakpoints now provide source locations (#165).
Rodrigo allowed call stacks to be inspected in the debugger (#158).
Hannes introduced support for stack decoding and viewing custom stack annotations (#172).
Rodrigo made the Haskell Debugger use the external interpreter (#170), which paves the way for multi-threaded debugging (see also #140). This change also allowed Rodrigo to implement Windows support (#184) with the help of Hannes.
Matt fixed a bug in the handling of data constructors with constraints (#175).
Hannes improved caching in the CI (#173).
ghc-debug
Matt and Hannes fixed several issues with
AP_STACKclosures (!79, !80, !86).Hannes implemented asynchronous heap traversal in
ghc-debug-brick, making the interface more responsive (!78).Hannes added history navigation and search caching to the
ghc-debug-brickinterface (!83).Hannes added a summary row to the string counting table view (!81), and fixed the search limit not being honoured during incremental searches (!76).