{-
Now records.
-}
module Records where
open import Data.Unit using (⊤; tt)
open import Data.Bool
-- Records are just Σ-types. So here's Σ:
record Σ (A : Set)(B : A → Set) : Set where
field
fst : A
snd : B fst
-- Building record values
ex : Σ Bool T
ex = record { fst = true; snd = tt }
{-
What about accessing the fields?
There are two ways one might want to do this:
• Projection, for instance using projection functions
fst : ∀ {A B} → Σ A B → A
snd : ∀ {A B}(p : Σ A B) → B (fst p)
• Opening, given p : Σ A B we might want to open p to get
fst : A
snd : B fst
Using the module system we can get both!
For each record you get a parameterized module
containing projection functions:
record R : Set where
field
x₁ : A₁
x₂ : A₂ [x₁]
...
xn : An [x₁..xn-1]
module R (r : R) where
x₁ : A₁
x₂ : A₂ [x₁]
...
xn : An [x₁..xn-1]
-}
-- Doing C-c C-o Σ to see the contents of the Σ module gives us:
-- Modules
-- Names
-- fst : {A : Set} {B : A → Set} → Σ A B → A
-- snd : {A : Set} {B : A → Set} (r : Σ A B) → B (Σ.fst r)
-- We can also instantiate it to a particular record value:
open Σ ex renaming (fst to x; snd to y)
-- now x = true : Bool and
-- y = tt : ⊤
-- Let's return to the sort example.
-- We can pack up a set and a comparison function
-- in a Poset record.
record Poset : Set₁ where
field
A : Set
_≤_ : A → A → Bool
-- Definitions inside a record go in the record module.
_≥_ : A → A → Bool
x ≥ y = y ≤ x
op : Poset
op = record { _≤_ = _≥_ }
-- C-c C-o Poset gives us
-- Modules
-- Names
-- _≤_ : (r : Poset) → Poset.A r → Poset.A r → Bool
-- _≥_ : (r : Poset) → Poset.A r → Poset.A r → Bool
-- A : Poset → Set
-- op : (r : Poset) → Poset
open import Data.List
-- Our sort module is now parameterized on a Poset record (not the module).
module Sort (P : Poset) where
-- This is a good example of where opening a record is really nice.
open Poset P
insert : A → List A → List A
insert y [] = y ∷ []
insert y (x ∷ xs) =
if y ≤ x then y ∷ x ∷ xs
else x ∷ insert y xs
sort : List A → List A
sort [] = []
sort (x ∷ xs) = insert x (sort xs)
open import Nat
NAT : Poset
NAT = record { _≤_ = _≤_ } -- the A field can be inferred from _≤_
-- We now instantiate with the NAT poset.
open Sort NAT
-- Now sort : List ℕ → List ℕ
xs = 3 ∷ 7 ∷ 0 ∷ 10 ∷ 2 ∷ []
test₁ = sort xs