Comonads

Comonad definitions with counits, comultiplications, and comonad laws.

comonads

Comonads and coKleisli categories on V-enriched FinSet.

A comonad (W, ε, δ) consists of an endofunctor W, a counit ε: W ⇒ Id, and a comultiplication δ: W ⇒ W² satisfying:

W(δ) ∘ δ = δ_W ∘ δ     (coassociativity)
ε_W ∘ δ = id             (left counit)
W(ε) ∘ δ = id            (right counit)

The coKleisli category of a comonad has the same objects but morphisms A → B are morphisms W(A) → B in the base category, composed via:

f =>> g = g ∘ W(f) ∘ δ_A

This module provides:

Comonad (abstract)
├── CofreeComonad           — cofree comonad from a functor
└── DiagonalComonad         — W(A) = A × A with diagonal/projection

CoKleisliCategory — wraps a comonad for composition

Comonad

Bases: ABC

Abstract comonad (W, ε, δ) on V-enriched FinSet.

Subclasses must implement endofunctor, counit, and comultiply. CoKleisli composition is derived.

endofunctor abstractmethod property

endofunctor: Functor

The underlying endofunctor W.

counit abstractmethod

counit(obj: SetObject) -> Morphism

The counit component ε_A: W(A) → A.

PARAMETER DESCRIPTION
obj

The object A.

TYPE: SetObject

RETURNS DESCRIPTION
Morphism

The counit morphism ε_A.

Source code in src/quivers/monadic/comonads.py
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
@abstractmethod
def counit(self, obj: SetObject) -> Morphism:
    """The counit component ε_A: W(A) → A.

    Parameters
    ----------
    obj : SetObject
        The object A.

    Returns
    -------
    Morphism
        The counit morphism ε_A.
    """
    ...

comultiply abstractmethod

comultiply(obj: SetObject) -> Morphism

The comultiplication component δ_A: W(A) → W(W(A)).

PARAMETER DESCRIPTION
obj

The object A.

TYPE: SetObject

RETURNS DESCRIPTION
Morphism

The comultiplication morphism δ_A.

Source code in src/quivers/monadic/comonads.py
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
@abstractmethod
def comultiply(self, obj: SetObject) -> Morphism:
    """The comultiplication component δ_A: W(A) → W(W(A)).

    Parameters
    ----------
    obj : SetObject
        The object A.

    Returns
    -------
    Morphism
        The comultiplication morphism δ_A.
    """
    ...

cokleisli_compose

cokleisli_compose(f: Morphism, g: Morphism) -> Morphism

CoKleisli composition: f =>> g = g ∘ W(f) ∘ δ_A.

For f: W(A) → B and g: W(B) → C, produces W(A) → C.

PARAMETER DESCRIPTION
f

Left coKleisli morphism W(A) → B.

TYPE: Morphism

g

Right coKleisli morphism W(B) → C.

TYPE: Morphism

RETURNS DESCRIPTION
Morphism

Composed coKleisli morphism W(A) → C.

Source code in src/quivers/monadic/comonads.py
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
def cokleisli_compose(self, f: Morphism, g: Morphism) -> Morphism:
    """CoKleisli composition: f =>> g = g ∘ W(f) ∘ δ_A.

    For f: W(A) → B and g: W(B) → C, produces W(A) → C.

    Parameters
    ----------
    f : Morphism
        Left coKleisli morphism W(A) → B.
    g : Morphism
        Right coKleisli morphism W(B) → C.

    Returns
    -------
    Morphism
        Composed coKleisli morphism W(A) → C.
    """
    delta = self._comultiply_at_domain(f)
    wf = self.endofunctor.map_morphism(f)
    return delta >> wf >> g

CoKleisliCategory

CoKleisliCategory(comonad: Comonad)

The coKleisli category of a comonad.

Objects are the same as the base category. Morphisms A → B in the coKleisli category are morphisms W(A) → B in the base category.

PARAMETER DESCRIPTION
comonad

The underlying comonad.

TYPE: Comonad

Source code in src/quivers/monadic/comonads.py
132
133
def __init__(self, comonad: Comonad) -> None:
    self._comonad = comonad

comonad property

comonad: Comonad

The underlying comonad.

identity

identity(obj: SetObject) -> Morphism

CoKleisli identity at object A: ε_A: W(A) → A.

PARAMETER DESCRIPTION
obj

The object A.

TYPE: SetObject

RETURNS DESCRIPTION
Morphism

The coKleisli identity morphism.

Source code in src/quivers/monadic/comonads.py
140
141
142
143
144
145
146
147
148
149
150
151
152
153
def identity(self, obj: SetObject) -> Morphism:
    """CoKleisli identity at object A: ε_A: W(A) → A.

    Parameters
    ----------
    obj : SetObject
        The object A.

    Returns
    -------
    Morphism
        The coKleisli identity morphism.
    """
    return self._comonad.counit(obj)

compose

compose(f: Morphism, g: Morphism) -> Morphism

CoKleisli composition: f =>> g.

PARAMETER DESCRIPTION
f

Left morphism W(A) → B.

TYPE: Morphism

g

Right morphism W(B) → C.

TYPE: Morphism

RETURNS DESCRIPTION
Morphism

Composed morphism W(A) → C.

Source code in src/quivers/monadic/comonads.py
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
def compose(self, f: Morphism, g: Morphism) -> Morphism:
    """CoKleisli composition: f =>> g.

    Parameters
    ----------
    f : Morphism
        Left morphism W(A) → B.
    g : Morphism
        Right morphism W(B) → C.

    Returns
    -------
    Morphism
        Composed morphism W(A) → C.
    """
    return self._comonad.cokleisli_compose(f, g)

DiagonalComonad

DiagonalComonad(quantale: Quantale | None = None)

Bases: Comonad

The diagonal comonad W(A) = A × A with projection and diagonal.

ε_A: A × A → A is the first projection. δ_A: A × A → (A × A) × (A × A) is the diagonal on pairs.

This comonad models "contexts" where each element has access to a pair of values. It arises from the product adjunction Δ ⊣ ×.

PARAMETER DESCRIPTION
quantale

The enrichment algebra. Defaults to PRODUCT_FUZZY.

TYPE: Quantale or None DEFAULT: None

Source code in src/quivers/monadic/comonads.py
189
190
191
def __init__(self, quantale: Quantale | None = None) -> None:
    self._quantale = quantale if quantale is not None else PRODUCT_FUZZY
    self._functor = _DiagonalFunctor()

quantale property

quantale: Quantale

The enrichment algebra.

endofunctor property

endofunctor: Functor

W(A) = A × A.

counit

counit(obj: SetObject) -> Morphism

ε_A: A × A → A is first projection.

PARAMETER DESCRIPTION
obj

The object A.

TYPE: SetObject

RETURNS DESCRIPTION
ObservedMorphism

The projection morphism.

Source code in src/quivers/monadic/comonads.py
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
def counit(self, obj: SetObject) -> Morphism:
    """ε_A: A × A → A is first projection.

    Parameters
    ----------
    obj : SetObject
        The object A.

    Returns
    -------
    ObservedMorphism
        The projection morphism.
    """
    import itertools

    source = ProductSet(components=(obj, obj))
    data = torch.full((*source.shape, *obj.shape), self._quantale.zero)
    for idx in itertools.product(*(range(s) for s in obj.shape)):
        for idx2 in itertools.product(*(range(s) for s in obj.shape)):
            data[idx + idx2 + idx] = self._quantale.unit
    return observed(source, obj, data, quantale=self._quantale)

comultiply

comultiply(obj: SetObject) -> Morphism

δ_A: A × A → (A × A) × (A × A) is diagonal on pairs.

Maps (a1, a2) to ((a1, a2), (a1, a2)).

PARAMETER DESCRIPTION
obj

The object A.

TYPE: SetObject

RETURNS DESCRIPTION
ObservedMorphism

The comultiplication morphism.

Source code in src/quivers/monadic/comonads.py
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
def comultiply(self, obj: SetObject) -> Morphism:
    """δ_A: A × A → (A × A) × (A × A) is diagonal on pairs.

    Maps (a1, a2) to ((a1, a2), (a1, a2)).

    Parameters
    ----------
    obj : SetObject
        The object A.

    Returns
    -------
    ObservedMorphism
        The comultiplication morphism.
    """
    import itertools

    source = ProductSet(components=(obj, obj))
    target = ProductSet(components=(obj, obj, obj, obj))
    data = torch.full((*source.shape, *target.shape), self._quantale.zero)
    for idx1 in itertools.product(*(range(s) for s in obj.shape)):
        for idx2 in itertools.product(*(range(s) for s in obj.shape)):
            src = idx1 + idx2
            tgt = idx1 + idx2 + idx1 + idx2
            data[src + tgt] = self._quantale.unit
    return observed(source, target, data, quantale=self._quantale)

cokleisli_compose

cokleisli_compose(f: Morphism, g: Morphism) -> Morphism

CoKleisli composition using the diagonal comonad.

Source code in src/quivers/monadic/comonads.py
252
253
254
255
256
def cokleisli_compose(self, f: Morphism, g: Morphism) -> Morphism:
    """CoKleisli composition using the diagonal comonad."""
    delta = self.comultiply(self._extract_base(f.domain))
    wf = self._functor.map_morphism(f)
    return delta >> wf >> g

CofreeComonad

CofreeComonad(store: SetObject, quantale: Quantale | None = None)

Bases: Comonad

The cofree comonad W(A) = A × S for a fixed store object S.

Also known as the "store comonad" or "costate comonad" on finite sets.

ε_A: A × S → A is the first projection (extract the value). δ_A: A × S → (A × S) × S duplicates the store component.

PARAMETER DESCRIPTION
store

The fixed store/environment object S.

TYPE: SetObject

quantale

The enrichment algebra. Defaults to PRODUCT_FUZZY.

TYPE: Quantale or None DEFAULT: None

Source code in src/quivers/monadic/comonads.py
299
300
301
302
def __init__(self, store: SetObject, quantale: Quantale | None = None) -> None:
    self._store = store
    self._quantale = quantale if quantale is not None else PRODUCT_FUZZY
    self._functor = _StoreFunctor(store)

store property

store: SetObject

The store object S.

quantale property

quantale: Quantale

The enrichment algebra.

endofunctor property

endofunctor: Functor

W(A) = A × S.

counit

counit(obj: SetObject) -> Morphism

ε_A: A × S → A is the first projection.

PARAMETER DESCRIPTION
obj

The object A.

TYPE: SetObject

RETURNS DESCRIPTION
ObservedMorphism

The extraction morphism.

Source code in src/quivers/monadic/comonads.py
319
320
321
322
323
324
325
326
327
328
329
330
331
332
333
334
335
336
337
338
339
def counit(self, obj: SetObject) -> Morphism:
    """ε_A: A × S → A is the first projection.

    Parameters
    ----------
    obj : SetObject
        The object A.

    Returns
    -------
    ObservedMorphism
        The extraction morphism.
    """
    import itertools

    source = ProductSet(components=(obj, self._store))
    data = torch.full((*source.shape, *obj.shape), self._quantale.zero)
    for a_idx in itertools.product(*(range(s) for s in obj.shape)):
        for s_idx in itertools.product(*(range(s) for s in self._store.shape)):
            data[a_idx + s_idx + a_idx] = self._quantale.unit
    return observed(source, obj, data, quantale=self._quantale)

comultiply

comultiply(obj: SetObject) -> Morphism

δ_A: A × S → (A × S) × S duplicates the store.

Maps (a, s) to ((a, s), s).

PARAMETER DESCRIPTION
obj

The object A.

TYPE: SetObject

RETURNS DESCRIPTION
ObservedMorphism

The comultiplication morphism.

Source code in src/quivers/monadic/comonads.py
341
342
343
344
345
346
347
348
349
350
351
352
353
354
355
356
357
358
359
360
361
362
363
364
365
366
def comultiply(self, obj: SetObject) -> Morphism:
    """δ_A: A × S → (A × S) × S duplicates the store.

    Maps (a, s) to ((a, s), s).

    Parameters
    ----------
    obj : SetObject
        The object A.

    Returns
    -------
    ObservedMorphism
        The comultiplication morphism.
    """
    import itertools

    source = ProductSet(components=(obj, self._store))
    target = ProductSet(components=(obj, self._store, self._store))
    data = torch.full((*source.shape, *target.shape), self._quantale.zero)
    for a_idx in itertools.product(*(range(s) for s in obj.shape)):
        for s_idx in itertools.product(*(range(s) for s in self._store.shape)):
            src = a_idx + s_idx
            tgt = a_idx + s_idx + s_idx
            data[src + tgt] = self._quantale.unit
    return observed(source, target, data, quantale=self._quantale)