1
------------------------------------------------------------------------
3
------------------------------------------------------------------------
5
-- Vectors (as in Data.Vec) also represent n-ary products, so what is
6
-- the point of this module? The n-ary products below are intended to
7
-- be used with a fixed n, in which case the nil constructor can be
8
-- avoided: pairs are represented as pairs (x , y), not as triples
11
{-# OPTIONS --universe-polymorphism #-}
13
module Data.Product.N-ary where
16
open import Data.Product
19
open import Function.Inverse
21
open import Relation.Binary.PropositionalEquality as P using (_≡_)
27
_^_ : ∀ {ℓ} → Set ℓ → ℕ → Set ℓ
30
A ^ suc (suc n) = A × A ^ suc n
34
⇿Vec : ∀ {a} {A : Set a} n → A ^ n ⇿ Vec A n
36
{ to = P.→-to-⟶ (toVec n)
37
; from = P.→-to-⟶ fromVec
39
{ left-inverse-of = fromVec∘toVec n
40
; right-inverse-of = toVec∘fromVec
44
toVec : ∀ {a} {A : Set a} n → A ^ n → Vec A n
45
toVec 0 (lift tt) = []
47
toVec (suc (suc n)) (x , xs) = x ∷ toVec _ xs
49
fromVec : ∀ {a} {A : Set a} {n} → Vec A n → A ^ n
52
fromVec (x ∷ y ∷ xs) = (x , fromVec (y ∷ xs))
54
fromVec∘toVec : ∀ {a} {A : Set a} n (xs : A ^ n) →
55
fromVec (toVec n xs) ≡ xs
56
fromVec∘toVec 0 (lift tt) = P.refl
57
fromVec∘toVec 1 x = P.refl
58
fromVec∘toVec 2 (x , y) = P.refl
59
fromVec∘toVec (suc (suc (suc n))) (x , y , xs) =
60
P.cong (_,_ x) (fromVec∘toVec (suc (suc n)) (y , xs))
62
toVec∘fromVec : ∀ {a} {A : Set a} {n} (xs : Vec A n) →
63
toVec n (fromVec xs) ≡ xs
64
toVec∘fromVec [] = P.refl
65
toVec∘fromVec (x ∷ []) = P.refl
66
toVec∘fromVec (x ∷ y ∷ xs) = P.cong (_∷_ x) (toVec∘fromVec (y ∷ xs))