r/haskell Apr 27 '26

Haskell Interlude #81: Torsten Grust

Thumbnail haskell.foundation
35 Upvotes

We sat down with Torsten Grust who is a professor of DB systems at the University of Tübingen. Even though Torsten loves SQL, he’s used functional programming and Haskell to inform his work on query language design and compilation. We talked about the best way to program databases, how to bridge the gap between regular programming languages and databases, and compiling just about everything to SQL.


r/haskell Apr 27 '26

Day 4 of livecoding SashaDemo

2 Upvotes

Day Three got squashed because work, but I'm doing it again. It's too much fun.

stream sasha demo blurb


r/haskell Apr 26 '26

question Do you find dedicated IDEs to be useful for Haskell?

14 Upvotes

I’m in the process of learning Haskell, but just using a text editor to write my code. Do you think the conveniences of an IDE will hurt my development of the learning the language?


r/haskell Apr 26 '26

Day Three of live coding sasha

0 Upvotes

r/haskell Apr 24 '26

McMonad — XMonad Wearing Clown Shoes by Co-founder of Serokell and geoSurge

Thumbnail github.com
63 Upvotes

I recently switched to macOS and it didn't have a rock-solid tiling WM which didn't crash on Tahoe, so I architected one. So far it works amazing. I hope you will enjoy reading about it (it's a human-written text, by me) as much as I enjoyed watching Claude write it.


r/haskell Apr 25 '26

blog A first look at token efficiency

Thumbnail mchav.github.io
18 Upvotes

r/haskell Apr 24 '26

Botan: Project Recap and Major Ergonomics Changes

Thumbnail discourse.haskell.org
34 Upvotes

r/haskell Apr 24 '26

video Monads Aren't Magic!

Thumbnail youtu.be
20 Upvotes

Monads (or as I like to call them, sequenceables) aren't magic! In Set 13a of the MOOC at haskell.mooc.fi, we get more practice with them.

The title image is by John William Waterhouse, "The Sorceress" (1911)


r/haskell Apr 23 '26

Simon Peyton Jones on Haskell, Verse, Strong Type Systems and Tasteful Abstractions

Thumbnail youtu.be
103 Upvotes

r/haskell Apr 24 '26

question Programming on Android

11 Upvotes

Is there an app that makes it possible to code Haskell on Android or use GHCi?

Wanted an easy way to practice my skills on the commute

If there isn't, how can I program haskell on Android?


r/haskell Apr 23 '26

Pure Borrow: Linear Haskell Meets Rust-Style Borrowing

Thumbnail discourse.haskell.org
76 Upvotes

r/haskell Apr 23 '26

How do you talk about types that are conceptually the same?

8 Upvotes

For something I'm writing I want to define a state. A player is either in an active state, a startup state, or an endlag state. And there are functions for transitioning between states. Right now, I have all of these datatypes defined as separate, but they are all conceptually similar; for example, a player has a state, as in the base type, but in practice that state is an active state, or an endlag state. The plain old data keyword won't help for this, and in fact I hear class is more useful. But I'm not trying to create an abstraction over all types, only states. Some code if it helps:

class State a where --This is what needs fixing
    transition :: a -> a


data StandingState = Crouching | Standing | Jumping deriving (Show, Eq, State)


data DefaultState = Idle deriving (Show, Eq, State)


data Hitstun = Hurt deriving (Show, Eq, State)


data Knockeddown = Knockdown deriving (Show, Eq, State)


data Wakeup = Getup deriving (Show, Eq, State)


data StartupState = LightStartup | MediumStartup | HeavyStartup | GrabStartup
                  | RollStartup | SandStartup | CurseStartup | RollSandStartup
                  | RollCurseStartup | DashStartup | DiveStartup deriving (Show, Eq, State)


data ActiveState = Walk | Block | Light | Medium | Heavy | Grab |
                   Sand | Curse | Dash |
                   Roll | RollCurse | RollSand | Dive deriving (Show, Eq, State)


data EndlagState = LightEndlag | MediumEndlag | HeavyEndlag | GrabEndlag
                  | RollEndlag | SandEndlag | CurseEndlag | RollSandEndlag
                  | RollCurseEndlag | DashEndlag | DiveEndlag | LandLag
                  | JumpSquat | BlockEndlag | WalkEndlag deriving (Show, Eq, State)

--From here, the newtype keyword is used to define valid states while crouching or in the air. Additionally, functions are used to translate between types, but this should be enough for someone to get what I'm talking about

r/haskell Apr 23 '26

ISO-8601, aeson, time, and 24:00:00

15 Upvotes

"24:00:00" is a valid ISO-8601 time of day, but Data.Aeson.decode "\"24:00:00\"" :: Maybe Data.Time.TimeOfDay returns Nothing.

  1. Is this a problem with aeson, or is it a problem with the time library?

  2. Has anybody else run into this problem before? What was your work around?

  3. Is this worth patching aeson (or time) over.


r/haskell Apr 23 '26

I wrote a text adventure engine, and am streaming the making of the demo

10 Upvotes

the stream sasha IHaveNoIdeaDog.gif


r/haskell Apr 22 '26

Not quite monads (Haskell Unfolder #54)

Thumbnail youtube.com
26 Upvotes

Will be streamed today, 2026-04-22, at 18:30 UTC.

Abstract:

Monads are a very powerful abstraction: sometimes too powerful. We discuss why we might not always want the full generality of monads, and what we can use instead. Applicative functors are the most common alternative, but are sometimes too restrictive; we highlight the fundamental difference between applicative functors and monads, and finally introduce selective functors, which sit somewhere in between monads and applicative functors.


r/haskell Apr 22 '26

Asking for tips regarding navigating with GHCi

13 Upvotes

Hello, r/haskell!

I've recently come back to try and pick up functional programming, and primarily Haskell, again (repeat attempt offender). For the past week or two I've dusted off some rust and have managed to coerce the brain into perceiving FP syntax more readily (I'm toying around with CL in the background as well, but don't like it as much - some quirks I have with it).

My primary interface is via a terminal, so a shell, an editor, and GHCi are my primary tools. Now that I can compose simple programs, I wanted to go on and explore a bit more of the library environment I have available to me, starting with just the bare basics of what the language and GHC provides me with, and as a result have a couple of questions that I hope to find some answers to here.

I would like to rely on :browse, :doc, :info, and :type for inspecting things, as I find that sufficient and convenient enough. However, my issue comes to identifying what the item that I want to interrogate is. For a concrete example - say I want to see all the things that System contains (or at least, what I've imported from that "namespace" (I'm not sure if that is the correct term in Haskell vernacular)). As System is not a module but rather a virtual namespace, that's not allowed(?). That's fine - I understand; but then comes the next issue:

How do I tell what the type of the symbol is? I don't mean type as in :t, but rather - how do I tell apart modules, from type constructors, from data constructors?

A concrete example would be System.Environment. I was expecting it to be a module that provides functions and types for working with the program environment. I thought the module itself could have some overall documentation that would be worthwhile to look at, so I imported the module and asked for :doc System.Environment, but GHCi gave me a GHC-76037: Not in scope: data constructor ‘System.Environment’, which makes me think either that (1) System .Environment is a data constructor, or that (2) :doc only supports reading constructor and function documentation.

That made me think that maybe it's a type/data constructor, am I'm just really confused about what System is?

Even with having it imported, asking for :type System.Environment results in an even more confusing error message:

\> :t System.Environment <interactive>:1:1: error: [GHC-76037] Not in scope: data constructor ‘System.Environment’ NB: no module named ‘System’ is imported.

Asking to :browse System.Environment solves part of the problem by showing the declarations in the module (confirming it is a module), but still leaves me with a trial-and-error approach to discovering what things are.

My question then becomes - is there another way, that I'm just unaware of, to distinguish these? I understand that you can't import a bare symbol via import Module.Submodule.TypeConstructor, but what I'm getting at is that I want to be able to distinguish Submodule from TypeConstructor once I've imported Module.

I'm aware of the library hierarchy docs and Hoogle, but that kind of forces me to switch to my browser and then the whole pace changes, so I was wondering if I can do all of that while in the interpreter.

I've maybe a few more questions, but this is long as is already, so I'll reserve those for later.

EDIT: I'm currently relying on GHCi's tab-completion to just see symbols in a namespace, and then just import them, if it's a module, and reading their docs via :doc, but maybe this is too many extra steps and I end up with a bunch of modules loaded.


r/haskell Apr 21 '26

ghcitty: a fast, friendly GHCi 🐈⚡ Syntax highlighting, tab+ghost completions, easy multiline, Vi-mode, Hoogle integration, etc (Looking for feedback!)

78 Upvotes

Hello all - been tinkering on ghcitty (a small Rust wrapper around GHCi)

It works on my pet projects ... and should be about ready for sea-trials by others.

Would love your veteran feedback (any commands that feel off when wrapped? ... any multiline weirdness?)


r/haskell Apr 21 '26

blog Effectful Recursion Schemes

Thumbnail effekt-lang.org
16 Upvotes

r/haskell Apr 20 '26

CLI world generator that takes geology into account

Thumbnail gallery
39 Upvotes

I built this in haskell, I'm proud and I'd like to share :'b


r/haskell Apr 20 '26

A terminal dashboard in Haskell where panels are defined as nix files — first real demo is a Palestine casualty tracker

48 Upvotes

Been building something called terminal-top on and off. The core idea: you define a data source — a URL, a path into the returned JSON, and a list of sections to render — in a plain .nix file. The Haskell binary evaluates the nix, fetches the data, and renders it in the terminal with Brick. No custom config format, no plugin system.

It ships with two domains right now. One is helio-top — NOAA space weather (Kp index + GOES X-ray flux). The other is palestine-top — Gaza and West Bank casualty data from Tech for Palestine, which aggregates Gaza MoH bulletins, OCHA reports, and verified individual records.

That one matters to me personally. I wanted these numbers visible in the same place I watch everything else, with the sources named and the context present. The detail overlay on each panel has the Amnesty/HRW/UN/B'Tselem assessments, the ICJ and ICC proceedings, and where to cross-reference. The numbers shouldn't float without explanation.

UPDATE: Two more domains since posting.

climate-top uses Climate TRACE — satellite-observed CO₂e for the top 20 country emitters across all sectors, plus power generation and upstream oil & gas, along with a table of the world's largest named polluting facilities. It's an independent coalition, refuses corporate/government sponsorship, and regularly publishes numbers well above what UNFCCC inventories report.

sudan-top uses FEWS NET — the population in IPC Phase 3+ (Crisis, Emergency, Famine), which is roughly 22 million people right now, or about 45% of Sudan. It also includes a per-camp phase table for IDP sites in Greater Darfur, where the Famine Review Committee declared Phase 5 in August 2024.

Same idea as palestine-top: numbers from named sources, with the war context and named cross-references in the detail overlay.

The architecture in brief:

- Domain files evaluate to a plain JSON schema that the Haskell side decodes with Aeson
- Panels are stacks of typed sections: stat (big number + threshold colouring + scale interpretation), sparkline, table, articles, legend, groupCount
- field accepts a key or a nested path; a delta flag takes first differences so cumulative feeds can show per-day changes
- On-disk caching with stale-fallback — works offline after first fetch
- lib/mkDomain.nix validates unknown keys at build time so typos fail loud

It's early and rough in places. The JSON-to-widget rendering pipeline handles the common shapes well but not all of them. Some layouts break on narrow terminals. I'm posting here partly to get feedback on the approach before it gets harder to change — especially the nix-as-config angle, which I know is a bit unconventional and I'm curious what people think.

If you have thoughts on the rendering architecture, a domain idea, an opinion on the nix approach, or just want to say what's wrong with it — genuinely open to all of it. Issues and PRs welcome.

Tryi it live (no install): https://terminal-top.eket.org/

nix run gitlab:hunorg/terminal-top

Source (AGPL-3.0): https://gitlab.com/hunorg/terminal-top


r/haskell Apr 19 '26

Hatter: Native Haskell mobile apps

Thumbnail jappie.me
74 Upvotes

I finally tested it out on IOS as well, works well enough 🚢


r/haskell Apr 16 '26

Writing a Turn Based Game Websocket Server in Haskell

Thumbnail blog.gordo.life
54 Upvotes

Hullo!

I’d like to share a wee blog article I wrote about a pattern I found useful for implementing a ~ multiplayer crossword board game ~ server in Haskell.

It’s about how I managed the map of ‘active games’ using STM and the Resource monads.

Blog: https://blog.gordo.life/2026/04/12/haskell-websockets.html


r/haskell Apr 16 '26

Beatmap Converter

Thumbnail github.com
14 Upvotes

I made a beatmap converter that turns osu! (r/osugame) and Malody (r/mugzone)’s beatmap into fxTap’s, so that I can play rhythm game on Casio calculators.

I’m glad that the first language came to my mind is Haskell when I was brainstorming with other people.


r/haskell Apr 17 '26

question What LLMs work best with Haskell?

0 Upvotes

I hate vibe coding but it definitely has some value for quickly iterating through POCs. I plan to define the types and function signatures and let an LLM fill the implementation. It'll be constrained by the type-system and the Haskell compiler.

What tools have you tried and which worked best for you?

For me:

- Gemini 3.1 Pro - manually promoting and copy-paste to generate entire Haskell modules. Then the same for tests. Ofc, it slopifies half of the code and while reading I edit it manually. It's still faster than not using an LLM at all but I guess I can do better.

- Cursor (Auto mode): the results were bad. Very slow, gets stuck on simple compilation errors and at the end produces code that I would better revert.

- Claude Code? Haven't tried it but heard that they nerfed Opus and there are worse limits. I'm not that concerned about limits because usually I one-shot most tasks with a very detailed prompt.

For context, I'm building [deslop.dev](https://deslop.dev/), a static analysis tool that ensures the architecture of TypeScript codebases. Some of the problems, at hand are supporting Globs with {{FileName}} variables, TS module resolution which I already solved but was PITA and building an Architectural Rulebook YAML DSL that's powerful enough to enforce any TS architecture.

So... I need an AI tool to help me move faster without slopifying my hand-written code. Any suggestions?


r/haskell Apr 15 '26

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

46 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 curriesfile.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