Haskell has long offered an unusual combination of expressive types, strong correctness guarantees, and high-performance native code. Yet despite its maturity and proven use in demanding production systems, the language still faces challenges around tooling, education, ecosystem accessibility, and broader industrial adoption.
In this interview, we discuss what needs to change for Haskell to reach more developers and companies, and where the Haskell Foundation can have the greatest impact. We also look at Haskell from the perspective of a large financial system at Bitnomial: how type safety and effect tracking help engineers manage correctness at scale, where the complexity budget for advanced types should be spent, and why technologies such as Servant remain powerful tools for moving guarantees from individual applications to entire systems.

You recently became Chair of the Haskell Foundation at a particularly important moment: the Foundation is moving away from having an executive director and toward a new structure with a committee responsible for shaping a unified technical vision. From your perspective, what are the most important problems the Haskell ecosystem needs to solve over the next three to five years, and where can the Foundation make a difference that individual companies or open-source maintainers cannot?
We need to lower the friction of using, or trying, Haskell. Haskell is a great language. It has genuine advantages in commercial settings. It has a solid ecosystem of third-party packages for a wide variety of use cases. Experts are generally productive. But there are two points that consistently come up as problems, especially in industry.
Number one is about tooling. Haskell has good tooling, actually – so, so much better than a decade ago, when I started – with active projects like GHC, Cabal, Ormolu, HLint, GHCUp, and Haskell Language Server continuously improving, just to name a few. But the needle has moved, and tooling is expected to be great and cohesive. Communities that are ten times larger have poured ten times more effort and money into their tooling. These communities have sanded the rough edges, and it shows in a generally robust and pleasant experience.
Number two is education. The Haskell community is more than 35 years old. There’s a lot of knowledge scattered about in research papers, blog posts, user guides, and most importantly, people’s heads. And yet, a point of feedback I keep hearing is that people are often unsure or unaware of some recommended way to do something. What’s the best, up-to-date way to profile a Haskell application? What about speeding up builds in continuous integration in 2026? Should I use singletons here? How do I structure my application to support logging?
The Haskell Foundation is uniquely positioned to make a difference on both of those fronts, but the way in which it can be effective is different from other organizations. Do you need specific work done on GHC? That’s Serokell’s domain. Do you want generally faster builds? That’s a broader challenge, where it doesn’t necessarily make sense for a single organization to tackle, while everyone benefits. That’s where the Haskell Foundation can coordinate efforts and make the Haskell community better off.
You’ve said that one of your goals is to expand Haskell’s reach in industry, and today you work at Bitnomial, whose backend is built entirely in Haskell. After seeing Haskell from both the community and production sides, what do you think actually prevents more companies from adopting it: the learning curve, tooling, hiring, ecosystem maturity, perceived business risk, or something else?
From an industrial perspective, the barriers to using Haskell are things that slow development down. I mentioned some of these things in the previous question, but let me put a more in-the-trenches perspective on it here.
A common issue I have faced is the ecosystem of third-party bindings. A lot of programming these days is plumbing data from one service to another. Chances are, if one of these services is even a little niche, you’re going to need to put in quite a bit of work to get that working! Bitnomial maintains a relatively large set of bindings to third-party services and technologies, some of which are quite tricky to get right (looking at you, FIX). This issue isn’t specific to Haskell, but rather to smaller communities.
Another issue I keep seeing is about knowledge of the tooling. There are wonderful facilities to profile and debug Haskell code. However, knowledge of these facilities has not been disseminated as well as one would hope! For example, I keep introducing people, at Bitnomial and beyond, to the GHC eventlog, a critical piece of technology for anything related to the runtime performance of Haskell programs. In practice, this means that it’s a little harder to get high-performance and robust systems in Haskell than it should be, and that slows things down as well. This is entirely fixable, although it’s not clear to me what the best way to address this is. One more blog post isn’t going to do the job.
I have not personally witnessed pushback at the business level, and I guess that this is simply because Haskell isn’t visible to non-engineers. For management, the differences between e.g. Rust and Haskell don’t matter, as long as development velocity is high.
What advantages does Haskell offer a business like Bitnomial?
Bitnomial runs a financial exchange, clearinghouse, and brokerage, supporting trading and clearing operations on millions of trading accounts, in a regulatory environment which is rapidly evolving. This requires a technology platform that simultaneously provides correctness guarantees (as we handle money), excellent runtime performance, and high iteration speed. Haskell is a total package that has these properties, in a way that very few other tech stacks, if any, can provide.
Since Payward’s acquisition of Bitnomial, we have started to lean even more in Haskell’s type system to provide better correctness guarantees where it makes the most sense – usually at system boundaries. For example, we are heavy users of the type-level API domain-specific language Servant, and are leaning into it more and more every day.
At the same time, we are investing time (specifically, much of mine) in runtime performance and scalability. The runtime performance achievable for Haskell software compiled with GHC never ceases to amaze me. I’m also happy to report that tooling around profiling is quite good, although, as I mentioned in a previous answer, the existence of these tools isn’t particularly well-known.
Bitnomial engineers are able to work on all of this without sacrificing their ability to quickly deliver and iterate on features for our customers. The team remains confident in changing entire systems within our software while keeping the number of bugs minimal. This was true before LLMs, and our velocity has only increased since.
Your Haskell Ecosystem Workshop talk is titled “Servant at Bitnomial — Expanding type-safety from applications to systems.” Where do you think the boundary of useful type safety lies in a real financial system? How far can invariants be pushed into types before the abstractions begin to impose unacceptable complexity on developers?
More type-safety encodes more implicit information. This is taken to the next level with Haskell’s forced tracking of side-effects. In a way, more type-safety reduces cognitive load – the amount of information that a developer needs to hold in their head at any given time. However, I agree that many techniques that improve type-safety also increase the amount of information required to interact with this code. It’s not always clear if the cognitive load is net-reduced.
One way to bypass the complexity of more type-safety is encapsulation. GHC extensions are scoped to single modules, so it’s entirely possible to implement interfaces which, internally, are based on strong type-safe guarantees, but that keep a pleasant developer experience. For example, a colleague of mine, Solomon Bothwell, has been working on role-based permissioning of Servant endpoints. On the surface, the developer experience is straightforward, but it is internally powered by singleton types!
Sometimes, exposing the complexity is unavoidable. Ultimately, to decide when additional explicit type-safety is worth the complexity cost, I have settled on something based on Jeff Bezos’ one-way vs. two-way door analogy. If extra type-safety prevents unrecoverable issues – such as security vulnerabilities, or data loss or corruption – I am more than happy to pay for the complexity cost. If extra type-safety prevents recoverable issues – such as data loss in a caching system – then it is acceptable to compromise, and spend the complexity budget elsewhere.
In your “Servant by Construction” series, you deliberately rebuild parts of Servant to demystify advanced type-level programming. Haskell is often praised for abstractions that make invalid states unrepresentable, but those same abstractions can make a codebase difficult for newcomers to understand. What have you learned about designing sophisticated typed systems that remain approachable, debuggable, and maintainable by an engineering team?
Designing a sophisticated system that eliminates invalid states at compile-time should follow the same guideline as for the design of any domain-specific language: build a system out of small composable parts with orthogonal concerns, with hooks for extensibility built-in. The rest is about great documentation.
I don’t believe that there are concepts that are too difficult to understand. Software development is knowledge work. Learning is expected. The onus is on the expert to make the learning easy. Different developers learn differently, so I like to provide documentation that takes a few different forms, including user-guide-style documents, multiple examples, and internal dissections. The Servant by Construction blog series is a series that I wrote for my coworkers, precisely to encourage them to tinker with Servant.
Your background spans experimental physics, scientific computing, quantitative research, energy infrastructure, and now exchange and clearinghouse software. How has moving between these domains changed the way you think about correctness?
It’s not a coincidence that my career has taken the path it has. All domains where I studied and worked value precision and correctness highly.
In graduate school, correctness was important because mistakes might set me back months, or even in some extreme cases years, behind schedule. Moving into the workforce changed the stakes, where I have seen bugs have calamitous financial impacts.
The major shift that occurred in my mind regarding correctness didn’t come from changing domains; it came from the move from writing software alone, to writing software as part of a team. Correctness is much harder to achieve, and enforce, in an environment where context is shared.
As a lone wolf, as it were, I have my own idiosyncrasies, but I also have the full context of everything I do. This makes it easier to enforce invariants which are implicit. As a team, part of the context is explicit (for example, due to shared domain knowledge or documentation), but much of the context remains implicit. Enforcing correctness implies making as much of the implicit context, explicit, as possible.
This is where a strong type system and side-effect-tracking, like Haskell provides, makes all the difference in the world. I try to put as much context as I can in types – where it makes within my complexity budget, as per my previous answer.
Are there lessons from scientific computing that mainstream software engineering should integrate?
One thing that comes up again and again in scientific computing is the elasticity of resources. Your program may run on a cluster of 4 nodes, or a thousand nodes. It may run for minutes, or weeks. This necessarily implies writing flexible software that scales appropriately to the resources available. Today’s modern computers provide the capabilities for parallel computing on the CPU, but also now on compute accelerators like graphical processors (GPUs) and tensor processors (TPUs). Apart from specific domains like machine-learning and scientific computing, parallel programming isn’t as visible as it perhaps should be.
I get it. Writing parallel and concurrent software is hard. Very hard! In many popular domains, like web development, the parallelization can be sometimes hidden (forking to handle each request, for example), but this is not a general solution. Programming languages like Haskell, that have control over side-effects, are perfect for this use-case. At the risk of causing some eye rolls due to this point being hammered so much in the community: software transactional memory is unparalleled in its ability to simplify complex synchronizations between parallel threads. At the same time, software transactional memory remains rare because it’s almost impossible to get right outside of programming languages that track side-effects, like Haskell.
You have explored typed dimensions for scientific computing, type families for trading features, and higher-kinded types for dataframe-like structures. Why do you think Haskell has never achieved the same position in data science and numerical computing that Python or Julia have, despite its ability to express domain constraints so precisely? What would need to change for Haskell to become genuinely competitive there?
Decades ago, Python became popular in the scientific community because it was straightforward for non-programmers to be productive quickly. This led to, ultimately, a first open-source and easy-to-use stack for numerical and scientific computing in NumPy, SciPy, and Matplotlib. Many people, myself included, could not wait to jump from MATLAB to Python for this reason. It didn’t help that MATLAB was closed-source. Over time, the Python ecosystem grew so much that today’s data scientists would be foolish to use anything else, except in some specific domains. It’s rather telling that new programming languages like Mojo specifically target Python’s syntax; everyone is just so familiar with it!
Haskell is a completely different beast. The emphasis is on correctness and expressivity, not necessarily a fast onboarding. It’s also rather alien-looking for non-programmers. Over 20 years, the compounding ecosystem growth that Python has seen in the data science space, has left Haskell in the dust, due to no fault of its own, really.
To carve itself a niche in this space today, Haskell needs two things.
First, Haskell needs to achieve a baseline of usability for the non-programmer. Regardless of domain, technical computing is concerned with out-of-the-box high-performance numerical routines, interactive notebooks, plotting, and support for a wide variety of somewhat specific data formats. I’ve been happy to see a revival of the DataHaskell group, led by Michael Chavinda, who are working on this front; I encourage people to check them out!
Second, it needs a killer app, as it were. It needs to make people think “There’s something important I need to achieve, and Haskell is the best way to achieve it”. If only I knew what that could be. Haskell is a great language in which to implement domain-specific languages, embedded or not. Is that where Haskell can make its mark in data science, with something like the Accelerate project?
You maintain or contribute to projects across very different parts of the ecosystem, including Cloud Haskell, Beam, and Hakyll, while also working in industry and leading the Haskell Foundation. Looking across the ecosystem as a whole, which Haskell ideas or technologies do you believe are genuinely underappreciated today: things that could influence mainstream software engineering much more broadly over the next decade?
The obvious answer to me is control over side effects, which in Haskell is usually referred to as “mathematical purity”. This idea has already caught on in languages that have become much more popular than Haskell, such as in Rust via the borrow-checker. This is something that’s often talked about – how new languages like Rust have borrowed (pun intended) a lot from Haskell.
I’d like to point to another place where purity has been highly beneficial. Over the machine-learning revolution of the past 15 years, we’ve seen new domain-specific languages like Jax, Futhark, and Halide, that use purity to enable much higher-performance array-oriented programming, that run on a wide variety of platforms – CPU, GPU, and TPU. In today’s generative AI boom, there’s no better endorsement of the idea of purity.
In general, effect systems are going to disseminate. I just don’t know when. We’re going to look back in 20 years and say “why the hell didn’t this move into the mainstream decades ago?”.
.png)

