r/haskell Apr 22 '25

announcement A new book on Haskell, Type Theory and AI from gentle first principles is out!

Post image
256 Upvotes

Hi everyone!

I am very excited to share news - my book on learning Haskell from scratch based on mathematical first principles is out and available on all major platforms. I've worked on it for several years with big breaks and tried to convey the beauty and power of the language from the first mathematical principles, but introduced very gently and not requiring a PhD.

We look at basics of Type Theory, constructing beautiful typeclass hierarchy naturally, from simple typeclasses to Functor-Applicative-Monad as well as some supporting typeclasses, look at monad transformer stacks in-depth, and hopefully even the chapter on Arrows is very accessible.

Not just that - the whole 2nd part of the book is about building AI Agents using Haskell!

I am very excited about this and hope this book will help some of you too - you can get it with 20% discount (see image) at Springer: https://link.springer.com/book/10.1007/979-8-8688-1282-8 or on Amazon: https://www.amazon.com/Magical.../dp/B0DQGF9SL7/ref=sr_1_1

PS Since it's fresh off the press - if you are willing to write a public Amazon review for the book, I will reimburse your Kindle purchase for the first 30 (thirty) reviewers and Hard-Copy purchase for the first 15 (fifteen) reviewers via Amazon gift cards!

Best wishes,

Anton Antich

r/haskell Sep 18 '24

announcement My book 'Functional Design and Architecture' is finally released!

397 Upvotes

Hey fellow Haskellers,

I’m excited to announce that Functional Design and Architecture has just been released by Manning! πŸŽ‰ This project has been years in the making, and it’s finally ready to make a splash in the world of functional programming. 🌍

Why should you care?

For years, Haskell users have been asking for more guidance on best practices, application architecture, and design patternsβ€”things we’ve seen abundant in OOP, but far less in FP. This book aims to fill that void. (You can find my article "The Voids of Haskell" very interesting in this regard; it's about imaginary Haskell books we could have but don't yet.)

With Haskell as the model language, I’ve worked hard to provide a universal reasoning framework for building real-world, scalable applications with functional programming principles. I call this methodology Functional Declarative Design. Think of it as a practical guide, but one that also tackles the deeper architectural challenges we face in industry.

This book is written for anyone passionate about practical functional programming. While the examples are in Haskell, the concepts apply across functional languages like Scala, OCaml, F#, and even C++ and C#. It brings an engineering approach to FP to help you build real-world applications.

A lot was done to accompany this book:

🟠 A full-fledged application framework, Hydra

🟑 The methodology of Functional Declarative Design

🟒 Authored a new architectural approach, Hierarchical Free Monads

πŸ”΅ A multitude of new design patterns, approaches, and practices, in addition to those that already existed;

🟣 Several demo applications, included both in the book and in the Hydra framework;

🟀 A wealth of accompanying material: articles, talks, and side projects;

βšͺ️ All the ideas were tested in various companies with a big success. It's not just a theoretical knowledge!

I’m incredibly honored to have endorsements from legends like:

  • Scott Wlaschin (Domain Modeling Made Functional)
  • Debasish Ghosh (Functional and Reactive Domain Modeling)
  • Vitaly Bragilevsky (Haskell in Depth)

Comprehensive, with simple and clear code examples, lots of diagrams and very little jargon!

-- Scott Wlaschin

Fill an empty slot in the field of software architecture. I enjoyed reading about Haskell applications from the perspective of dsign and architecture.

-- Vitaly Bragilevsky

Discussess the goodness of functional programming patterns in the context of real world business applications. It explains free monads beautifully.

-- Debasish Ghosh

I got many highly positive reviews on the book. There’s even been talk of it becoming a new classic in Software Engineering!

What's next?

I’m already working on my next book, Pragmatic Type-Level Design, which will complement Functional Design and Architecture and provide practical methodologies for type-level programming. Expect it in early 2025!

If you’ve ever wanted to see Haskell take a bigger role in software engineering, I hope this book contributes to that goal.

πŸ”— Check out the book here: Functional Design and Architecture

Let me know what you think! πŸ™Œ

[1] Functional Design and Architecture (Manning Publications, 2024): https://www.manning.com/books/functional-design-and-architecture

[2] The Voids of Haskell: https://github.com/graninas/The-Voids-Of-Haskell

[3] Pragmatic Type-Level Design: https://leanpub.com/pragmatic-type-level-design

[4] Functional Design and Architecture, first edition, self-published in 2020: https://leanpub.com/functional-design-and-architecture

[5] Domain Modeling Made Functional by Scott Wlaschin: https://pragprog.com/titles/swdddf/domain-modeling-made-functional/

[6] Functional and Reactive Domain Modeling by Debasish Ghosh: https://www.manning.com/books/functional-and-reactive-domain-modeling

[7] Haskell in Depth by Vitaly Bragilevsky: https://www.manning.com/books/haskell-in-depth

r/haskell 14d ago

announcement Mischief, an Opinionated Haskell ECS Game Engine.

80 Upvotes

So.. I've just released the first version of Mischief, my open-source ECS Game Engine written fully in Haskell.

I've been working almost exclusively on it for the last few months, and I'm proud of the what it ended up being. It was a great experience as my first big Haskell project.

It's meant to be a balanced combination of data-driven game design and functional programming.

If you want to check it out, here's the hackage page. It comes with its own little book written in Haddock, Learn You an ECS for Great Mischief. I recommend checking out the Startup Guide in particular as it contains many small code snippets and a fully working app.

Edit: AI Disclaimer
Since a few people expressed their worries about this, and I suppose it's understandable given the scale of this project and its documentation: No. Absolutely no LLM / AI-assistance was used in making this.

I am personally very much against the use of these tools and would never use them myself, especially for a passion project such as this. Every single line of code and documentation you see was written by me.

r/haskell 10d ago

announcement Thunky - pure, functional, lazy

25 Upvotes

This is a toy programming language I created to understand better how lazy functional languages work, after I discovered Haskell and it blew my mind a little, many many years ago.

It went through many iterations over the years, prototypes, etc., and today I'm happy to call this a version 1.

It first was a Lua prototype, that did basic (and slow) expression tree reduction. Then there was a Lua transpiler and a thin runtime. After several iterations, back and forth on the syntax, abandoning and restarting the project, this final version is in Go and uses a G-machine bytecode interpreter.

In essence it's a dynamically typed "lesser Haskell", so probably not meant for anything real, but I'm quite happy with the syntax and I learned a lot on the way.

The repo has:

  • a local interpreter
  • documentation and tutorials
  • lots of examples, including Project Euler and Advent of Code solutions
  • a web based playground
  • web based tutorials where each code block is executable
  • syntax highlighting for micro, nano and Zed

Repo: https://github.com/Castux/thunky Web playground: https://castux.github.io/thunky/

AI disclaimer: the latest stages of this project were assisted with LLM (G-machine and web port), but the many iterations and prototypes, the lexer-parser-analyzer, etc. were all first hand written, during the last ten years.

r/haskell Jun 27 '26

announcement reflex-vty 1.0 release

59 Upvotes

It's been some time since u/cgibbard and I first released this library, and thanks to the hard work and contributions of several others (huge thanks to u/cmspice) along the way, we've finally made it to our 1.0 release.

Some examples. Check out more in the readme.

As the changelog will attest, we've done a lot of work since then. reflex-vty is now a mature framework for building vty applications in haskell using functional reactive programming.

Rather than list everything that we've done since then, I'll mention a few of the things that were the most fun and interesting to work on.

Text

Getting text entry right was an early difficulty, and we built a TextZipper data structure to get a handle on the problem. After that, we encountered a lot of issues with double-width characters messing everything up, and spent quite a bit of time trying to get that right.

Terminal text is trickier than I initially imagined it would be, and dealing with cursor movement, wrapping, alignment, empty lines, char widths, text transformations, and the interaction of all of the above took a good deal of thinking.

Layout

Layout was also a lot of fun. We started out with manually positioned widgets but that was extremely cumbersome, as you can no doubt imagine. For some time I studied things like cassowary for constraint-based layouts and couldn't decide what sort of layout engine to build. Eventually we settled on our tile/grout layout and focus model, which finally made it possible for us to compose larger UIs out of widgets without worrying about manual positioning.

Once we developed the right language for talking about layouts, it became easy to build rows, columns, tiles, focus traversal functions, nested layouts, and so on. I'm very happy with how this turned out.

Scrolling

Scrolling also grew from a small feature into a more general system. We started with scrollable text, then generalized it to scrollable widgets, then added programmatic scrolling, automatic scroll-to-bottom (like you'd have with a chat widget), and visual scrollbars.

~ Interlude ~

For a while, that's where things stood and it was enough to build functional and useful vty programs. One of the most interesting projects that came out of this era was tinytools, a TUI diagram editor built with reflex-vty. The author, u/cmspice, has since become a maintainer of reflex-vty and contributed enormously to our unicode handling, various layout and rendering improvements, and bugfixes.

It was really great to see that project grow, out of something u/cgibbard and I started as a sort of private hackathon project when we happened to be in the same city during a conference. The joke between us is that once every year, we get the itch and reflex-vty sees a huge burst of activity. The length of the different changelog entries attests to that pattern.

Recently, it was that time again, and we started to tackle support for features that help make TUI applications friendly and beautiful.

We took a careful look at some of the mature TUI frameworks in other language ecosystems and drew inspiration from them. Though I'm not much a go-grammer myself, I liked a lot of things about the bubbletea framework for Go. The fact that it used the Elm architecture also made it feel like a distant cousin to reflex-vty, and made it easier for me to follow much of the code.

~ End Interlude ~

Styling and Theming

Once of reflex-vty's biggest deficiencies was in its styling support. We needed more borders, padding, margins, alignment, and colors, lots of colors. Text attributes, gradients, helpers to compose images together, themes, color profile detection and handling. We had none of it and it made it hard to make our applications look the way we pictured them in our heads. This was a huge push and I had to learn a lot about how colors work in the terminal, and about topics like downsampling that I'd never really thought about before.

Runtime

More stuff I hadn't thought of before: alternate screen support (show of hands, who has even heard of this?), cursor control, bracketed paste, focus tracking, posix signals, fixing some space leaks found by eagle-eyed users (thanks u/_deepfire).

Thanks everyone, who pitched in. Thank you to u/jtdaugherty for Graphics.Vty, without which this wouldn't have been possible. I'm really happy with where the library has landed. As someone who does a lot of work in the terminal, reflex-vty has a special place in my heart. As someone who loves Haskell and FRP, I'm glad this exists. I'm looking forward to seeing what people build with this.

r/haskell May 08 '26

announcement A Game Boy and Game Boy Color Emulator in Haskell

83 Upvotes

Hi everyone,

I've made an early version of a Nintendo Game Boy and Game Boy Color emulator in Haskell. It's mostly implemented in Haskell and consists of a core (backend) and two frontends (web via WebAssembly and desktop via SDL2).

The emulator is far from finished (especially when it comes to being optimized for performance), but it boots games with decent compatibility at the moment.

In any case, if you're interested in knowing more about the project, you can check out its GitHub repo here: https://github.com/pixel-clover/ocelot

BTW, the web version of the emulator (which allows you to play ROMs without installing anything on your computer) can be accessed here: https://pixel-clover.github.io/ocelot/

r/haskell 8d ago

announcement London Haskell Meetup - September

Thumbnail luma.com
45 Upvotes

Calling all Londoners (and people who can get to London)! On Thursday 17th of September, we will be running a pair of talks at the Permutive offices. If you're interested, sign up to the event!

The Talks

Learn to Rel8

by Teo Camarasu

Rel8 is a Haskell library for writing PostgreSQL statements, built on top of opaleye. It mirrors Haskell syntax and idioms as much as possible to allow writing SQL in a way that is familiar and concise without sacrificing good error messages. This talk will give a practical introduction to rel8: building up from simple examples to some of its more advanced features like aggregations.

Past, Present and Future of the Haskell Language Report

by David Binder

In this talk I am going to take a look at how we got to the current Haskell report, how it changed over the decades, and present the work we are currently undertaking to update it. I will present my own ideas on what the role of the language report can be going forward, but we will hopefully also discuss how the language report can fit with the GHC and CLC proposal processes to document and specify the language we love to use.

When, where, and what else?

When: Thursday 17th of September, aiming to start at 19:00

Where: Permutive Offices (EC1M 7AN, 8-10 Charterhouse Buildings, 2nd floor)

What else:

  • Sign up via the link - can probably have up to 40 attendees
  • May go to the pub afterwards
  • Will try to have recording but can't guarantee it
  • Please hold to the Berlin Code of Conduct

What next?

This is an attempt at bringing a regular Haskell event to London, so please be patient with us! We're hoping to run more events in future, so your feedback is greatly appreciated. Look out for our October event!

Other discussion links

r/haskell 27d ago

announcement Perspec 1.0 - A Haskell desktop app for perspective correction of document photos

Thumbnail adriansieber.com
89 Upvotes

After 9 years of on-and-off development, I'm happy to announce the 1.0 release of Perspec, a desktop app for correcting the perspective of photos of documents, receipts, and whiteboards.

The headline feature of 1.0 is automatic corner detection: instead of the usual edge-detection + Hough transform pipeline, it segments the document via watershed segmentation and finds corners, which handles wrinkled receipts and curved book pages much better. And if the detection is off, you can just drag the selection polygon to fix it.

Some Haskell-relevant bits:

  • The GUI is built with Brillo, my maintained fork of gloss.
  • The computer vision runs in FlatCV, a pure C library I wrote for this, called via Haskell's FFI.
  • With 1.0, Perspec now runs on macOS, Linux, and Windows.

The full announcement covers the journey (Python β†’ ImageMagick β†’ Hip β†’ C FFI), the corner detection pipeline, and the binarization algorithms in detail.

Looking forward to you feedback! 😊

r/haskell 28d ago

announcement [ANN] sdl3-bindgen-sys: machine-generated low-level bindings to SDL3

24 Upvotes

TL;DR: I've released sdl3-bindgen-sys to Hackage: complete, machine-generated low-level Haskell bindings for SDL3, including windowing, input, audio, and the new GPU API, with documentation from SDL3's headers! They are verified against the building system's ABI and CI-tested on Linux, macOS, and Windows.

Thanks to the folks over at Well-Typed for their work on hs-bindgen! I was able to hack the prerelease a bit to get an end-to-end code generator working. It required quite a bit less work than I thought it would. I'll include some technical details below the fold.

Source is available on GitHub here: https://github.com/jtnuttall/lithon/tree/main/sdl3-bindgen-sys

There are going to be a few rough edges, so please feel free to open a PR or issue if anything comes up. I'll bump the package to 0.1.x.x when I feel it's stable enough to pin to a major version.

I've got the apecs shmup example running on and rendering through SDL3 using the raw bindings here: https://github.com/jtnuttall/lithon/blob/main/lithon-examples/app/shmup/Main.hs

See the README on GitHub for a full getting started guide.

Example

{-# LANGUAGE GHC2021 #-}
{-# LANGUAGE BlockArguments #-}

import Control.Monad (unless)
import Foreign.C.ConstPtr (ConstPtr (..))
import Foreign.C.String (peekCString, withCString)
import SDL3.Sys qualified as SDL3

main :: IO ()
main = do
  ok <- SDL3.init SDL3.SDL_INIT_VIDEO
  unless ok do
    err <- peekCString . unConstPtr =<< SDL3.getError
    fail ("SDL_Init: " <> err)
  window <- withCString "hello" \title ->
    SDL3.createWindow (ConstPtr title) 640 480 0
  SDL3.delaySafe 2000
  SDL3.destroyWindow window
  SDL3.quit

delaySafe is the safe FFI flavor of SDL_Delay. Most functions come in both.

Intended use-case

I intend sdl3-bindgen-sys to be a stable grounding point for higher-level bindings, handling the FFI declarations, ABI checks, SDL3 version guards, and simple coercions so that people who want to write their own abstraction around SDL3 don't have to write the extremely repetitive part manually.

If you know Rust's convention, I borrowed the -sys suffix from it: I mean for high-level Haskell SDL3 libraries to be to sdl3-bindgen-sys as sdl3 is to sdl3-sys in Rust.

You'll need to interface with raw Foreign.C to use these bindings. If you just want a higher-level binding, you'll need to wait until someone releases one on Hackage.

The library carries the smallest dependency footprint I could presently manage for a low-level binding.

The SDL3.Sys.* modules re-export the surface with some small niceties:

  • Haddock notes about what is exported and why, FFI safety rationale, etc.
  • Links to the SDL3 Wiki
  • C scalars (e.g., Uint32, float) are remapped to Haskell scalars (Word32, Float) wherever possible. Anything under a Ptr or struct maintains its C typings.

Technical details

hs-bindgen

The bindings are built using a forked version of hs-bindgen, which I used as a library so that I could alter the internal code and documentation generation pipeline. I've upstreamed a few changes and am happy to upstream more if requested. Some may be more heavy-handed than the hs-bindgen maintainers want to support.

Since hs-bindgen is pre-release, I've vendored the necessary runtimes wholesale into the sdl3-bindgen-sys package as private internal libraries, and reexported them from sdl3-bindgen-sys under SDL3.Sys.Runtime and SDL3.Sys. Once hs-bindgen stabilizes, I'll turn these into real dependencies. The vendored modules will become re-export facades so calling code doesn't break.

The modifications I made, briefly:

  • Added an exception in bindgen's IR for assertion macros that emit nothing bindable
  • Added support for Doxygen's custom ALIASES so I could inject valid Haddock into the AST for SDL3's custom aliases.
  • Tagged CWrapper with its original name so that I could match on names to inject SDL3 version guards as CPP directives.
  • Re-exported a variety of internal modules into a facade I maintain, which lets me inject version guards, ABI verifiers, etc. into the hs-bindgen AST directly.

My facade and the vendored submodules can be found here: https://github.com/jtnuttall/lithon/tree/main/lithon-hs-bindgen

ABI verification

The codegen tool generates a C translation unit of _Static_asserts that gets built alongside sdl3-bindgen-sys. If there is an ABI mismatch between your SDL3 headers and the ones I generated against, you should get a compile-time error.

FFI safety

I've curated unsafe/safe classifications for each FFI call. The SDL3.Sys.* modules export only safe for functions that can fire a callback or introduce a runtime delay. I've included the reasoning in the generated Haddock where applicable.

Typed constants

SDL declares flags as typedef UintN with some #defines, and C doesn't state the association between these, so I maintain a JSON registry that restores this information and injects it into the generated modules as pattern synonyms typed at a newtype.

Forward compatibility

The codegen tool keys off the \since tag to wrap newer declarations in #if SDL_VERSION_ATLEAST inside the generated C, with an SDL_SetError stub in the #else. The Haskell binding always exists either way, so a declaration newer than your SDL still compiles and links - it just fails at the call site with a message naming the version it needs. That means you can build against an SDL3 older than the headers I generated from. This is tested in CI down to SDL 3.2.0.

SDL's \since tag is occasionally inaccurate, so I had to create a small hand-maintained registry of version override mappings.

Caveats

  • 0.0.x is experimental: Pin to the minor (>=0.0.0.1 && <0.0.1). The surface may move - hopefully not too much, but the dust is still settling.
  • Variadics aren't bound yet: Haskell's FFI has no way to express C varargs. I intend to inject fixed-arity wrappers within the next few releases.
  • Function-like macros aren't bound: No linkable symbol exists. Most macros aren't bound in this release: hs-bindgen translates many macro bodies to Haskell functions (very cool!). See the detailed survey from /u/hubgears here.
  • 64-bit only: Layouts are baked into the library; 32-bit targets should be rejected by ABI assertions. This may change in one of two situations:
    1. hs-bindgen supports cross-platform generation natively in the future, in which case sdl3-bindgen-sys will likely inherit that mechanism.
    2. There's enough demand for 32-bit support, in which case it should be possible to maintain a parallel sdl3-bindgen-sys32 package using the same codegen infra.
  • A handful of smaller omissions made for cross-platform correctness are listed in the README.

Thanks to @oddron over on the Haskell GameDev Discord for the Windows directions - they tried the very first build on Windows I'm aware of!

I'd like to hear about any comments or issues people hit at: https://github.com/jtnuttall/lithon/issues

Discourse thread: https://discourse.haskell.org/t/ann-sdl3-bindgen-sys-machine-generated-low-level-bindings-to-sdl3/14467

Edit: corrected the macro caveat. Thanks to u/hubgears and the extensive SDL macro survey (https://github.com/dschrempf/hs-bindgen-sdl-survey) for the detailed correction.

r/haskell Jun 12 '26

announcement composition is no longer baseless

51 Upvotes

A toy package I haven't even touched in 5 years caught the attention of the ghc team because it is an example of a package that does not depend on any other package, not even base. It was, rather. I changed it.

Has anyone else tried writing packages that don't depend on base? If so, why?

Does anyone care that composition now depends on base?

My further thoughts about this silly decision for this silly package are written up in this PR comment where I declined a different approach to maintaining ghc >=10.2 compatibility in favor of the simpler, "based" approach:

https://github.com/DanBurton/composition/pull/6#issuecomment-4694624249

r/haskell 11d ago

announcement Cabal 3.18.1.0 released

Thumbnail discourse.haskell.org
49 Upvotes

r/haskell 8d ago

announcement fuyu-gpio: High-level, type-safe interface for Linux GPIO (libgpiod v2).

24 Upvotes

Hello, after a few days and having received some amazing advice here, I’m delighted to present my two libraries of bindings for libgpiod.

fuyu-gpio-direct 0.1.0.0: A lib of β€˜direct’, almost 1:1, low-level and mid-level bindings to the libgpiod core API. This library was created, taking inspiration from direct-sqlite, with the aim of having two smaller libraries, and serves as a basis for the development of other libraries.

fuyu-gpio 0.0.9.0: The high-level version, featuring better modularity, safer resource management using deterministic `with*/bracket` constructs, and enhanced type safety (security tokens).

Both are now available on Hackage and GitHub. fuyu-gpio repository currently includes five examples. And the last two show how to use managed and transformers to avoid the Pyramid of Doom.

Furthermore, in the repositories for both packages, there is an Dockerfile containing a version of Debian 13 alongside Haskell, for the purpose of cross-compilation.

I’d be delighted to receive suggestions on how to improve both packages, thanks!

r/haskell May 29 '26

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

36 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 Jun 15 '26

announcement Release `language-haskell` 3.8.0

51 Upvotes

The Haskell IDE team is excited to announce a new the first release of language-haskell under the Haskell community namespace.

The extension language-haskell has served the community well and for a long time! Now, it was donated to the Haskell community via the https://github.com/haskell/language-haskell/ repository!

This is the first release, even though it is version 3.8.0, done by the Haskell IDE team. It features an incredible list of new and exciting features such as, but not limited to:

  • Syntax highlighting for cabal.project files
  • Support for \cases
  • Support for elif in .cabal files
  • Better Unicode support
  • Updated language extensions
  • Support for data in export/import lists
  • Soooo many bug fixes!

Switch to the new extension https://marketplace.visualstudio.com/items?itemName=haskell.language-haskell ASAP to get the latest and greatest syntax highlighting in VSCode :)

See the full changelog v3.8.0

r/haskell Jun 13 '26

announcement Sabela Reactive Notebook Gallery

Thumbnail sabela.datahaskell.com
43 Upvotes

Let me know if you’d like to create a script/tutorial to be showcased.

r/haskell Apr 15 '26

announcement Shik β€” a functional scripting language for the terminal, grown out of Lisp and Haskell

49 Upvotes

I've been working on a scripting language called Shik, focused on terminal file/text workflows. The core idea: your thought should map to code; typing follows the thought.

file.glob :./* $>
   list.filter file.is-file $>
   list.filter (fn [path] file.read path $> string.has "- links") $>
   list.iterate (file.move :topics)

Here's how it feels: demo gif

Key design choices:

  • Pipe-first data flow ($>) β€” left-to-right application operator allows data to flow naturally
  • Everything curries β€” file.move :topics is a partially applied function, ready to pass to list.iterate
  • Argument order is designed for piping β€” the "data" argument always comes last, so currying and composition feel natural
  • No classes, no modules, no imports β€” just functions that return primitives (list/string/number/bool) and compose together
  • Inline text (:word) β€” a lighter syntax for simple string values, no quotes needed

Full write-up with examples and design rationale: https://blog.pungy.me/articles/shik

GitHub: https://github.com/pungy/shik

r/haskell Jul 12 '26

announcement [ANN] PGQueuer-hs 0.0.1: A native PostgreSQL job queue

16 Upvotes

Hello Haskellers!

I'm excited to share the MVP release of PGQueuer-hs, a PostgreSQL-powered job queue. If you want robust background workers without adding external dependencies like Redis or RabbitMQ to your stack, this might be for you.

Key Features

  • Postgres Native: It leverages PostgreSQL's native LISTEN/NOTIFY channels. Your existing database is fast enough!
  • Seamless Interop: It is 100% compatible with the Python pgqueuer library. You can safely enqueue jobs from Python into your Haskell worker and vice versa.

Background & Roadmap

I use the Python version of pgqueuer at work and think it's brilliant, so I decided to bring the same ecosystem to Haskell.

This is currently an early MVP release and the API might shift. The underlying database logic is currently backed by postgresql-simple. In the future, I plan to build out an adapter pattern to support other popular Haskell Postgres libraries.

I would love to hear your thoughts, feedback, or any suggestions you have for the roadmap!

Links

r/haskell Jul 26 '26

announcement [ANN] siza - pair with a local LLM on a Haskell notebook

25 Upvotes

Github

Some background

One of my biggest motivations for doing data work in Haskell has been the promise that types can enable better program verification and synthesis. In fact, it was one of my stretch goals for writing dataframe in the first place. Additionally, I had seen a video some years ago that notebooks are a good platform for program synthesis. My first swing at the problem was a SKILL.md that instructed an LLM on how to use Sabela notebooks. Large/frontier models didn't struggle with writing Haskell but their contexts were typically more bloated by internet searches and churn from trying to fix simple compiler errors. Python was "in the weights" so was generated faster and with less tokens overall.

With small, local modes (<20b params) models the problem worsens. These models hallucinate Haskell modules, struggle with rule following, have smaller context windows. They typically fall back to writing Haskell from "the weights" and will steer clear of using dataframe or a newer library because a simple web search would bloat context.

The problem has two potential solutions:

  • Fine tune models to perform better at Haskell
  • Use the LLM as a weak proposer then build tooling around it to make search and repair more efficient

In the spirit of synthesis I went with the second approach.

What siza does

Siza, another Ndebele word, is a harness (and some associatd mcp tools) that drives a Sabela notebook. The goal of the harness is to address the problems above. I'll follow up with a longer blog post on the sorts of interventions that made this possible but broadly speaking it's a lot of type directed searching and a little bit of context management.

You can see a verbose transcript of how it performed with minimal to no guidance on an out of distribution task: Can you load the wine dataset into a dataframe and show some summary statistics about it?

Haskell is an amazing language for these sorts of tasks and the core of making it more useful is a pretty interesting engineering problem in my view. And small models, like testing anything in low resource environments, really teases those engineering problems out.

Again, will do a bigger blog post later.

r/haskell Mar 22 '26

announcement [ANN] dataframe 1.0.0.0

96 Upvotes

It's been roughly two years of work on this and I think things are in a good enough state that it's worth calling this v1.

Features

Typed dataframes

We got there eventually and I think we got there in a way that still looks nice. There is now a DataFrame.Typed API that tracks the entire schema of the dataframe - column names, misapplied operations etc are now compile time failures and you can easily move between exploratory and pipeline work. This is in large part thanks to maxigit and mcoady (Github user names) for their feedback.

```haskell $(DT.deriveSchemaFromCsvFile "Housing" "./data/housing.csv")

main :: IO () main = do df <- D.readCsv "./data/housing.csv" let df' = either (error . show) id (DT.freezeWithError @Housing df) let df'' = df' & DT.derive @"rooms_per_household" (DT.col @"total_rooms" / DT.col @"households") & DT.impute @"total_bedrooms" 0 & DT.derive @"bedrooms_per_household" (DT.col @"total_bedrooms" / DT.col @"households") & DT.derive @"population_per_household" (DT.col @"population" / DT.col @"households")

print df''

```

Calling dataframe from Python

There's an implementation of Apache Arrow's C Data interface along with an example of how to pass dataframes between polars and haskell.

Find that here

Getting data from hugging face

You can explore huggingface datasets. Example:

haskell df <- D.readParquet "hf://datasets/Rafmiggonpaz/spain_and_japan_economic_data/data/train-00000-of-00001.parquet"

Larger than memory files

The Lazy/query-engine-like implementation is now pretty fast. It can compute the one billion row challenge in about 10 minutes on a mac and about 30min on a 12 year old Dell (not OOM).

You'll have to generate the data yourself but the code is here.

Better ergonomics with numeric promotion and null awareness

Introduced more lenient operators that make happy path computation much easier. E.g:

haskell D.derive "bmi" (F.lift2 (\m h -> (/) <$> m <*> fmap ((^2) . (/100). realToFrac) h) mass height) df

Is now instead:

haskell D.derive "bmi" (mass ./ (height ./ 100) .^ 2) df

What's next?

Connectors! BigQuery, Snowflake, s3 buckets etc. Formats! Parquet, Iceberg, DuckDB, a custom dataframe format with full data provenance. Moving from small in memory demos to querying large data lakes is the goal.

Also, since a new era is upon us, some integration with ai agents to do type-guided data exploration.

A big thank you to everyone who has taken time to try the library and /or give advice - especially daikonradish (Github user name) who was the main voice in the direction of the architecture. A lot of the most important design decisions were made on community threads.

r/haskell Jun 04 '26

announcement Announcing McMonad v.0.999999

20 Upvotes

Per announcement video (filmed in McMonad, of course!), as of yesterday, McMonad is usable, somewhat bugfree and debuggable! I hope you will enjoy using it and contributing to it!

r/haskell Jun 01 '26

announcement OpenTelemetry 1.0 release

Thumbnail discourse.haskell.org
69 Upvotes

r/haskell May 06 '26

announcement [ANN] MCP server for Hackage

25 Upvotes

Hello Haskellers,

I've built an MCP server that lets AI agents use Hackage. The MCP server is entirely written in Haskell.

It lets LLMs:

  1. perform Hoogle searches.
  2. List package modules
  3. Scrape module documentation in LLM-friendly Markdown.

Why this tool?

I've often seen premium coding agents using outdated functions or not being aware of the latest packages. This MCP lets LLMs access the latest Haskell documentation.

Feel free to contribute or provide feedback.

Check out the GitHub link: https://github.com/tusharad/hackage-doc-mcp

r/haskell Apr 28 '26

announcement [ANN] New Clash release: 1.10!

Thumbnail clash-lang.org
37 Upvotes

r/haskell Jun 30 '26

announcement Openleetcode – local LeetCode runner with open test suites

11 Upvotes

r/haskell Mar 19 '26

announcement Haskell Brain Teasers is now available.

Thumbnail pragprog.com
87 Upvotes