{-# OPTIONS --without-K --safe #-}
module Cats.Category.Constructions.Terminal where
open import Data.Product using (proj₁ ; proj₂)
open import Level
open import Cats.Category.Base
import Cats.Category.Constructions.Iso as Iso
import Cats.Category.Constructions.Unique as Unique
module Build {lo la l≈} (Cat : Category lo la l≈) where
open Category Cat
open Iso.Build Cat
open Unique.Build Cat
IsTerminal : Obj → Set (lo ⊔ la ⊔ l≈)
IsTerminal ⊤ = ∀ X → ∃! X ⊤
record HasTerminal : Set (lo ⊔ la ⊔ l≈) where
field
⊤ : Obj
isTerminal : IsTerminal ⊤
! : ∀ X → X ⇒ ⊤
! X = ∃!′.arr (isTerminal X)
!-unique : ∀ {X} (f : X ⇒ ⊤) → ! X ≈ f
!-unique {X} f = ∃!′.unique (isTerminal X) _
⇒⊤-unique : ∀ {X} (f g : X ⇒ ⊤) → f ≈ g
⇒⊤-unique f g = ≈.trans (≈.sym (!-unique f)) (!-unique g)
⊤-unique : ∀ {X} → IsTerminal X → X ≅ ⊤
⊤-unique {X} term = record
{ forth = ! X
; back = term ⊤ .∃!′.arr
; back-forth = ≈.trans (≈.sym (term X .∃!′.unique _)) (term X .∃!′.unique _)
; forth-back = ⇒⊤-unique _ _
}
terminal-unique : ∀ {X Y} → IsTerminal X → IsTerminal Y → X ≅ Y
terminal-unique X-term Y-term
= HasTerminal.⊤-unique (record { isTerminal = Y-term }) X-term
open Build public using (HasTerminal)
private
open module Build′ {lo la l≈} {C : Category lo la l≈}
= Build C public using (IsTerminal ; terminal-unique)