Actegories

Hacker News Top Tools

Summary

An article explaining the concept of actegories in category theory and their role in programming optics such as lenses and prisms, with Haskell implementations.

No content available
Original Article
View Cached Full Text

Cached at: 07/14/26, 01:17 PM

# Actegories Source: [https://bartoszmilewski.com/2026/06/30/actegories/](https://bartoszmilewski.com/2026/06/30/actegories/) Previously:[Kan Extensions in Double Categories](https://bartoszmilewski.com/2026/06/13/kan-extensions-in-double-categories/)\. In programming, actegories play a central role in optics: lenses, prisms, traversals, etc\. To understand actegories, let’s start with the definition of a monoidal category\. ## Monoidal Category A monoidal category![\mathbf M](https://s0.wp.com/latex.php?latex=%5Cmathbf+M&bg=ffffff&fg=29303b&s=0&c=20201002)is a category equipped with a tensor product\. A tensor product is a functor![\otimes \colon \mathbf M \times \mathbf M \to \mathbf M](https://s0.wp.com/latex.php?latex=%5Cotimes+%5Ccolon+%5Cmathbf+M+%5Ctimes+%5Cmathbf+M+%5Cto+%5Cmathbf+M&bg=ffffff&fg=29303b&s=0&c=20201002)\. We assume that this product is associative and unital– up to isomorphism\. It means that there is an invertible associator: ![\alpha_{a, b, c} \colon (a \otimes b) \otimes c \to a \otimes (b \otimes c)](https://s0.wp.com/latex.php?latex=%5Calpha_%7Ba%2C+b%2C+c%7D+%5Ccolon+%28a+%5Cotimes+b%29+%5Cotimes+c+%5Cto+a+%5Cotimes+%28b+%5Cotimes+c%29&bg=ffffff&fg=29303b&s=0&c=20201002) natural in all three arguments\. We also have a unit object![1](https://s0.wp.com/latex.php?latex=1&bg=ffffff&fg=29303b&s=0&c=20201002)and two \(invertible, natural\) unitors: ![\lambda_a \colon 1 \otimes a \to a](https://s0.wp.com/latex.php?latex=%5Clambda_a+%5Ccolon+1+%5Cotimes+a+%5Cto+a&bg=ffffff&fg=29303b&s=0&c=20201002) ![\rho_a \colon a \otimes 1 \to a](https://s0.wp.com/latex.php?latex=%5Crho_a+%5Ccolon+a+%5Cotimes+1+%5Cto+a&bg=ffffff&fg=29303b&s=0&c=20201002) To get a better feel for it, we can try to model a monoidal category in Haskell\. We parameterize it by the type of the tensor product,`ten`, which we want to be a`Bifunctor`: The standard way to define a subcategory of Hask is to restrict the types of objects by imposing a constraint\. Such a restriction has a special kind,`Constraint`: A common example of such a constraint is a typeclass\. For instance`Monoid`will restrict the objects of the category to be monoids\. \(In principle, we should also restrict the type of arrows, here to monoid morphisms\.\) We can specify the unit of a monoidal category as an associated type \(parameterized by`ten`\): ``` type Unit ten :: Type ``` The unit should be an object of the category, so it should satisfy the constraint\. We can encode this in our definition as a precondition:`obj \(Unit ten\)`\. This leads to a circularity, which we can overcome using the language pragma`UndecidableSuperClasses`: Finally, we can add the associator and the unitors \(and their inverses\): Notice the`obj`constraints in the type of these functions and the infix notation for the tensor\. Let’s work out a few examples\. The simplest is the category of all types with a cartesian product as tensor\. We define`Hask`using an empty class, and we make all objects its instances: Similarly, we can define a monoidal category with`Either`as the tensor product, or with`Monoid`as the object constraint\. ## Actegory An actegory is a category that supports the action of a monoidal category\. You may think of it as “multiplying” or “scaling” the objects of this category by objects of the monoidal category\. The \(left\) action can be defined as a functor from the product category to![C](https://s0.wp.com/latex.php?latex=C&bg=ffffff&fg=29303b&s=0&c=20201002): ![\triangleright \colon \mathbf M \times C \to C](https://s0.wp.com/latex.php?latex=%5Ctriangleright+%5Ccolon+%5Cmathbf+M+%5Ctimes+C+%5Cto+C&bg=ffffff&fg=29303b&s=0&c=20201002) or, after currying, as a functor from![\mathbf M](https://s0.wp.com/latex.php?latex=%5Cmathbf+M&bg=ffffff&fg=29303b&s=0&c=20201002)to the endofunctor category: ![\triangleright \colon \mathbf M \to [C, C]](https://s0.wp.com/latex.php?latex=%5Ctriangleright+%5Ccolon+%5Cmathbf+M+%5Cto+%5BC%2C+C%5D&bg=ffffff&fg=29303b&s=0&c=20201002) The coherency conditions are the invertible natural transformations that relate the action![\triangleright](https://s0.wp.com/latex.php?latex=%5Ctriangleright&bg=ffffff&fg=29303b&s=0&c=20201002)to the tensor product![\otimes](https://s0.wp.com/latex.php?latex=%5Cotimes&bg=ffffff&fg=29303b&s=0&c=20201002)and its unit![1](https://s0.wp.com/latex.php?latex=1&bg=ffffff&fg=29303b&s=0&c=20201002): ![\alpha_{m n a} \colon (m \otimes n) \triangleright a \to m \triangleright (n \triangleright a)](https://s0.wp.com/latex.php?latex=%5Calpha_%7Bm+n+a%7D+%5Ccolon+%28m+%5Cotimes+n%29+%5Ctriangleright+a+%5Cto+m+%5Ctriangleright+%28n+%5Ctriangleright+a%29&bg=ffffff&fg=29303b&s=0&c=20201002) ![\lambda_{a} \colon 1 \triangleright a \to a](https://s0.wp.com/latex.php?latex=%5Clambda_%7Ba%7D+%5Ccolon+1+%5Ctriangleright+a+%5Cto+a&bg=ffffff&fg=29303b&s=0&c=20201002) The action is functorial in both arguments, so our Haskell translation pegs it, for simplicity, as a`Bifunctor`\. \(A`Profunctor`action is also possible\. Categorically, it would correspond to using![\mathbf M^{op}](https://s0.wp.com/latex.php?latex=%5Cmathbf+M%5E%7Bop%7D&bg=ffffff&fg=29303b&s=0&c=20201002)as the monoidal category\.\) Another simplifying assumption is that the action uniquely identifies the tensor product, encoded here as the functional dependency`act \-\> ten`\. The simplest example of an actegory is the self action of the cartesian product\. Here, the monoidal category acts on itself: ## Monoidal Functors Actegories that use the same monoidal category for their actions form a category\. The morphisms in this category are \(strict\) monoidal functors\. These are functors that map one action to another: ![f (m \triangleright_1 a) \cong m \triangleright _2 f a](https://s0.wp.com/latex.php?latex=f+%28m+%5Ctriangleright_1+a%29+%5Ccong+m+%5Ctriangleright+_2+f+a+&bg=ffffff&fg=29303b&s=0&c=20201002) In Haskell, we can model them as: In fact, actegories form a bicategory, with action\-preserving natural transformations acting between monoidal functors\. Here’s an interesting example of a monoidal functor between non\-trivial actegories: Haskell code is available[here](https://v15.next.forgejo.org/BartoszMilewski/Categories/src/branch/main/src/Actegory.hs)\.

Similar Articles

Tambara Equipment

Hacker News Top

This article explains Tambara modules in category theory, their relation to monoidal functors and profunctor optics, and illustrates the concepts using Haskell code, drawing from a recent paper by Mateusz Stroiński.

Profunctor Equipment in Haskell

Hacker News Top

This blog post provides a toy Haskell implementation of profunctor equipment, including natural transformations and composition, to make category-theoretic concepts accessible to programmers.

Applied Category Theory Course (2018)

Hacker News Top

An online course on applied category theory taught by John Baez, based on the book 'Seven Sketches in Compositionality', covering ordered sets, resource theories, and databases through a series of lecture notes.

Existentials on a Leash

Lobsters Hottest

A technical article presenting an encoding for existential types in Haskell using linear functions and unsafeCoerce, enabling 'naked' existentials without GADT wrappers, and demonstrating it with a safe variant of the lens combinator unsafePartsOf.

Coalgebras and Automata

Lobsters Hottest

An introductory literate Haskell document exploring the relationship between coalgebras and automata, demonstrating how state machines can be modeled using fold and unfold operations within category theory.