[^1]: https://pvp.haskell.org/
Why are they requiring two numbers to represent one (semantic) number?
A problem with Semver is that a jump from 101.1.2 to 102.0.0 might be a trivial upgrade, and then the jump to 103.0.0 requires rewriting half your code. With two major version numbers, that would be 1.101.1.2 to 1.102.0.0 to 2.0.0.0. That makes the difference immediately clear, and lets library authors push a 1.103.0.0 release if they really need to.
In practice, with Semver, changes like this get reflected in the package name instead of the version number. (Like maybe you go from data-frames 101.1.2 to data-frames-2 1.0.0.) But there's no consistent convention for how this works, and it always felt awkward to me, especially if the intention is that everyone migrates to the new version of the API eventually.
The author of a library has no idea how tightly coupled my code is to theirs and should therefore only make yes/no answers to ”is this a breaking” change.
For example, when a large ORM library si use changed a small thing like ”no longer expose db tables for certain queries because not all db engines support it anyway” (ie moving a protected property to private) it required a two week effort to restructure the code base.
> In practice, with Semver, changes like this get reflected in the package name instead of the version number.
Not once have I seen this happen. Any specific examples?
Thus making the silly example possible.
Remember, everyone: Haskell is very old!
As it’s grown it’s been pretty cool to have transparent schema transformations instead of every function mapping a statement a dataframe you can have function signatures like:
``` extract :: TypedDataFrame [Column "price" (Maybe Double), Column "quantity" Int, Column "comments" T.Text] -> TypedDataFrame [Column "price" (Maybe Double), Column "quantity" Int] -- body of extract
transform :: TypedDataFrame [Column "price" (Maybe Double), Column "quantity" Int] -> TypedDataFrame [Column "price" Double, Column "quantity" Int] -- body of transform
clean :: TypedDataFrame [Column "price" (Maybe Double), Column "quantity" Int, Column "comments" T.Text] -> TypedDataFrame [Column "price" Double, Column "quantity" Int] clean = transform . extract ```
But you can also do the simple thing too and only worry about type safety if you prefer:
``` df |> D.filterWhere (country_code .==. "JPN") |> D.select [F.name name] |> D.take 5 ```
Being able to work across that whole spectrum of type safety is pretty great.
DataHaskell in general is revived and improving on multiple fronts. Exciting stuff!
https://blog.carolina.codes/p/call-for-speakers-2026-is-open
This makes complex dashboards so much easier to build, because in Python you have to test everything in the dashboard to make sure a change to a common dataset didn’t break anything.
Is there a good web dashboard library like streamlit for Haskell I wonder?
You can try it from https://www.datahaskell.org/ under "try out our current stack"
Strong typing and data science seems like a good combination.
When I've audited some of the published data at our org, there are errors that would have been caught with even basic type-safety. That's how I got the green light to start harassing my team with type safety in our pipelines.
Of course, as with all things in programming, it isn't a silver bullet. It adds a layer of rigor that can slow things down, and there are often (seemingly always) nuances which can't be caught easily by most type systems. Things like complex relations between values (like 'if in Y is in [range], X must be null, and Z must be one of [a, b, c]'). Even so, eliminating categories of errors is worthwhile, and makes it easier to focus on the more complex challenges.
Over all I'd agree though, it's a good combination.
Now hoping to build a bunch of Neuro symbolic AI on top of this.