Unison
Unison is a simple, pure functional programming language with one trick: types and terms are content-addressable. As it turns out, this massively simplifies many aspects of programming, especially distributed computing.
I first contributed to Unison for fun, as an outside open-source contributor, and later got hired by the team to work full time, primarily on the core code authoring data structures and algorithms.
You can check out the language here and see a list of my contributions here. Whatever you think of Unison (and you should think good things!), content-addressable ASTs are the way of the future. You'll see, you'll all see!
T Times
T Times is a public transit dashboard for riders in the greater Boston area. It combines real-time bus and
train data from the MBTA feed with walk-time estimates from the OpenRouteService API to render a dense dashboard
with little "leave your current location in X minutes" icons.
The implementation also features some fun geospatial data structures an algorithms, all implemented from scratch:
a bounded volume hierarchy, geohashing and un-geohashing, polyline parsing, Ramer-Douglas-Peucker, a polygon containment algorithm, and more.
These are to provide features such as contextual location names, like "Routes near you in [neighborhood], [city]".
T Times is a registered 501(c)(3) non-profit. The app is live at ttimes.boston, though it
doesn't look like much if you aren't currently near an MBTA stop.
T Times is also currently undergoing a rewrite in Rust (classic)... stay tuned!
ki
ki is a lightweight structured concurrency library in Haskell. I first heard about structured concurrency in a 2018 blog post by Nathaniel J. Smith entitled Notes on structured concurrency, or: Go statement considered harmful. This immediately piqued my interest, as a Haskell enthusiast, because I knew of many ways that spawning Haskell's own green threads, analogous to goroutines, were also "considered harmful" and often misused, leaking resources and leaving background computations running longer than they should. I ported some basic ideas from Trio, the Python implementation of structured concurrency, but in Haskell things look quite different, as there is a runtime, and it supports prompt delivery of exceptions between threads.
ki's implementation is small, but mighty. It uses a careful combination of asynchronous exception masking, transactional memory, and atomic fetch-and-add to guarantee that background threads don't outlive their scope, exceptions propagate from parent to child and vice-versa, and memory and CPU usage remain minimal.
The test suite was also sophisticated, for a time. It used the dejafu library to mock IO and exhaustively enumerate all possible interleavings of threads, which allowed me to confirm no race conditions exist with relatively little effort. I eventually moved to a simpler test suite with individual unit tests, because using dejafu in the test suite either necessitated an undesirable effect on ki's type signatures, or else required the use of a proper module system like Backpack, which adds unwanted complexity.
ki-unlifted
ki-unlifted is a variant of the ki API suitable for monads that are "unliftable" to IO.
Chores
Chores is a self-hosted progressive web app for managing a large collection of recurring tasks. I built
it after becoming a homeowner in 2024 and spending a week Googling "new homeowner upkeep", ending up with an
enormous list of tasks ranging from weekly to every other year, with no good way to
track them, combined with an already-large list of household cleaning tasks due every 1-4 days.
The app divides chores into "due today" on the home screen and everything else
behind a "view all" page, keeping the clutter down. Chores can be automatically rescheduled from their
completion date, or pinned to the calendar with flexible recurrence rules: "every Monday", "every other
Friday and Saturday", "every 15th of the month", "every 3rd-to-last day of the month", "every 1st and 3rd
Tuesday". Calendar-based chores are uncommon, but handy for trash day, street sweepings, and rent reminders.
Chores are ordered by an invisible "rot" score, which is a measure of how neglected a chore is, as a function
of how many days it's overdue relative to how often it's meant to be done. The most neglected chore floats to
the top, making it easy to hack away in priority order in the (overwhelmingly likely) case that you don't have
time to do them all.
Shopping
Shopping is a self-hosted grocery list progressive web app with one major distinguishing feature: items can be associated with specific
stores, and within each store, a specific aisle or section. While in shopping mode, the list is sorted by
section in the order you've configured. The result is a streamlined shopping experience... no more
doubling back across the store to pick up that last item or two!
The concurrency model is somewhat novel and works well for this kind of two-users-at-most app. There's no
event log, no server-push, and no requirement for fully linearized transactions. Instead, every edit bumps a
monotonically-increasing data version. The server accepts client requests regardless of what version the
client is at, only rejecting genuinely conflicting operations, such as trying to edit something that's already
been deleted. Every response from the server includes the current data version, and if the client finds
itself behind, it refreshes everything. Combined with a fetch-on-visibility mechanism (with aggressive
caching), this produces a simple system that works really well in practice. I or my spouse can be at the store actively
shopping, while the other is at home thinking of items to add at the last minute, and everything just works without
requiring manual refreshing.
kll
kll is a library that provides a KLL (Karnin-Lang-Liberty) sketch, a probabilistic data
structure used to approximate quantiles. The library also includes a sliding window extension.
t-digest
t-digest is a Unison implementation of the online clustering variant of the t-Digest data
structure, as defined in "Computing Extremely Accurate Quantiles
Using t-Digests" by Ted Dunning and Otmar Ertl. It's useful for accurate accumulation of rank-based
statistics such as quantiles and trimmed means on large datasets, and is especially accurate at very low
and very high normalized ranks. It can also be efficiently merged, making it suitable for map-reduce
workflows.
t-digest was the first "real" data structure I implemented when exploring efficient
solutions for producing online P95 estimates and the like, retaining a minimal number of samples. It works
quite well!
t-digest-window
t-digest-window extends the t-digest library with a clever implementation of
a sort of sliding window abstraction: the weight of samples decays exponentially, per a fixed time window
configured during data structure initialization.
This adaptation offers a significant improvement over the usability of a t-digest in practice, as it's
often the case that newer samples are more important than older samples for an unbounded stream of data.
There are other sliding window implementations I experimented with before settling on exponential decay,
with different time and space trade-offs.
The main quirk of this idea is that samples don't fall out of the data structure entirely when their age
reaches the window duration, as is common with most sliding window abstractions. However, the expected
lifetime of a sample is still precisely the window duration, so for many applications, this is totally
acceptable.
heaps
heaps is a mergeable heap data structure, as described in G. S. Brodal and C. Okasaki,
"Optimal purely functional priority queues," Journal of Functional Programming, 1996, supporting O(1)
insert, peek, and union, and O(log n) time pop. The library provides three heap variants: a min
heap, a max heap, and a heap that accepts a custom ordering function.
finger-tree
finger-tree is an implementation of the finger tree data structure in Unison, as described
in "Finger trees: a simple general-purpose data structure" by Ralf Hinze. In Unison, the finger tree data
structure is a little bit awkward, as the monoidal measure dictionary has to be passed manually to the
operations that require it, since the language lacks a mechanism for implicit arguments (which isn't
necessarily a bad thing). Nonetheless, it's useful to have a blueprint implementation of a general finger
tree, which can either be wrapped, or copied and specialized to a particular monoid and measure.
queues
queues is a Haskell library providing two purely functional queue implementations based on
Okasaki's work: a real-time persistent queue, and a faster ephemeral variant.
I built and benchmarked several more variants before determining that those two are the best-performing.
The real-time queue implements a technique that Okasaki calls "scheduling" - carefully arranging the data
structure to force internal nodes to weak-head normal form ahead of when they are needed, so enqueueing and
dequeueing always run in constant time, unlike the classic two-list queue that occasionally exhibits an O(n)
rotation during dequeueing. It's genius.
reservoir-sampling
reservoir-sampling is a library that provides a couple of different implementations of
reservoir sampling, a technique for selecting exactly k random elements from a stream of
unknown size.
quickselect
quickselect is an implementation of the quickselect algorithm, which picks out the
kth smallest element of a list in O(n) time. This algorithm is commonly used to select the median
of a dataset faster than the naive approach of sorting and then picking the center element.
mit
mit is a Git wrapper that exposes a small set of high-level commands: commit,
sync, branch, and undo. mit commit replaces git
commit, mostly dispensing with the staging area by invoking git commit -p under the
hood. mit sync acts roughly as git stash && git pull && git stash
pop, but considerably smarter.
I built it to streamline my own solo git usage, but also to massively simplify the process of collaborating
on a codebase with others, all pushing to a shared branch (think: side project or hackathon).
Imagine you've made a few commits you haven't pushed. Meanwhile, the main
branch has advanced. On top of that, you're halfway through something,
with a pile of unstaged changes. In vanilla Git, if you decide you want to merge the main branch into yours,
you're juggling a stash, a merge, and an unstash, with potential conflicts to resolve during merging,
and then again during unstashing. With mit, you just run mit sync.
Run mit with -v and you'll see it invoke the git
binary tens of times per command — all sequencing that mit handles quietly on your
behalf.
These days, jj seems to be the new hotness in the "Git but better"
space, but mit has served as my own open-source replacement for git, papering
over its rough edges, for years. :)
Poll Supply
Poll Supply is a progressive web app for creating polls with approval voting ballots. I built it to have
an easier time deciding what movie to watch or restaurant to eat at, among a small mutually trusted group of
friends (trust is necessary, because poll results are visible live!).
The backend is event-sourced and pushes changes to
clients, so users only need to load the poll once and don't have to refresh to see the latest poll options
or results. The frontend, meanwhile, keeps track of its outstanding requests, and assumes they will all succeed
(so that it can update the UI immediately), and separately keeps a source-of-truth model based on the event
stream from the server.
Baby Tracker
Baby Tracker is a self-hosted progressive web app for logging newborn feedings, sleep and wake windows, and diaper
changes. I built it after my son arrived and I found that every app store option was either too slow to load, cumbersome to use,
had useful bits buried behind a paywall, or all of the above. My goal was ultimate simplicity: open app, tap button, close app.
I also integrated the backend with push notifications, for reminders and progress updates, delivered to me via a private
family Discord server.
trace
trace is a library that lets you annotate arbitrary spans of code with a name, for the
purpose of logging how long the code takes to execute. Spans can be nested, forming a tree. I use this
library extensively in production to easily identify which parts of a program are taking the most time, in
order to prioritize where to look for optimization opportunities. It's also helpful for identifying where
parallelism can improve performance.
deflate
deflate is an implementation of the DEFLATE compression algorithm, as specified by
RFC 1951.
zipfile
zipfile is an implementation of .ZIP archive parsing.
Park Bench
Park Bench is a quick-and-dirty, low-friction benchmarking tool with immediate feedback. It features
live comparisons between different functions under benchmark for a variety of different statistics, including
wall-time, CPU time, resident memory usage, allocation speed, and number of garbage collections.
Whenever benchmarking something in Haskell, I reach for Park Bench first. Only very rarely do I find myself
wishing for something with more robust statistical analysis, beyond Park Bench's relatively simple two-point linear
regression.
benchmark
benchmark is a trimmed-down Unison port of the same idea. It features many fewer statistics,
as Unison doesn't currently expose any runtime stats from its runtime.
Cretheus
Cretheus is a clean wrapper around Aeson, Haskell's premiere JSON library. It exposes JSON encoding and decoding
combinators, rather than leaning into typeclasses.
I built this interface as an alternative to Aeson, because in
practice a typeclass-style API leads to defining and using a lot of "throwaway types" that cause clutter and long
compile times. It's also much easier to accidentaly break an API during what feels like a routine refactoring.
Sometimes, or maybe most of the time, just writing straightforward, explicit encoding and decoding routines is
all you need!
unconditional-jump
unconditional-jump is an implementation of a "jump"-like control flow primitive in Haskell. It
lets you define a label within a scope and jump to it with a return value, unwinding the stack, much like a
return-statement in an imperative language.
It's often the syntactically cleanest way to
implement programs that want to stop computing and return early when any error condition is encountered.
Without it, your options in Haskell are to pattern-match and proceed only in one branch, operate in a monad
stack that supports throwing errors, or throw an untyped exception, each with their own tradeoffs. I
originally implemented this abstraction with the continuation monad, but for performance and ergonomic
reasons, reworked it using an exception-based implementation instead.
hasql-listen-notify
hasql-listen-notify is a library that adds Postgres LISTEN/NOTIFY support to the
hasql ecosystem.
I built this after discovering that the only other published library purporting to offer this functionality
had numerous bugs. hasql-listen-notify properly handles all of the tricky bits, including escaping Postgres identifiers
and resetting closed connections in the await loop. It also exposes the backend PID of notifications, which
is useful for filtering out one's own published messages, and other diagnostic purposes.
timer-wheel
timer-wheel is a Haskell library providing an alternative timer data structure for applications
that need to register timers at scale. GHC's built-in timer manager uses a single global priority search
queue, which can become a bottleneck when registering hundreds of thousands of timers. timer-wheel
uses a fixed-size array of priority search queues instead, trading some insert and expiry performance for
timeout accuracy. It also supports cancelable recurring timers, which re-enqueue themselves after expiring.
repld
repld is a pair of programs that communicate over a Unix socket. The server wraps any long-running
stdio-based program, and the client sends input to it. I use a tiny vim keybinding to tie them together, so
that sending the "inner paragraph" (vim-speak for the chunk of text under the cursor) to a persistent REPL
session is a mere keybinding away.
repld solves the "quadratic replay" problem that plagues traditional terminal REPLs, offering
a more declarative notebook-style development workflow instead. In a REPL, if you've sent (say) 5 commands before
deciding you want to re-run them all after tweaking some source code, you refresh your session, then press up 5 times,
enter, up 4 times, enter, up 3 times... exhausting!
I nearly always have a repld session running during development, especially when the project I'm
iterating on is factored well enough to support localized REPL-style iteration.
http-router
http-router is a standalone Haskell HTTP routing library built on WAI. It provides a straightforward
DSL for defining a routing table, and compiles to an efficient segment-based lookup tree.
I use this library for every web app backend I write in Haskell. It's so much more lightweight than anything
else I've seen, and vastly outperforms the naive linear route lookup you'd get if you try to write a web app without
any additional routing abstraction.
http-router
http-router is a Unison implementation of a similar library. The core idea is the same: a data
structure and set of combinators for writing an efficient HTTP route parser. However, the libraries
differ in a couple of fundamental ways per the semantics of the programming languages.
termbox
termbox is a high-level Haskell FFI binding to termbox, a minimal C library for writing terminal
user interfaces. I found termbox to be a delightfully simple alternative to something like ncurses, and the
other bespoke TUI libraries in the Haskell ecosystem. It's bare-bones, which is great for making little games
and simple programs, but less great for making sophisticated dashboards of widgets. I built termbox atop
two lower-level layers, for modularity and code reuse, and also built two higher-level wrappers that expose
the imperative termbox API as something more purely-functional.
termbox-bindings-hs
Low-level bindings.
termbox-bindings-c
Even lower-level bindings.
termbox-banana
An FRP flavored wrapper around the termbox API.
termbox-elm
An Elm Architecture flavored wrapper around the termbox API.
jsonapi
jsonapi is an implementation of JSON:API v1.1, a specification for building APIs in JSON.
crc32
crc32 is an implementation of the CRC-32 checksum algorithm, as used in Ethernet, PKZIP,
PNG, and more.
bounded-recent-set
bounded-recent-set is a data structure similar to an LRU cache. It is a fixed-size set that
tracks the logical insertion (or re-insertion) time of every element. If a new element needs to be inserted
when the data structure is at capacity, the oldest element is evicted.
I implemented this data structure to power the "recent routes" feature of T Times, the public transit
dashboard app I authored. Each user has their own bounded recent set of bus and train route/stop pairs,
which simply tracks the latest 50 unique routes the user rode, at the stop they boarded. Then, in the UI,
the set is filtered down to only those that are nearby (up to 4).
This feature is my completely hands-off replacement for a contextual "favorite routes" feature, dependent
on the user's current location. It works great!
tasty-hspec
tasty-hspec is a small utility library that lets you run an hspec test suite under
tasty without manually converting each test. For a period when both libraries were under active
development and users were migrating from one to the other, it served as a convenient bridge between the two
ecosystems.
int-supply
int-supply is a minimal Haskell library for generating unique integers using atomic fetch-and-add.
list-shuffle
list-shuffle is a Haskell library for shuffling and sampling lists with optimal time and space
complexity, using the Fisher-Yates algorithm internally. There are a lot of cute purely-functional implementations
of list shuffle available, but none of them even come close to the performance of some good old-fashioned
(internal) mutability :)
shuffle
shuffle is a Unison port of the same idea.
percent-encoding
percent-encoding is an implementation of the percent-decoding algorithm, which converts a
URL-safe string into a string that can contain any Unicode code point. It assumes the string is encoded in
UTF-8.
text-ansi
text-ansi is a lightweight Haskell library providing combinators for decorating text with ANSI
escape sequences. It supports common textual types and uses GHC rewrite rules to minimize the memory and CPU
overhead of inserting the escape sequences.
uri-reference
uri-reference is a URI reference data structure and parser, as specified in
RFC 3986.
http-media-type
http-media-type is an HTTP media type data structure, parser, and renderer, as specified in
RFC 9110.
json-pointer
json-pointer is an implementation of JSON pointers, as defined by
RFC 6901.
strict-tuple
strict-tuple provides types and typeclass instances for strict tuples in Haskell, filling a gap in
the standard library.
pg
pg is a command-line utility knife for Postgres, with a few features
that simplify the ceremony of initializing a cluster, creating a database, and so on, all scoped to the current
directory for project-local Postgres access.
I built pg because I often have many projects on my filesystem that talk to Postgres, and it's
convenient to sandbox each one to its own database cluster. The binaries that Postgres ships, however, are
optimized for running just once on a machine, like a 1990s sysadmin, setting up a global Postgres installation
in system directories.
pg also includes a query plan pretty-printer for investigating query
performance. Full-featured online visualizers exist, of course, but sometimes all you need is flat text in a
terminal, and this output format fills a nice middle ground between raw EXPLAIN output and a
full HTML canvas.
stm-pubsub
stm-pubsub is an implementation of the publish-subscribe pattern built on top of Haskell's
Software Transactional Memory (STM). It's similar to a "broadcast channel" abstraction, but with the added
feature that slow subscribers can cause the publisher to block, as a backpressure mechanism.
mbta
mbta is a partial set of bindings to the MBTA V3 API, including predictions and alerts.
riak2
riak2 is a nearly-complete set of low- and high-level Riak bindings, leveraging many features
of the Haskell type system to expose a safe and ergonomic API. The bindings cover Riak's key-value store
(including sibling resolution), CRDTs, secondary indexes, map-reduce, bucket types and bucket properties,
Erlang functions, and search.
I'm also a contributor to the riak library that precedes riak2.
riak-admin
riak-admin is library for programmatically interacting with the riak-admin CLI. I wrote it to supplement
direct Riak API access, since Riak's API doesn't cover everything riak-admin can do.
Haskell Papers
Haskell Papers is a collection of computer science papers related to Haskell, functional
programming, and similar topics, hosted as a static site on GitHub Pages.
Each paper is tagged with metadata (authors, year of publication), and the
collection is filterable on this metadata.
ersatz-pointer
ersatz-pointer is my attempt at a beginner-friendly wrapper around GHC's weak pointer API. The standard
interface is quite confusing. The main contribution here is good documentation, though the interface also
adds a Source type class to prevent common pitfalls, and adds a Material phantom type to prevent
finalization from firing too early.
Pingplot
Pingplot is a terminal program that pings 8.8.8.8 every quarter-second and renders a
live histogram of ping times in a TUI, with support for zooming in and out. I run it whenever I find myself
thinking "is my Internet crapping out? Yes... yes it seems to be..."
sqlit
sqlit began as a high-level Haskell binding library to SQLite. Working on it revealed lower-level
gaps in the ecosystem, so development has paused while I work on sqlite-bindings and a
sqlite-syntax.
sqlite-bindings
sqlite-bindings are fully-faithful 1:1 Haskell binding to SQLite 3, structured as two layers:
sqlite-bindings-c for direct C-flavored FFI bindings, and sqlite-bindings for a slightly
more idiomatic (but still nearly 1:1) Haskell interface on top.
sqlite-syntax
sqlite-syntax is a work-in-progress parser and pretty-printer for the SQLite flavor of SQL. The
goal is to be able to parse and manipulate SQLite queries programmatically, serving as the foundation for
powerful Haskell-SQLite integration.
zmq
zmq is an experimental high-level Haskell binding to ZeroMQ, featuring safety improvements over the
C++ API. It leverages the type system and carefully designed exposed API to rule out some common
gotchas.
libzmq
libzmq is a set of Haskell FFI bindings to ZeroMQ, including draft API support. It exposes the
full C API, with the package version tracking the underlying ZeroMQ version directly.
Learn By Reading
Learn By Reading is a mobile-only prototype of a Spanish learning app. It presents one sentence of a story
at a time, with Kindle-like controls for flipping pages: short-press the left or right side of the screen
to go back or forward. Long-press on the right side before advancing to reveal the translation.
I found
this a fantastic and motivating way to learn: early on you're long-pressing every sentence, but over time
you find yourself short-pressing more and more, just reading a book in Spanish.
7 Little Words
7 Little Words is an implementation of the 7 Little Words phone app, but with a custom word bank of English
SAT vocab words. I built it because I loved the idea behind 7 Little Words, but felt it missed the mark a
bit with its word bank of simple words. Why not have fun and expand your vocabulary at the same time?
Palabritas
Palabritas is a prototype Spanish vocab practice app modeled after the mobile game 7 Little Words. It
presents a few English definitions alongside a collection of 3-4 letter tiles ("palabritas") that
collectively spell the Spanish words for those definitions. The goal is to use all the tiles, which advances
the board to a more difficult level.
Explore Core and More
Explore Core and More is a tool that exposes an experimental alternative syntax for GHC Core, built primarily for
performance analysis and investigation of compiled Haskell code. The basic idea is simple: make Core more readable. One
of the biggest wins is rendering state-token-passing style code as straight-line, do-notation-like syntax
rather than the deeply nested form GHC normally produces.
It's not the most principled implementation. For starters, it parses GHC's
stringy Core output directly, rather than hooking into the compilation pipeline at some earlier, pre-rendering
phase. But it's easier to write a parser than to integrate with the GHC API, so I pursued this approach instead. It's serviceable. :)
pywatch
pywatch is a file-watcher utility for LeetCode-style coding sessions. Any time a .py
file is touched, it's executed. Minor niceties: debouncing, screen clearing, and a timer in the corner.
ytcd
ytcd (YouTube channel downloader) is a minimalist C codebase that downloads the latest videos
from a configured list of YouTube channels. It's built on yt-dlp, runs on a daily schedule, and is
organized to drop videos directly into a Jellyfin-compatible directory structure (though users are encouraged
to fork the tiny codebase and tweak it to their needs).
Downloads are intentionally delayed by two days, giving SponsorBlock annotations time to accumulate, so that
yt-dlp (via ffmpeg) can strip out annoying ad-reads and other promotional segments.
Somerville Candidate Questionnaire 2025
Somerville Candidate Questionnaire 2025 is a "grader app" for local politicians' answers to questionnaires
ahead of the 2025 mayoral and city council elections in Somerville, Massachusetts. Users could read
anonymized responses to each question, grade the answers, and then reveal which candidates they agreed with
most. It was a one-off app for a specific election cycle. The link may go offline at some point as I don't
plan to renew the domain.
safe-exceptions-checked
safe-exceptions-checked is a small Haskell library based on Edsko de Vries and Adam
Gundry's "Lightweight Checked Exceptions
in Haskell" blog post. I thought the idea was rather elegant, and the only thing missing was a companion
library for others to use. Well, I wrote that, and soon after realized that the abstraction doesn't really
make sense in the context of concurrent programming. I abandoned the library after this realization.
language-lua2
language-lua2 is a parser and pretty-printer for Lua, built to experiment with the Earley parsing
algorithm. Earley parsers let you define a grammar at a high level, including left-recursive rules, without
the careful refactoring that parser combinators require to avoid infinite loops. In practice, the library
ended up slow, and I lost interest before getting around to tuning it for performance.
inotify
inotify is bindings to the Linux inotify API for watching filesystem events.
blake3
blake3 is Haskell FFI bindings to the BLAKE3 cryptographic hash function, bundling the
hand-optimized C and assembly implementations for AVX2, AVX-512, SSE2, and SSE4.1.
reactive-banana-extras
reactive-banana-extras is an add-on package to reactive-banana, a functional
reactive programming (FRP) library. It features a type class that unifies the concepts of Behavior,
Moment, and Dynamic (a new type defined as a Behavior paired with the
Event that updates it). It also includes a large number of combinators I found useful for writing
FRP programs.
wai-middleware-travisci
wai-middleware-travisci is a WAI middleware for authenticating webhook payloads from Travis CI.
I first built the functionality directly into one web app, then extracted it as a library the moment I needed
the exact same logic in a second place. I don't think anyone uses Travis CI anymore, but hey, the code might
still work. :)
proem
proem is a custom Haskell prelude.
Roots
Roots is a work-in-progress batteries-included standard library for Elm, which includes a couple novel
abstractions for defining reusable fragments of an update function.
ghc-switch
ghc-switch is a shell script that simplifies the installation and switching between multiple
GHC versions.
deterministic-hls-builds
deterministic-hls-builds was an early attempt at shell-scripting a deterministic
installation of Haskell Language Server, to avoid ending up with slightly different setups on different
machines due to the official installer (or lack thereof). These days, ghcup is a much better
solution. :)
Both were primitive tools that were necessary for a time early in Haskell's life, before
ghcup was created and deprecated them both.
Note: I am the co-maintainer of these libraries, not the original author.
hasql-interpolate
hasql-interpolate is a QuasiQuoter for hasql that lets you write SQL with
interpolated Haskell expressions and spliced SQL snippets, instead of managing positional parameters by hand.
It makes SQL queries invoked via a Haskell program vastly more readable.
stm-fsifo
stm-fsifo ("first-still-in-first-out") is a variant of an STM queue that supports constant
time removal of any element, not just the front. Its primary use case is a cancelable task queues, and was
built to support a (yet unreleased) high-performance resource pool library.