{-# OPTIONS --safe --without-K #-}
open import Prelude
module Generics.Telescope where
open import Agda.Builtin.Reflection public using (Visibility; visible; hidden; instance′)
infixr 5 _∷_
infixr 4 _++_
mutual
data Tel : Level → Setω where
[] : Tel lzero
_∷_ : (A : Set ℓ) (T : A → Tel ℓ') → Tel (ℓ ⊔ ℓ')
_++_ : (T : Tel ℓ) (U : ⟦ T ⟧ᵗ → Tel ℓ') → Tel (ℓ ⊔ ℓ')
⟦_⟧ᵗ : Tel ℓ → Set ℓ
⟦ [] ⟧ᵗ = ⊤
⟦ A ∷ T ⟧ᵗ = Σ[ a ∈ A ] ⟦ T a ⟧ᵗ
⟦ T ++ U ⟧ᵗ = Σ[ t ∈ ⟦ T ⟧ᵗ ] ⟦ U t ⟧ᵗ
∷-syntaxᵗ : (A : Set ℓ) (T : A → Tel ℓ') → Tel (ℓ ⊔ ℓ')
∷-syntaxᵗ = _∷_
syntax ∷-syntaxᵗ A (λ x → T) = [ x ∶ A ] T
++-syntaxᵗ : (A : Tel ℓ) (T : ⟦ A ⟧ᵗ → Tel ℓ') → Tel (ℓ ⊔ ℓ')
++-syntaxᵗ = _++_
syntax ++-syntaxᵗ T (λ x → U) = [[ x ∶ T ]] U
data TelInfo (I : Set ℓ) : ∀ {ℓ'} → Tel ℓ' → Setω where
[] : TelInfo I []
_∷_ : {A : Set ℓ'} {T : A → Tel ℓ''}
→ I → ((a : A) → TelInfo I (T a)) → TelInfo I (A ∷ T)
_++_ : {T : Tel ℓ'} {U : ⟦ T ⟧ᵗ → Tel ℓ''}
→ TelInfo I T → ((t : ⟦ T ⟧ᵗ) → TelInfo I (U t)) → TelInfo I (T ++ U)
constTelInfo : {I : Set ℓ} → I → {T : Tel ℓ'} → TelInfo I T
constTelInfo i {[] } = []
constTelInfo i {A ∷ T} = i ∷ λ _ → constTelInfo i
constTelInfo i {T ++ U} = constTelInfo i ++ λ _ → constTelInfo i
Curriedᵗ : (T : Tel ℓ) → TelInfo Visibility T → (⟦ T ⟧ᵗ → Set ℓ') → Set (ℓ ⊔ ℓ')
Curriedᵗ [] _ X = X tt
Curriedᵗ (A ∷ T) (visible ∷ vs) X = ( a : A ) → Curriedᵗ (T a) (vs a) λ t → X (a , t)
Curriedᵗ (A ∷ T) (hidden ∷ vs) X = { a : A } → Curriedᵗ (T a) (vs a) (curry X a)
Curriedᵗ (A ∷ T) (instance′ ∷ vs) X = ⦃ a : A ⦄ → Curriedᵗ (T a) (vs a) (curry X a)
Curriedᵗ (T ++ U) (vs ++ vs') X = Curriedᵗ T vs λ t →
Curriedᵗ (U t) (vs' t) λ u → X (t , u)
curryᵗ : {T : Tel ℓ} {vs : TelInfo Visibility T} {X : ⟦ T ⟧ᵗ → Set ℓ'}
→ ((t : ⟦ T ⟧ᵗ) → X t) → Curriedᵗ T vs X
curryᵗ {T = [] } f = f tt
curryᵗ {T = A ∷ T} {visible ∷ vs} f = λ a → curryᵗ λ u → f (a , u)
curryᵗ {T = A ∷ T} {hidden ∷ vs} f = curryᵗ (curry f _)
curryᵗ {T = A ∷ T} {instance′ ∷ vs} f = curryᵗ (curry f _)
curryᵗ {T = T ++ U} {vs ++ vs'} f = curryᵗ λ t → curryᵗ λ u → f (t , u)
uncurryᵗ : {T : Tel ℓ} {vs : TelInfo Visibility T} {X : ⟦ T ⟧ᵗ → Set ℓ'}
→ Curriedᵗ T vs X → (t : ⟦ T ⟧ᵗ) → X t
uncurryᵗ {T = [] } f tt = f
uncurryᵗ {T = A ∷ T} {visible ∷ vs} f (a , t) = uncurryᵗ (f a ) t
uncurryᵗ {T = A ∷ T} {hidden ∷ vs} f (a , t) = uncurryᵗ (f { a }) t
uncurryᵗ {T = A ∷ T} {instance′ ∷ vs} f (a , t) = uncurryᵗ (f ⦃ a ⦄) t
uncurryᵗ {T = T ++ U} {vs ++ vs'} f (t , u) = uncurryᵗ (uncurryᵗ f t) u
_^_ : Set → ℕ → Set
A ^ zero = ⊤
A ^ suc n = A × (A ^ n)