Maintaining haskell programs

So I was browsing youtube today watching random videos on programming and I came across this one

It’s a small snippet and I don’t know who Tsoding Daily is, but the comments suggest that he’s authored some good Haskell learning content in the past.
He said he stopped using Haskell because its “a pain in the butt to maintain”. I don’t have enough experience with production level Haskell to have a viable opinion here, but I always assumed maintaining Haskell code was probably a lot easier than most mainstream languages.

So I’m curious, those of you who have been working in this and have maintained programs for a long time, how do you all feel about the maintainability of Haskell applications?

1 Like

It’s hard to respond to the video because there’s no concrete criticism here. Tsoding says:

  1. Haskell is a pain in the ass to maintain
  2. Haskell is beautiful
  3. Cabal and Stack are painful to use
  4. Haskell is written by mathematicians
  5. Haskell is not engineered properly

But it’s not clear what these claims mean. What exactly is painful? What isn’t “engineered” properly? Why does the cons outweighs the pros?

With only this video there really isn’t much I can say that will address these claims.


The video didn’t seem to have a lot of facts, so I’ll focus on the question of maintainability:

As with any other language, you can write pretty unmaintainable code in Haskell. Overusage of non-total functions (head, tail, from Just) can make your program an error minefield, for example. Huge functions with low cohesion, functions/modules that are highly coupled, plenty of ways to create an unmaintainable mess.

Haskell does have plenty of ways to create beautiful, maintainable code too, though. I feel that when used correctly, Haskell is better at writing maintainable code than most other languages. One thing that Haskell is missing, is ubiquitous software architecture knowledge. OOP has patterns, piles of books on how to write good OOP programs. Haskell’s “how to write maintainable software” documentation is much more sparse, and what’s there is much less widely known.

When learning Haskell, I learned about how the type system works, how some functional gems work, how to write parsers, some core principles of compilers, but never really how to structure programs, how to keep coupling low and cohesion high. I already got that with OOP, and that knowledge isn’t always directly transferable.


I’m not looking for the claims he made to be substantiated in any type of way, the video just got me thinking about what the maintenance experience is like; how do experienced devs feel in general about the maintainability of Haskell programs?

Some of the YouTube comments echo the sentiment that the tooling isn’t good, but at this point, I personally don’t have a problem with the it. I think HLS is fantastic and cabal seems to do everything I want it to do. I just setup a dev container and I’m off to the races.

But I’m curious what others think who have been in the trenches for a while

It’s difficult to tell without knowing the explicit problem he faced. I agree the interactions among cabal-ghc-stack-hls might be difficult. For example:

  • if you want to use a non stackage package in a stack project you have to modify stack.yaml and package.yaml/.cabal. This is well documented in stack's user guide, so I am not blaming stack for this, but in general we should warn people that developer do not read documentation at all (hyperbole), so instead of writing a nice user guide is much better to throw a big and explicit error with “you are doing this and that wrong”. I can imagine someone having trouble with this ending up with a mess of environment difficult to maintain.

  • ghc extension ecosystem is a mess. 9 out of 10 times, I don’t know what they do; I just turn them on because the compiler suggest them in an cryptic error message. Moreover, extensions can break other extensions, and compiler updates might change the behaviour of type-level extensions. For example:

    • I’ve been trying to use effectul library recently, It turns out that with GHC2021 extension it doesn’t compile, you have to use Haskell2010 and a bunch of extension. This mean that there is at least one extension within GHC2021 which breaks all other code. The error is something about illegal kind {k}. Please use optimus-prime kind level programming to solve skolem-curry paradox and break the simulation we live on.… yes, I made that up but to me the error message was as cryptic as that (the real error was related to kinds actually)
    • Also, having so many extensions creates some sort of “type system a la carte”, super difficult to undestand and maintain. If you want to use something like vector-sized you must activate many extension and deactivate(!!) others like StarIsType… which is weird because up to the documentation using * as type is legacy, but GHC2021 do include it(?).
  • In my computer hls performs horrible with ghc-9.4.5. Imagine updating the compiler and the language server works… but works very bad.

  • cabal prefers to download new package versions instead of using the one already in the system (is there any flag like --prefer-installed??). If you copy paste code from a project to another within you own computer I might happen that you download different versions in each project leading to compilation fails in the new version, which can’t be ported to the old one. Yes, this is bad user behaviour because we should add dependency bounds in the cabal file, but even then, if your bounds aren’t tight enough, you may end up in this situation

So these are a few example on how maintainbility can be difficult when you update the compiler, or libraries or you simply copy code from other place.


I honestly think Haskell is easy to maintain and the errors I get when upgrading are always trivially solved if you have expertise. The errors are ugly but I survived so many servant tornado error messages I don’t care anymore.


Sadly almost certainly due to PolyKinds. I don’t think error messages were an important enough concern for the decision makers of GHC2021.

Please do report such errors somewhere. For the best reach (directly to all GHC devs), report them to Issues · Glasgow Haskell Compiler / GHC · GitLab. if you don’t like the idea of flooding that, then use GitHub - haskell/error-messages.

GHC2021 includes it becuase it was already part of Haskell2010. So it is not really an “extension” in the sense of adding a feature, but rather a part of the standard that you can disable if you want. Maybe the extension should have been called StarIsNotType (and NoStarIsNotType) but the double negation would be confusiong too.


It’s not missing it. I’ve published two books “Functional Design and Architecture” dedicated to this topic exactly. Seems haskellers prefer to ignore its existence for some reason.


Oh yeah, it’s out there, but not really near the “entrance” of the Haskell world. It’s not as ubiquitous as the design pattern material for OOP that you straight up get in uni classes in the first or second year.

From a quick glance your books look interesting, though I can imagine there are dissenting opinions for the specific choices you made on what to explain. There’s a million ways of doing things in Haskell, and very strong opinions in all directions as to what way is the right way. Specifically mtl versus free monads versus effect systems is fiercely debated.

This is also something I’ve noticed in discussions about Serokell’s certification program: questions like “why these choices for subjects?”. I think with any book, there are going to be a lot of people saying “you should have gone for Y instead of X”.

That said, thanks for writing these books. I think that the questions “what makes a good functional architecture”, and “what are the high level dos and don’ts” are extremely valuable to explore.


Side note: My personal backup program uses GHC2021 and effectful. I don’t recognize these issues. Do you have the latest versions of everything?

1 Like

I find Haskell actually really easy to maintain. The “if it compiles it works” is especially true when refactoring allowing to rewrite confidently bits of code which got overly complex.


I compare maintenance of Haskell programs to gardening:

  • :seedling: When you do it daily, the results are beautiful and the effort is low. Each incremental step is nice and pleasant.
  • :desert: If you forgot about your Haskell package for several years, it might be easier to burn the entire thing to the ground instead of trying to bring it up-to-date.

Hopefully this is not too off-topic, but I’m sad to see Kowainik’s packages like summoner, policeman, and stan wither. I’ve opened a pull request for summoner to update it to support GHC 9.4, but that has seen no response for over a month. Do you need help? I can’t promise anything, but maybe I could help with minimal maintenance like that pull request now and then.


:100: agreed with this :point_up:

Tsoding was undoubtedly aware of the tendency of GHC upgrades to break older programs. Unlike many other compilers, GHC is one of the rare exceptions that not only accepts but also embraces breaking changes. Whenever an issue arises, it is promptly addressed and fixed, rather than leaving older bugs as permanent features to endure.

1 Like

I think it’s slightly off-topic but I haven’t been maintaining any of the Kowainik packages for more than a year and I don’t have plans to return to their maintenance. You should contact current maintainers if you want to offer support and maintenance help.

On a non-off-topic subject, since almost all Haskell packages are maintained by volunteers in their free time for free, it’s unfortunately quite common when people completely stop maintaining Haskell packages with no one to step in. Besides, often it’s impossible to use an older package if it hasn’t been maintained for a while.

Some people stop maintaining Haskell packages party because maintenance requires too much churn (myself included).


IIRC, I was trying to create a new Effect similar to IxMonadState (docs here). I think the effects you create in your app aren’t type constructors, hence

-- this compiles
data MyADT :: Effect where

-- this doesn't
data MyADT s :: Effect where

Yet another reason to use StandaloneKindSignatures (which is in GHC2021):

type MyADT :: Type -> Effect
data MyADT s where

1 Like

My experience is completely the opposite on this one. Haskell is the only language I’ve ever used where I’ve been able to come back to code years later and still be able to understand it.


It’s also quite unfortunate when other people volunteer their time for free yet their contributions are ignored.

I appreciate you are no longer a maintainer @ChShersh, so this isn’t directed at you, but I thought I’d mention it whilst we were “on the off-topic”. Do you have any suggestions about what I should do in this case?


In my experience, Haskell is rock solid when it comes to long term maintenance.

I am working on a web application with about 20 thousand lines of Haskell code and about 400 packages of Haskell dependencies needed for compilation. It was written, according to git, with Stackage lts-5.1. Looking up, this means base and GHC 7.10.3. This was back in 2016. We are now at GHC 9.2, shipping new features every once in a while. The «hardest» thing to overcome, as far as maintenance goes, was when Amazon pulled a rug from under our feet and we had to roll out a patch to our dependency mime-mail — and I am saying «hardest» in quotes because that was a routine, clearly bounded change. We depend on all the same libraries all these years — a few times a small patch was needed, a «version bump». I have no tales to tell because nothing worth talking about ever happens.

I am hugely thankful to the people that made Hackage, Cabal and Stack. There are obviously cultural differences and disagreements. But the hard, principled position of Haskell’s packaging’s thought leaders made Haskell easy to rely on. They get all the flak and no praise; so let me praise.

I see the person in the video is from Novosibirsk, Russia. I know some people from there. As I see it, they are a rough about the edges kind of people. They like themselves a lyrical hyperbole and unafraid to be sincere both in the good and in the bad. I should be taking whatever he is saying with a grain of salt.