-
Notifications
You must be signed in to change notification settings - Fork 634
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 -> Mwon't work because there's no indication that theMis 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
opento functions, too.- The target of the function must be a record.
- Assuming a module
M x y z, the statementopen M xadds 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