circuits: traced categories and circuits

[ bsd3, control, library ] [ Propose Tags ] [ Report a vulnerability ]

circuits is a Haskell library that makes feedback first-class, by providing Circuit, the initial traced category over a base category, hyperfunctions via Hyper, and combinators and interpreters. It is experimental, but could be a promising approach to programming circuits that is intensional, ergonomic and performant.


[Skip to Readme]

Modules

  • Circuit
    • Circuit.Circuit
    • Circuit.Classes
    • Circuit.Hyper
    • Circuit.Monoidal
    • Circuit.Traced

Downloads

Maintainer's Corner

Package maintainers

For package maintainers and hackage trustees

Candidates

  • No Candidates
Versions [RSS] 0.1.0.0
Change log ChangeLog.md
Dependencies base (>=4.18 && <5), profunctors (>=5.0 && <6) [details]
Tested with ghc ==9.10.1, ghc ==9.12.2, ghc ==9.14.1
License BSD-3-Clause
Copyright Tony Day (c) 2025
Author Tony Day
Maintainer tonyday567@gmail.com
Uploaded by tonyday567 at 2026-05-26T07:00:45Z
Category control
Home page https://github.com/tonyday567/circuits#readme
Bug tracker https://github.com/tonyday567/circuits/issues
Source repo head: git clone https://github.com/tonyday567/circuits
Distributions
Downloads 0 total (0 in the last 30 days)
Rating (no votes yet) [estimated by Bayesian average]
Your Rating
  • λ
  • λ
  • λ
Status Docs not available [build log]
All reported builds failed as of 2026-05-26 [all 2 reports]

Readme for circuits-0.1.0.0

[back to package description]

⟴ circuits

First-Class Feedback

The free traced monoidal category is the smallest thing you can add to a category to get feedback. Not a library of combinators — a single GADT and a single coinductive type, a hyperfunction no less, connected by this Galois connection ...

~ What we learned building it


⚙️ Install

(m)cabal build circuits

Compiles on MicroHS & GHC 9.10+ with base & profunctors

📡 Usage

import Circuit

-- Fibonacci via knot-tying
>>> take 5 (trace (\(fibs, ()) -> (0 : 1 : zipWith (+) fibs (drop 1 fibs), fibs)) () :: [Integer])
[0,1,1,2,3]

-- Iteration with Either
>>> let step n = if n < 3 then Left (n + 1) else Right n in trace (either step step) (0 :: Int)
3

Representations

Circuit arr t a b is the initial, inspectable encoding (a GADT with Lift, Compose, and Knot). Hyper a b is the final, coinductive encoding in which the feedback channel is structural in the type. The Trace class abstracts the tensor, giving lazy knots via (,) or iteration via Either (with the convention Left feeds back, Right exits).

Conversion is given by reify and encode (and encodeEither/runEither). The core triangle on observables is reify . encode = id.

🧭 Pitch

circuits is a rethink of how to interact with a compiler and arrange code pipelines — circuits — in ways that are intentional, clear, correct and performant.

Hyper is the same as the Kidney & Wu construction:

newtype Hyper a b = Hyper { invoke :: Hyper b a -> b }

From the paper and surrounding literature, we use the hyperfunction axioms and derive a Circuit:

data Circuit arr t a b where
  Lift    :: arr a b -> Circuit arr t a b
  Compose :: Circuit arr t b c -> Circuit arr t a b -> Circuit arr t a c
  Knot    :: arr (t a b) (t a c) -> Circuit arr t b c

This happens to be the initial traced category over a base category and naturally encodes to a Hyper. To be concrete and on the nose, it's a 2-cell bolted on to the free category. Lifting the trace over a category and abstracting the tensor came later.

Have you used your eyeballs yet and read Bartosz's latest? Original thought is a strong claim and could be awkward.

~ claude (tank mode on)

Circuit covers functions, compositional paths, and feedback loops. Hyper is an efficient final encoding where feedback dissolves into the type structure itself. The Trace class (in Circuit.Traced) abstracts the tensor, giving polymorphic loop semantics: lazy knots with (,) or iteration with Either. All braided, cartesian and cocartesian structure lives in Circuit.Monoidal.

other/ traces these ideas from the Kidney & Wu hyperfunctions paper through a narrative arc. Circuit is the initial encoding — a GADT with visible constructors, interpreted by reify. Hyper is the final encoding — a coinductive type where feedback dissolves into the structure itself. The triangle reify = lower . encode connects them.

📦 Sibling libraries

circuits-parserCircuit (->) Either f (These a f) as a parser for a wide variety of f and a.

circuits-ioCircuit (Kleisli IO) Either as a way to engage with file I/O, sockets, servers, (a)timings & asynchronicity.

circuits-meter — circuit measurement and performance.

📖 Read

"tracing hyperfunctions" — Kidney & Wu (2026). The paper that inspired the core construction. Introduces Hyper as a self-dual object in the traced sense and the hyperfunction axioms.

other/ — the narrative arc (notation, marks-and-stacks, knot, triangle proof, tensors, Mendler case, examples). For the long version.

examples/ — cards: parsers, pipes, Elgot iteration, delimited continuations. Paste code blocks into cabal repl.

Contributing

We welcome contributions of any persuasion or fancy. New contributors should open an issue and say hi.

AI / LLM policy

LLMs and agents have been used in the development of this library, including category theory, coding, generation, refactoring, documentation and narrative.

what we prefer ⟜ all code must compile, have and pass doctests, and be reviewable. ⟜ if you open a PR, you must be able to explain what the code does and why. "my buddy Grok wrote it" is not an explanation. ⟜ do not submit code you have not read, understood, and tested.

what we do not do ⟜ ban AI tools. they are part of the workflow. ⟜ accept code that fails the same standards we apply to AI contributions.

code is code and coders are going to code.


Hackage build