module Functions.Views where open import Data.Nat using (ℕ; zero; suc; _<_; _>_; s≤s; z≤n; _+_; _*_) open import Data.Sum using (_⊎_; inj₁; inj₂) open import Relation.Binary.PropositionalEquality using (_≡_; refl)
Let A be a type.
Let P : A → Set a disjunction (parameterized on A).
A view on A is a function with type (a : A) → P a.
Assume the following definitions.
data Even : ℕ → Set
data Odd  : ℕ → Set
data Even where
  zero : Even zero
  odd  : ∀ {n} → Odd n → Even (suc n)
data Odd where
  even : ∀ {n} → Even n → Odd (suc n)
The parity view:
parity : ∀ n → Even n ⊎ Odd n parity zero = inj₁ zero parity (suc n) with parity n parity (suc n) | inj₁ x = inj₂ (even x) parity (suc n) | inj₂ y = inj₁ (odd y)
The ordering view is a view on ℕ × ℕ (in curried form):
ordering : ∀ n m → n < m ⊎ n ≡ m ⊎ n > m
Define the ordering view!
The disjunction of the view can be replaced by an individual data type:
Even n ⊎ Odd n ~ Parity n where
data Parity : ℕ → Set where even : ∀ n → Parity (n * 2) odd : ∀ n → Parity (1 + n * 2)
n < m  ⊎  n ≡ m  ⊎  n > m ~ Ordering n m where
data Ordering : ℕ → ℕ → Set where less : ∀ m k → Ordering m (suc (m + k)) equal : ∀ m → Ordering m m greater : ∀ m k → Ordering (suc (m + k)) m
Define the functions
parity′ : ∀ n → Parity n
compare : ∀ m n → Ordering m n
If we pattern match on parity n we learn not only whether n is even or odd but we also get a proof of it. From the proof we can get additional information too (like what is the half of n).
Views are very handy with the with construct.
Parity:⌊_/2⌋ : ℕ → ℕ -- half (⌊ 1 /2⌋ = 0)
Parity when implementing the view function.