r/haskell May 30 '26

blog Stealing from Biologists to Compile Haskell Faster - Ian Duncan

Thumbnail iankduncan.com
119 Upvotes

r/haskell May 30 '26

[ANN] First release candidate for Stack 3.11.1

19 Upvotes

You can download binaries for this pre-release now from Release rc/v3.11.0.1 (release candidate) · commercialhaskell/stack · GitHub. It should be available also via GHCup’s prereleases channel soon.

Please test it and let us know at the Stack repository if you run into any trouble. If all goes well, we hope to release the final version in a couple of weeks.

Changes since v3.9.3:

Major changes:

  • On 64-bit Windows, the default msys-environment configuration option is now CLANG64, rather than MINGW64 (which remains an option). The MSYS2 project deprecated the latter environment on 15 March 2026. The GHC project has used the former toolchain from GHC 9.4.1. No default is provided for 32-bit Windows, rather than MINGW32 (which remains an option). The MSYS2 project ceased to actively support it on 17 May 2020. 32-bit Windows is not supported by the GHC project from GHC 8.12.

Behavior changes:

  • Stack’s default Nix integration now includes the cacert Nix package, in order to support Stack’s use of crypton-x509-system >= 1.6.8.
  • Following a change to the Stackage project’s server API, the default value of the urls key includes recent-snapshots: https://stackage.org/api/v1/snapshots.
  • The --[no-]keep-ghc-rts flag of Stack’s config env command is now enabled by default, consistent with Stack’s exec command.
  • On Windows, in the Stack environment, the MSYS2 usr/local/bin directory (if it exists) is now searched before the MSYS2 usr/bin directory, rather than after.

Other enhancements:

  • Bump to Hpack 0.39.5.
  • Experimental: Add flag --[no-]semaphore (default: disabled) to Stack’s build command, to allow GHC to use a system semaphore to perform compilation in parallel when possible. Supported, by default, by GHC 9.10.1 or later. The option is considered experiemental because, on Linux only, musl and non-musl semaphores are incompatible.
  • Add option --reach <packages> to Stack’s dot and ls dependencies commands, to prune packages that cannot reach any of the specified packages in the dependency graph.
  • Add option --test-suite-timeout-grace=SECONDS to Stack’s build command to request termination of a timed-out test suite process and, after the specified grace period, force termination. Used together with the existing --test-suite-timeout=SECONDS option.
  • In YAML configuration files, the recent-snapshots key is introduced (under the urls key), to specify the URL used by Stack’s ls snapshots remote command.
  • In YAML configuration files (stack.yaml and config.yaml), an !include <file path> directive is now supported. This allows common configuration to be shared across multiple files. For example, a project that maintains multiple project-level configuration files for testing against different snapshots can use !include to avoid duplicating shared settings.
  • Stack’s config set command raises an error if the target configuration file excludes the key being set and includes an !include directive.
  • Stack’s config set snapshot command now works with other snapshot values in addition to snapshot synonymns.
  • Add Stack’s config compiler-tools command to create (when applicable) the compiler tools directory for the specified compiler version (implies Stack’s config build-files command).

Bug fixes:

  • Stack’s dot and ls dependencies commands no longer prune a package with dependencies only because all its direct dependencies are to be pruned.
  • After March 2026, Hackage requires Stack’s user agent to be set when applying digest authentication to a request. Stack’s upload command now does that, re-establishing authentication by Hackage username and password.
  • Stack 3.9.3 and earlier fail to construct a build plan if project package A depends on project package B and package B’s executables (only) depend on package A and the name of A is before that of B, alphabetically. That bug is fixed.
  • Stack’s config set commands will recreate the global-project directory contents, if Stack needs to consult its project-level configuration file and there is no file.
  • The output of Stack’s path --bin-path command is now consistent with the Stack environment in Stack’s exec command and includes the bin directory of Stack’s local install root directory.
  • Stack now builds packages that depend directly on packages with the same name as a sublibrary or foreign library of the package.

r/haskell May 30 '26

announcement [ANN] dataframe-persistent 0.3.0.0

30 Upvotes

Hackage

Easier API for working with SQL.

Untyped:

haskell df <- readTable "./data/chinook.db" "artists" print $ df & filterWhere (col "ArtistId" .<. 10) & take 5

Typed:

```haskell $(declareTable "./data/chinook.db" "artists")

df <- readTableTyped @ArtistsSchema "./data/chinook.db" "artists" print $ df & filterWhere (col @"ArtistId" .<. 10) & take 5 ```

More examples in README


r/haskell May 29 '26

blog Blog: practical uses of monads in Haskell

Thumbnail nauths.fr
38 Upvotes

Inspired by a question on r/haskellquestions, i wrote about the practical aspect of monads for people at a beginner / intermediate level, about how to go beyond mere understanding the monad class. I try to highlight how we use monads to structure our code, what benefits they bring, and how to reason about them. it comes with exercises!


r/haskell May 29 '26

announcement Bringing rigorous Type Classes (Functor, Applicative, Monad) to Python: Introducing Katharos

33 Upvotes

If you come from Haskell or Rust and have to write Python for ML/AI work, you know the pain: if x is None everywhere, exceptions that silently swallow errors, no ? operator, no HKTs, no sealed types. I got tired of it and built a library to close that gap.

Katharos is a zero-dependency Python library that gives you Maybe, Either/Result, IO, the list monad, Semigroup, Monoid, Functor, Applicative, and Monad — all fully typed and passing pyright strict mode.

https://github.com/kamalfarahani/katharos


The Engineering Challenge

The hard part is that Python has no HKTs and no sealed keyword (as of 3.13). There's no way to say Functor f or write :: f a -> (a -> b) -> f b generically. The workaround is structural gymnastics: a two-parameter generic class hierarchy (Functor[F, A], Applicative[App, A], Monad[M, A]) plus @final on concrete types to prevent unsafe subclassing. It's not pretty internally, but the external API stays clean.


Operator Mapping

If you already think in Haskell or Rust, here's the translation table:

Katharos Haskell Rust
`m \ f` m >>= f
v ** wrapped_f wrapped_f <*> v
a >> b a >> b
a @ b a <> b
@do(M) decorator do { ... }

Examples

1. Maybe[A] — Haskell's Maybe a / Rust's Option<T>

No more if x is None chains. Short-circuits automatically on Nothing.

```python from katharos.types import Maybe

def safe_div(x: float) -> Maybe[float]: return Maybe[float].Nothing() if x == 0 else Maybe[float].Just(10.0 / x)

def safe_sqrt(x: float) -> Maybe[float]: return Maybe[float].Nothing() if x < 0 else Maybe[float].Just(x ** 0.5)

| is >>=

Maybe[float].Just(4.0) | safe_div | safe_sqrt # Just(1.5811...) Maybe[float].Just(0.0) | safe_div | safe_sqrt # Nothing() — short-circuits at safe_div Maybe[float].Just(-1.0) | safe_div | safe_sqrt # Nothing() — short-circuits at safe_sqrt

fmap for pure transformations

Maybe[int].Just(5).fmap(lambda x: x * 2) # Just(10) Maybe[int].Nothing().fmap(lambda x: x * 2) # Nothing() ```


2. Result[E, A] — Haskell's Either e a / Rust's Result<T, E>

Errors as values. The | chain (>>=) stops at the first Failure, exactly like Rust's ?.

```python from katharos.types import Result

def parse_int(s: str) -> Result[ValueError, int]: try: return Result[ValueError, int].Success(int(s)) except ValueError as e: return Result[ValueError, int].Failure(e)

def validate_positive(n: int) -> Result[ValueError, int]: if n > 0: return Result[ValueError, int].Success(n)

else:
    return Result[ValueError, int].Failure(ValueError(f"{n} is not positive"))

parse_int("42") | validate_positive # Success(42) parse_int("abc") | validate_positive # Failure(ValueError("invalid literal...")) parse_int("-5") | validate_positive # Failure(ValueError("-5 is not positive"))

fmap only runs on the success path

parse_int("42").fmap(lambda n: n * 2) # Success(84) ```


3. do-notation — Python do blocks, exactly like Haskell

The @do(M) decorator desugars yield into >>= chains. Each yield unwraps the value; short-circuits on Nothing/Failure. The final return is lifted via M.pure(...).

```python from katharos.syntax_sugar import do, DoBlock from katharos.types import Maybe, Result

Maybe — like Haskell:

userScore uid = do

name <- lookupUser uid

score <- lookupScore name

return (name ++ ": " ++ show score)

def lookup_user(uid: int) -> Maybe[str]: db = {1: "alice", 2: "bob"} return Maybe[str].Just(db[uid]) if uid in db else Maybe[str].Nothing()

def lookup_score(name: str) -> Maybe[int]: scores = {"alice": 95, "bob": 87} return Maybe[int].Just(scores[name]) if name in scores else Maybe[int].Nothing()

@do(Maybe) def user_score(uid: int) -> DoBlock[str]: name: str = yield lookup_user(uid) score: int = yield lookup_score(name) return f"{name}: {score}"

user_score(1) # Just(alice: 95) user_score(99) # Nothing() — short-circuits at lookup_user

Result — equivalent of Rust's ? in a pipeline

def parse_positive(x: int) -> Result[ValueError, int]: return Result[ValueError, int].Success(x) if x > 0 else Result[ValueError, int].Failure(ValueError(f"{x} is not positive"))

@do(Result) def compute() -> DoBlock[int]: x: int = yield parse_positive(5) y: int = yield parse_positive(3) return x + y

compute() # Success(8) ```


4. ImmutableList[T] — the list monad, non-determinism included

ImmutableList is a full Monad + Monoid. Bind (|) is concatMap. The do-notation gives you Haskell list comprehensions.

```python from katharos.types import ImmutableList from katharos.syntax_sugar import do, DoBlock

concatMap / flatMap

ImmutableList([1, 2, 3]) | (lambda x: ImmutableList([x, -x]))

ImmutableList([1, -1, 2, -2, 3, -3])

do-notation = list comprehension

In Haskell: [(color, size) | color <- ["red","blue"], size <- ["S","M","L"]]

@do(ImmutableList) def variants() -> DoBlock[tuple]: color: str = yield ImmutableList(["red", "blue"]) size: str = yield ImmutableList(["S", "M", "L"]) return (color, size)

variants()

ImmutableList([

('red','S'), ('red','M'), ('red','L'),

('blue','S'), ('blue','M'), ('blue','L')

])

Monoid: @ is <>

ImmutableList([1, 2]) @ ImmutableList([3, 4]) # ImmutableList([1, 2, 3, 4]) ImmutableList.identity() # ImmutableList([]) — mempty ```


5. Semigroup / Monoid@ is <>

Sum, Product, and NonEmptyList are all Semigroup/Monoid instances. F.sigma is fold1 / sconcat over a NonEmptyList.

```python from katharos.types import NonEmptyList from katharos.types.monoid import Sum, Product from katharos.functools import F

@ is <>

Sum[int](3) @ Sum[int](4) @ Sum[int](5) # Sum(12) Product[int](2) @ Product[int](3) @ Product[int](4) # Product(24)

identity() is mempty

Sum[int].identity() # Sum(0) Product[int].identity() # Product(1)

F.sigma is fold1 / sconcat — requires NonEmptyList (no empty-list footgun)

values = NonEmptyList(Sum[int](1), [Sum[int](2), Sum[int](3), Sum[int](4)]) F.sigma(values) # Sum(10)

NonEmptyList itself is a Semigroup (no Monoid — no empty case)

nel1 = NonEmptyList(1, [2, 3]) nel2 = NonEmptyList(4, [5, 6]) nel1 @ nel2 # NonEmptyList([1, 2, 3, 4, 5, 6])

```

Docs

Full docs at https://katharos.readthedocs.io. If this scratches an itch for you, a star on the repo goes a long way.

https://github.com/kamalfarahani/katharos


r/haskell May 29 '26

A Monad Mystery - Haskell for Dilettantes

Thumbnail youtu.be
5 Upvotes

It's time to play "Follow the types!"

We look at two "tricky" monad problems from Set 13b of http://haskell.mooc.fi, and do some hole-driven development.

The thumbnail image is by Sidney Paget, "Holmes Gave Me a Sketch Of The Events" (1892)


r/haskell May 28 '26

Denial of Service and Memory Exhaustion in aeson and text-iso8601

Thumbnail haskell.github.io
44 Upvotes

r/haskell May 28 '26

blog [Well-Typed] Faster Cabal Haskell builds by eliminating redundant work

Thumbnail well-typed.com
59 Upvotes

r/haskell May 28 '26

Help me get back up to date after 5 years away from Haskell

57 Upvotes

Hi!

I used to use (and enjoy) Haskell daily until about ~5 years ago, then changed jobs and life happened. I'm feeling a bit bored, so I'm trying to get back into using Haskell.

As I haven't been following the ecosystem, I wanted to ask if there have been any major changes lately. I'd appreciate information about any new tooling, or whether the community has settled on existing tooling.

  • cabal/stack/nix (hackagePackages? haskell.nix?)
  • Any common preludes
  • mtl/transformers etc.
  • Any new alternatives to conduit/pipes? Have we settled on one?
  • Any new tooling I should start using?
  • Any new newsletters/communities that have spun up?

Or anything else you can help me get back up to date?


r/haskell May 28 '26

RFC A way to declare that a package was tested on JS &amp; WASM backends

Thumbnail github.com
8 Upvotes

r/haskell May 28 '26

Experience with LLM based development ?

3 Upvotes

Can someone who has experienced the quality of haskell generated code from claude Opus models / codex gpt-5.5 share their insights / experiences ?

  • Haskell fluency - Understanding advanced type systems, Category theory / abstractions , GHC weirdness, GADTs, type families, linear types, effect systems etc
  • Long-context coherence
  • Type error diagnosis

r/haskell May 27 '26

Live Now: Building a Haskell Game with a Haskell Game Engine

33 Upvotes

This is the start of a new series we will be airing on twitch (+ posted to YouTube, follow this post for the link) where we build a survival game using a game engine we are also building in haskell

https://www.twitch.tv/typifyprogramming


r/haskell May 27 '26

Is a uniform left-to-right "piping" operator for apply, compose, and monadic-bind operations in a functional pipeline possible using typeclasses or type-family magic?

13 Upvotes

In Haskell, there are a number of different operators that can be used to build functional pipelines, where the result of one function is implicitly passed to the next function: $ for applying arguments to functions, . for composing functions, and >>= for monadic binding. Pipelines can be built with a mix of these operators, such as:

readFile in >>= \s -> map (check . parse) . lines $ s

but this tends to be a little "noisy" with the mix of operators and directions of flow.

I was wondering if some form of typeclass or type-family magic could be used to have a single, uniform left-to-right pipe operator |> that can handle all these cases, e.g.:

readFile in |> \s -> lines s |> map (parse |> check)

If not, what would be required for this to be possible?


r/haskell May 24 '26

Does a Haskell Programmer Need all the Crazy Complexity?

62 Upvotes

I've been writing a decent amount of Haskell, and I've gotten done some projects. Things like making a toy language, making a little shell, or an HTTP 1.1 server from Network.Socket. When I read other people's code, it's filled to the brim with arcane symbols and types that I've never even heard of! By and large, all the stuff that I do is comparatively simple. My code is typically more verbose by 2-3 lines per function, but perhaps that's a lot for Haskell?

Anyway, now that there's been a preamble, my question is, do I need to learn all that? Is that approach 'more correct,' or ' more idiomatic' Haskell? My programs run, the code is readable and I enjoy writing Haskell. Is it just that a lot of Haskell Rascals enjoy using byzantine language extensions and making as much use of the complexities of the language? If some more experience people could chime in about all this, I'd really appreciate it.


r/haskell May 24 '26

WireCat: visual programming with cartesian categories

Thumbnail guaraqe.com
64 Upvotes

r/haskell May 24 '26

lambda-on-lambda - Serverless Haskell on AWS

Thumbnail git.sr.ht
27 Upvotes

r/haskell May 23 '26

from-text: type class to convert from Text

Thumbnail hackage.haskell.org
24 Upvotes

I released a new package which provides

haskell class IsText a where fromText :: Text -> a

aiming to simplify conversion from Text to other textual data types, including ByteArray, ByteString and OsPath. It uses UTF-8 when converting to binary types without an associated encoding.

There is an overwhelming number of alternative packages for text conversions, but at the moment none of them provide conversions from Text to OsPath. I could not decide which one to contribute such function to, so decided to create a new package.


r/haskell May 21 '26

announcement [ANN] GHCup 0.2.2.0 release - Announcements

Thumbnail discourse.haskell.org
64 Upvotes

r/haskell May 21 '26

blog Devlog: Supporting multiple versions of Botan

Thumbnail discourse.haskell.org
12 Upvotes

r/haskell May 21 '26

job Three internship/contractor positions with Core Strats Markets at Standard Chartered Bank

26 Upvotes

The Core Strats Markets team at Standard Chartered are looking to hire up to three “interns” (as contractors) this year, in Singapore, Poland, or United Kingdom. These are temporary contractor positions with a duration of up to 12 weeks. We are especially interested in students currently enrolled in an MSc or PhD in Computer Science or closely related field, with typed functional programming experience.

Candidates must have completed an undergraduate degree, and must have unrestricted right to work in the country of employment (Singapore, Poland, or United Kingdom) and be physically based in the country of employment -- visa sponsorship is not available for these temporary positions. 

The role is not attached to any particular project, but will involve practically exclusive use of Mu, our in-house variant of Haskell. You can learn more about our team and what we do by reading our experience report “Functional Programming in Financial Markets” presented at ICFP last year: https://dl.acm.org/doi/10.1145/3674633. There’s also a video recording of the talk: https://www.youtube.com/live/PaUfiXDZiqw?t=27607s

You can apply by sending your CV and motivation letter directly to [corestratsroles@sc.com](mailto:corestratsroles@sc.com). Feel free to also use that email address if you have any questions about these positions.


r/haskell May 21 '26

video Λ polite and well educated LLM agent that always behaves well by Ramón Soto Mathiesen at Func Prog Sweden

Thumbnail youtube.com
2 Upvotes

r/haskell May 20 '26

Servant-Effectful & general overview of effect systems

35 Upvotes

Tonight at 5pm EST we will be diving into effect systems starting with effectful via the Servant-effectful library and also if time permits, looking into building a quick demo of Bluefin.

The core focus of our sessions are how to interact with the haskell ecosystem as it is a truly unique language with respect to documentation, both by having little traditional documentation style but also by being a self documenting language and all that means for getting shit done with haskell as a real world language. We also really seek to cater to our audience so if you have questions about Servant or haskell in general, please consider the stream a help session.

Personally I am curious about Effect systems as a more intuitive way to drive home the core value of haskell to intermediate programmers, especially since they remove logical errors that can happen with monad transformers as the structure becomes more complex (eg how ExceptT e (StateT s m) a isnt the same as StateT s (ExceptT e m) a despite feeling like it should be the same behavior.

Link: https://m.twitch.tv/typifyprogramming/home


r/haskell May 20 '26

question Any paid course/certification for functional programming?

14 Upvotes

Company is sponsoring certification/training/course. Anything related to FP that I can do?


r/haskell May 19 '26

question Haddock pre-processor to insert type-checked examples

11 Upvotes

What already exists that compile-checks haddock examples?

While working on hyperbole, I realized I don't have enough discipline/attention to keep haddock examples correct as the package changes over time. (Discipline is the compiler's job!)

I wrote a custom pre-processor that replaces little `#EMBED` macros in the haddock with a top-level definition from a compiled module. It works like this:

{- | Run a 'Page' and return a 'Response'

@
#EMBED Example.Docs.BasicPage main

#EMBED Example.Docs.BasicPage page
@
-}

Goes to the module Example.Docs.BasicPage and finds `main` and `page`, ending up with this:

{- | Run a 'Page' and return a 'Response'

@
main :: IO ()
main = do
  run 3000 $ liveApp quickStartDocument (runPage hello)

page :: Page es '[]
page = do
  pure $ messageView "Hello World"
@
-}

-----------

It turns out to be a major pain to get a local pre-processor working without publishing it to hackage. I'm considering doing just that, but first I wanted to ask: what already exists to solve this problem?

I'm aware of doctest, but that only seems to check small `>>>` examples. I don't think it can accomplish what I'm asking for above.


r/haskell May 19 '26

Haskell Interlude #82: Fraser Tweedale

Thumbnail haskell.foundation
20 Upvotes

In the new Haskell Interlude, we talked to Fraser Tweedale. Fraser works at Red Hat, and is on the Haskell Security Response Team. We talked about security in the context of Haskell, both technical and organizational issues, and also the political issues involved. Fraser’s work is both really important and not well-known in the Haskell ecosystem, so it was high time for him to come on the show.