-
Notifications
You must be signed in to change notification settings - Fork 644
Egg #4: Agda style records and modules
Matúš Tejiščák edited this page Apr 3, 2015
·
6 revisions
- Both modules and records can be parameterised but not indexed.
- Modules cannot take other modules as parameters.
- It does not make sense because every module is both a record type declaration and a definition of the single instance thereof.
- Hence, if a module takes another module, it can't tell what's in the taken module.
This:
record IsMagma (M : Type) : Type where constructor MkIsMagma -- or autogenerated if not named fields (*) : M -> M -> M
should desugar to this:
record IsMagma : Type -> Type where MkIsMagma : ((*) : M -> M -> M) -> IsMagma M
Notes:
- records cannot be indexed, only parameterised
- all parameters must be named (so that we know how to index)
-
IsMagma : Type -> Type where (*) : M -> M -> M
won't work because there's no indication that theM
is actually the parameter
-
- we need to deal with infix ops somehow
This:
f = x * y where open Fin_isMonoid n
should desugar to this:
f = x * y where __M0 = Fin_isMonoid n (*) = proj_* __M0 unit = proj_unit __M0 assoc = proj_assoc __M0
or, better, if we had pattern-matching where:
f = x * y where MkMonoid (*) unit assoc = Fin_isMonoid n
Notes:
- the above works nicely with
using
,renaming..to
, andhiding
- record opening could probably work at top-level, too
You can use the keyword open
in record declarations to mark some sub-fields as recursively auto-opening:
record IsSemigroup : (a : Type) -> Type where fields open isMagma : IsMagma a -- opens automatically assoc : (a * b) * c = a * (b * c) someRandomMagma : IsMagma a -- does not open automatically f : IsSemigroup a -> ... f sg = ... foo * bar ... assoc ... where open sg -- automatically opens the underlying isMagma, too -- (but not someRandomMagma)
In Agda, records can be constructed by explicitly assigning each field. For example we might have an equivalence relation
record { refl = ... ; sym = ... ; trans = ... }
It could be nice to borrow this syntax with the obvious desugaring. If the clear ambiguity here is undesired, the explicit syntax could require the type (or constructor) name:
record IsEquiv { ... }
This:
module M (x₁ : τ₁) ... (xₙ : τₙ) where f₁ : σ₁ f₁ = f₁_def ... fₙ : σₙ fₙ = fₙ_def
should desugar to these two declarations:
record __M_type : Type where MkM : (x₁ : τ₁) -> ... -> (xₙ : τₙ) -> (f₁ : σ₁) -> ... -> (fₙ : σₙ) -> M_type
M : (x₁ : τ₁) -> ... -> (xₙ : τₙ) -> __M_type M x₁ ... xₙ = MkM f₁_def ... fₙ_def
Some fᵢ_def
might need to be hoisted to top-level because they may need to pattern-match.
- A saturated module is a record, which is opened exactly as a regular record.
- An unsaturated module is a function. Let's generalise
open
to functions, too.- The target of the function must be a record.
- Assuming a module
M x y z
, the statementopen M x
adds aλ y z. fᵢ
in front of every fieldfᵢ
of the target of the function.
Binary Packages
Tool Support
Community
- Libraries, available elsewhere
- Idris Developer Meetings
- The Zen of Idris
- Non English Resources
Development