⟴ circuits
circuits is a toolkit for analysing circuits. A circuit, here, is any
computation that has direction, sequence, and flow: data moves through arrows,
feeds back on itself, and forks or joins along the way. The library gives you
small, composable pieces for building those structures and reasoning about them.
Solid arrows are enrichment; dashed arrows are the laws a free construction
draws on when it folds. (open full page)
graph LR
Category["Category"]
Channel["Channel"]
Strength["Strength"]
Traced["Traced"]
Tensor["Tensor"]
Action["Action"]
Free["Free"]
Sym["Sym"]
Net["Net"]
Loop["Loop"]
Category -.-> Free
Strength -.-> Loop
Traced -.-> Loop
Action -.-> Sym
Action -.-> Net
Traced -.-> Net
Category --> Channel --> Strength --> Traced
Category --> Tensor --> Action
Free --> Sym --> Net
Loop --> Net
linkStyle 0,1,2,3,4,5 stroke:#C44E8A,stroke-width:2px
linkStyle 6,7,8,9,10 stroke:#4B7FBD,stroke-width:2px
linkStyle 11,12,13 stroke:#8FB83A,stroke-width:2px
style Category fill:#1F7050,stroke:#1F7050,color:#1b1e23
style Channel fill:#4B7FBD,stroke:#4B7FBD,color:#1b1e23
style Strength fill:#C44E8A,stroke:#C44E8A,color:#1b1e23
style Traced fill:#3D3D7A,stroke:#3D3D7A,color:#c8ccd4
style Tensor fill:#D98A3A,stroke:#D98A3A,color:#1b1e23
style Action fill:#4B9680,stroke:#4B9680,color:#1b1e23
style Free fill:#4B9680,stroke:#4B9680,color:#1b1e23
style Sym fill:#8FB83A,stroke:#8FB83A,color:#1b1e23
style Net fill:#D98A3A,stroke:#D98A3A,color:#1b1e23
style Loop fill:#C44E8A,stroke:#C44E8A,color:#1b1e23
The module view groups the classes into their source files and adds the
satellites around the core. (open full page)
graph LR
Category["Circuit.Category"]
subgraph Channel ["Circuit.Channel"]
ChannelClass["Channel"]
Strength["Strength"]
Traced["Traced"]
end
subgraph Tensor ["Circuit.Tensor"]
TensorClass["Tensor"]
Action["Action"]
end
Free["Circuit.Free"]
Sym["Circuit.Sym"]
Net["Circuit.Net"]
Loop["Circuit.Loop"]
Hyper["Circuit.Hyper"]
Dagger["Circuit.Dagger"]
Ends["Circuit.Ends"]
Category --> ChannelClass --> Strength --> Traced
Category --> TensorClass --> Action
Free --> Sym --> Net
Loop --> Net
Loop --> Hyper
Dagger --> Net
Ends --> Loop
linkStyle 0,1,2 stroke:#4B7FBD,stroke-width:2px
linkStyle 3,4 stroke:#4B9680,stroke-width:2px
linkStyle 5,6 stroke:#8FB83A,stroke-width:2px
linkStyle 7,8 stroke:#9B6BC0,stroke-width:2px
linkStyle 9 stroke:#4B96B0,stroke-width:2px
style Channel fill:transparent,stroke:#4B7FBD,stroke-width:2px,stroke-dasharray: 5 5
style Tensor fill:transparent,stroke:#D98A3A,stroke-width:2px,stroke-dasharray: 5 5
style Category fill:#1F7050,stroke:#1F7050,color:#1b1e23
style ChannelClass fill:#4B7FBD,stroke:#4B7FBD,color:#1b1e23
style Strength fill:#C44E8A,stroke:#C44E8A,color:#1b1e23
style Traced fill:#3D3D7A,stroke:#3D3D7A,color:#c8ccd4
style TensorClass fill:#D98A3A,stroke:#D98A3A,color:#1b1e23
style Action fill:#4B9680,stroke:#4B9680,color:#1b1e23
style Free fill:#4B9680,stroke:#4B9680,color:#1b1e23
style Sym fill:#8FB83A,stroke:#8FB83A,color:#1b1e23
style Net fill:#D98A3A,stroke:#D98A3A,color:#1b1e23
style Loop fill:#C44E8A,stroke:#C44E8A,color:#1b1e23
style Hyper fill:#6B4C8A,stroke:#6B4C8A,color:#c8ccd4
style Dagger fill:#E07A9E,stroke:#E07A9E,color:#1b1e23
style Ends fill:#4B96B0,stroke:#4B96B0,color:#1b1e23
the shape of the library
Everything is built over a base arrow that you bring — (->), Kleisli m,
matrices over a semiring. The library does not pick a semantics; it adds
structure along two ladders.
A ladder of laws. The type classes form chains out of Category:
Channel → Strength → Traced (monoidal structure, tensorial strength, feedback
via trace) and Tensor → Action (the concrete (,) and Either machinery).
Each rung is one more law a target category can satisfy. These classes say
nothing about syntax; they are the contracts that folds have to meet.
A deck of languages. The GADTs form a parallel chain of free constructions,
each rung one enrichment of the last:
Free = Lift + Compose
Sym = Free + Par + Swap
Net = Sym + Knot + Copy + Discard + Plus + Zero
Free is the free category; Sym the free symmetric monoidal category; Net
the free traced PROP with a bimonoid, where every wire is a constructor you can
inspect. Loop sits to the side of this chain rather than on it: it is the free
traced monoidal category in normal form. Its laws are performed by its
instances, so every value collapses to at most one Knot over a base arrow.
Net and Loop are the two poles of the library — wiring you can read
backwards, and wiring that has been melted into a single loop. melt goes from
one to the other.
Between the ladders there is a family of folds. Each free construction can
be evaluated into any target category that satisfies the right laws; the GADT's
constructors are forgotten one at a time. Layer captures this pattern
uniformly, and Algebra provides the same deck à la carte from signature
functors.
In many of the free objects we tag common computation patterns: function
application, composition, tracing, and type tensoring. This bootstraps a
first-class foundation for computational circuits — direction, sequence, and
flow — without baking in a particular semantics too early.
Applications and closures can be delayed for analysis and measurement, or
retried. The feedback itself is visible as a wire, not hidden in a closure.
potential uses
The core stays small; companion libraries apply it to specific domains.
| library |
what it adds |
| circuits-ad |
reverse-mode automatic differentiation, pullbacks, and star-elimination |
| circuits-examples |
paste-into-GHCi example cards |
| circuits-int |
Int construction and polynomial-functor sketches |
| circuits-io |
sockets, queues, servers, and concrete IO transports |
| circuits-llm |
small transformer-style language-model experiments |
| circuits-mat |
matrices over a semiring as a traced monoidal category |
| circuits-meter |
one-line performance metering and stopwatch pipelines |
| circuits-parser |
parser combinators over a coinductive stream decomposition |
| circuits-pca |
principal component analysis as a residual-ownership protocol |
| circuits-repl |
REPL primitives: commit/emit dual, turns, channels, sessions |
install
Add circuits to your build-depends. GHC 9.10+ (tested with 9.14).
Dependencies beyond base: profunctors and stm.
examples
The example cards live in the separate
circuits-examples repository.
Each .md file is a short, paste-into-GHCi walkthrough with YAML front matter
(name, description, tags).
Cards are not a secondary dump for outdated material — they are the development
surface of the library. Stable cards document supported API; experimental cards
grow ideas that are not yet in the API. When a card matures, it gets promoted
into src/ and the public API.
thanks
Built on Launchbury, Krstic & Sauerwein (2013)
and Kidney & Wu (2026). The Hyper type is
theirs; the normal form that makes it inspectable is ours.
LLMs and agents helped with category theory, coding, refactoring, and
documentation.
