\begin{code} {-# OPTIONS --safe --without-K #-} module UF.Retracts-FunExt where open import MLTT.Spartan open import UF.Retracts open import UF.FunExt retract-variance : ∀ {𝓣} {X : 𝓤 ̇ } {Y : 𝓥 ̇ } {X' : 𝓦 ̇ } {Y' : 𝓣 ̇ } → funext 𝓤 𝓣 → retract X of X' → retract Y' of Y → retract (X → Y') of (X' → Y) retract-variance {𝓤} {𝓥} {𝓦} {𝓣} {X} {Y} {X'} {Y'} fe (rx , sx , rsx) (ry , sy , rsy) = γ where r : (X' → Y) → X → Y' r f x = ry (f (sx x)) s : (X → Y') → X' → Y s f' x' = sy (f' (rx x')) rs' : (f' : X → Y') (x : X) → ry (sy (f' (rx (sx x)))) = f' x rs' f' x = rsy (f' (rx (sx x))) ∙ ap f' (rsx x) rs : (f' : X → Y') → r (s f') = f' rs f' = dfunext fe (rs' f') γ : retract (X → Y') of (X' → Y) γ = (r , s , rs) retract-contravariance : funext 𝓤 𝓦 → {X : 𝓤 ̇ } {Y : 𝓥 ̇ } {Y' : 𝓦 ̇ } → retract Y' of Y → retract (X → Y') of (X → Y) retract-contravariance fe = retract-variance fe identity-retraction retract-covariance : {X : 𝓤 ̇ } {Y : 𝓥 ̇ } {X' : 𝓦 ̇ } → funext 𝓤 𝓥 → retract X of X' → retract (X → Y) of (X' → Y) retract-covariance fe rx = retract-variance fe rx identity-retraction codomain-is-retract-of-function-space-with-pointed-domain : {X : 𝓤 ̇ } {Y : 𝓥 ̇ } → X → retract Y of (X → Y) codomain-is-retract-of-function-space-with-pointed-domain x = ((λ f → f x) , ((λ y x → y) , λ y → refl)) retracts-of-closed-under-exponentials : {X : 𝓤 ̇ } {Y : 𝓥 ̇ } {B : 𝓦 ̇ } → funext 𝓦 𝓦 → X → retract B of X → retract B of Y → retract B of (X → Y) retracts-of-closed-under-exponentials {𝓤} {𝓥} {𝓦} {X} {Y} {B} fe x rbx rby = ii where i : retract (B → B) of (X → Y) i = retract-variance fe rbx rby ii : retract B of (X → Y) ii = retracts-compose i (codomain-is-retract-of-function-space-with-pointed-domain (pr₁ rbx x)) \end{code}