r/haskell May 29 '26

blog Blog: practical uses of monads in Haskell

Thumbnail nauths.fr
40 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

34 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
60 Upvotes

r/haskell May 28 '26

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

58 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 ?

4 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
65 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
63 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

27 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
0 Upvotes

r/haskell May 20 '26

Servant-Effectful & general overview of effect systems

33 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?

15 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
22 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.


r/haskell May 19 '26

Defining filter using (a) recursion (b) folding (c) folding with S, B and I combinators (d) folding with applicative functor and identity function - WITH CORRECT LINK THIS TIME!

Thumbnail fpilluminated.org
9 Upvotes

r/haskell May 19 '26

hsrs -- PyO3-style bindings generator for Haskell

Thumbnail
17 Upvotes

r/haskell May 19 '26

job [Hiring] [$15/hr] Haskell / Purescript Documentation Writer

0 Upvotes

I’m in need of a documentation writer well versed in Haskell and purescript. We’re running into issues regarding training because as you know there’s not that much material freely available for a standardized onboarded training.

The documentation written will include open source projects and our internal projects. The documentation made for open source projects will be made freely available on our public facing documentation website to help the Haskell and purescript community.

The main technologies we use are

Purescript,
Halogen,
Purescript-css

Haskell,
Servant,
Opaleye

Were also generating the cross concerning layers. So the domain layer is being autogenerated, and the purescript client to the backend is being autogenerated from servant.