open import Level
open import Data.List
open import Data.Nat
open import Data.Product
open import Data.Unit
module Normalise where
private
record Aggregate {ℓ} {t : Set ℓ} (_ : t) : Set (Level.suc ℓ) where
field
items : List (∃ λ (t' : Set ℓ) → t')
open Aggregate
unAggregateTypes : ∀ {ℓ} → List (∃ (λ (t' : Set ℓ) → t')) → _
unAggregateTypes [] = Lift ⊤
unAggregateTypes ((t , _) ∷ []) = t
unAggregateTypes ((t , _) ∷ xs) = t × unAggregateTypes xs
unAggregate : ∀ {ℓ} {t : Set ℓ} {x : t} → (c : Aggregate x) → unAggregateTypes (items c)
unAggregate record { items = [] } = lift tt
unAggregate record { items = items } = f items
where
f : (zs : _) → unAggregateTypes zs
f [] = lift tt
f ((_ , i) ∷ []) = i
f ((_ , i) ∷ x ∷ xs) = i , f (x ∷ xs)
instance
×-instance : ∀ {ℓ} {t₁ : Set ℓ} {t₂ : Set ℓ} {x : t₁} {y : t₂} {{_ : Aggregate x}} {{_ : Aggregate y}} → Aggregate (x , y)
×-instance {{i}} {{j}} = record { items = items i ++ items j }
module add {ℓ} (t : Set ℓ) where
instance
i : ∀ {x : t} → Aggregate x
i {x} = record { items = (_ , x) ∷ [] }
refactor : ∀ {ℓ₁ ℓ₂} {t₁ : Set ℓ₁} {t₂ : Set ℓ₂} (x : t₁ × t₂) {{_ : Aggregate x}} → _
refactor _ {{i}} = unAggregate i
open Normalise
mess : ((((⊤ × ℕ) × ℕ) × (ℕ × ⊤)) × (⊤ → ⊤))
mess = (((tt , 3) , 7) , (5 , tt)) , λ x → x
clean : ⊤ × ℕ × ℕ × ℕ × ⊤ × (⊤ → ⊤)
clean = refactor mess
where
open add (⊤ → ⊤)
open add ⊤
open add ℕ
poly : ∀ {a b c d e : Set} → (((a × b × c) × d) × e) → a × b × c × d × e
poly {a} {b} {c} {d} {e} mess = refactor mess
where
open add a
open add b
open add c
open add d
open add e