Skip to content

Commit 3a75f5f

Browse files
committed
comment: extensively on the design rationale
1 parent b707d83 commit 3a75f5f

File tree

1 file changed

+70
-1
lines changed

1 file changed

+70
-1
lines changed

src/Algebra/Construct/Sub/Group.agda

Lines changed: 70 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -2,6 +2,9 @@
22
-- The Agda standard library
33
--
44
-- Definition of subgroup via Group monomorphism
5+
--
6+
-- Based on Nathan van Doorn (Taneb)'s original PR
7+
-- https://github.com/agda/agda-stdlib/pull/2852
58
------------------------------------------------------------------------
69

710
{-# OPTIONS --safe --cubical-compatible #-}
@@ -17,14 +20,80 @@ open import Level using (suc; _⊔_)
1720
private
1821
module G = Group G
1922

23+
------------------------------------------------------------------------
24+
-- Definition
25+
--
26+
-- Fundamentally, this design is the same as in the above PR:
27+
-- a `SubX` is given by an `X` monomorphism...
28+
-- ... to be able to define such, the current library design requires
29+
-- * *some* `X`-domain of definition for the mono, here given by the
30+
-- placeholder name `domain`, which otherwise plays no role externally
31+
-- * an underlying bare ('raw') function defining the mono, here called
32+
-- (in search of a canonical name) `ι`, standing for 'injection'
33+
-- * the juice: that `ι` indeed defines a mono from the domain to the
34+
-- (underlying defining `rawX` subfield of the) top-level `X` module parameter
35+
2036
record Subgroup c′ ℓ′ : Set (c ⊔ ℓ ⊔ suc (c′ ⊔ ℓ′)) where
2137
field
38+
39+
-- as above, this name is essentially arbitrary,
40+
-- exisitng solely to be mentioned in the third field below
41+
2242
domain : RawGroup c′ ℓ′
23-
ι : _ G.Carrier
43+
44+
-- this function (obviously) needs a source and target:
45+
-- * the target, for the sake of the third field, needs to be
46+
-- `Carrier` subfield of the top-level `X` module parameter
47+
-- * the source, however, really exists solely to give a type to `ι`
48+
-- and indeed, the typechecker can infer (from the third field)
49+
-- that this type *must* be the `Carrier` of the `RawX` `domain`
50+
51+
-- Taneb's design introduces a `private` module
52+
-- `private module H = RawGroup domain`
53+
-- for the sake of affording easy/easier named access to its
54+
-- `Carrier` field, and as preferable to the hideous explicit form
55+
-- `RawGroup.Carrier domain` which is the definiens of `H.Carrier`
56+
57+
-- Neither is necessary, but can be, and is, reconstructed by the
58+
-- typechecker by offering instead a placeholder, in exactly the same way
59+
-- that `domain` exists as a named field solely to express the dependency
60+
-- in the type of `ι-monomorphism`. In that sense, it is an ephemeral form
61+
-- derived from `domain`, which moreover will never play a role in client
62+
-- uses of this module, except as a typing constraint on any application
63+
-- of `ι`, a constraint which is already inherited (by definitional equality!)
64+
-- from the type of the `⟦_⟧` parameter to `IsXHomomorphism`...
65+
66+
ι : _ G.Carrier -- where _ = RawGroup.Carrier domain
67+
68+
-- now all the pieces are in place, we can define what we *really* want
69+
2470
ι-monomorphism : IsGroupMonomorphism domain G.rawGroup ι
2571

72+
-- this is 'admin': any client module of `Subgroup` will likely want to
73+
-- refer to primitive *and* manifest subfields of `IsXMonmorphism`, so
74+
-- this is automatically made available to clients, but not `open`ed,
75+
-- so that such affordance is client-definable, as usual.
76+
2677
module ι = IsGroupMonomorphism ι-monomorphism
2778

79+
-- Similarly, but mathematically motivated: any client module of `Subgroup`
80+
-- will want access to *the `X` defined as the domain of the `IsXMonomorphism`*.
81+
-- But here, it is both automatically made available to clients, as above,
82+
-- *and* also `open`ed, so that its affordances are offered to any client
83+
-- via the 'canonical' names associated with the `X`/`IsX` bundle/structure
84+
85+
-- Taneb's design does this in two steps:
86+
-- * first, create the `IsX` structure, with name `isX`
87+
-- * second, create the `X` bundle` via `isX`
88+
89+
-- My own thinking on this has evolved: I would rather go straight for the
90+
-- bundle, from which `isX : IsX ...` is definable/exported by `open`.
91+
-- This avoids having to recapitulate the verbose telescope involved in any
92+
-- `IsX <telescope>` (and any design decisions/commitments around such things),
93+
-- or having to choose a name for the `isX` field, when, once again, all the
94+
-- heavy lifting is already made available by the `XHomomorphism` module, so
95+
-- for general DRY reasons, should not be repeated here.
96+
2897
group : Group _ _
2998
group = record { isGroup = isGroup ι-monomorphism G.isGroup }
3099

0 commit comments

Comments
 (0)