{-# OPTIONS --without-K --safe #-}
module Cats.Functor where
open import Level
open import Relation.Binary using (_Preserves_⟶_)
open import Cats.Category.Base
open import Cats.Util.Function using () renaming (_∘_ to _⊙_)
open import Cats.Util.SetoidMorphism using (_⇒_ ; IsInjective ; IsSurjective)
open import Cats.Util.SetoidMorphism.Iso using
( IsIso ; _≅_ ; IsIso→≅ ; Injective∧Surjective→Iso ; Iso→Injective
; Iso→Surjective )
import Cats.Category.Constructions.Iso as Iso
open Iso.Iso
infixr 9 _∘_
record Functor {lo la l≈ lo′ la′ l≈′}
(C : Category lo la l≈)
(D : Category lo′ la′ l≈′)
: Set (lo ⊔ la ⊔ l≈ ⊔ lo′ ⊔ la′ ⊔ l≈′)
where
private
module C = Category C
module C≅ = Iso.Build C
module D = Category D
module D≅ = Iso.Build D
field
fobj : C.Obj → D.Obj
fmap : ∀ {A B} → A C.⇒ B → fobj A D.⇒ fobj B
fmap-resp : ∀ {A B} → fmap {A} {B} Preserves C._≈_ ⟶ D._≈_
fmap-id : ∀ {A} → fmap (C.id {A}) D.≈ D.id
fmap-∘ : ∀ {A B C} {f : B C.⇒ C} {g : A C.⇒ B}
→ fmap f D.∘ fmap g D.≈ fmap (f C.∘ g)
sfmap : ∀ {a b} → C.Hom a b ⇒ D.Hom (fobj a) (fobj b)
sfmap = record
{ arr = fmap
; resp = fmap-resp
}
fobj-resp : fobj Preserves C≅._≅_ ⟶ D≅._≅_
fobj-resp {i} {j} x≅y
= record
{ forth = fmap (forth x≅y)
; back = fmap (back x≅y)
; back-forth
= begin
fmap (back x≅y) D.∘ fmap (forth x≅y)
≈⟨ fmap-∘ ⟩
fmap (back x≅y C.∘ forth x≅y)
≈⟨ fmap-resp (back-forth x≅y) ⟩
fmap C.id
≈⟨ fmap-id ⟩
D.id
∎
; forth-back
= begin
fmap (forth x≅y) D.∘ fmap (back x≅y)
≈⟨ fmap-∘ ⟩
fmap (forth x≅y C.∘ back x≅y)
≈⟨ fmap-resp (forth-back x≅y) ⟩
fmap C.id
≈⟨ fmap-id ⟩
D.id
∎
}
where
open D.≈-Reasoning
open Functor public
id : ∀ {lo la l≈} {C : Category lo la l≈} → Functor C C
id {C = C} = record
{ fobj = λ x → x
; fmap = λ f → f
; fmap-resp = λ eq → eq
; fmap-id = ≈.refl
; fmap-∘ = ≈.refl
}
where
open Category C
_∘_ : ∀ {lo la l≈ lo′ la′ l≈′ lo″ la″ l≈″}
→ {C : Category lo la l≈}
→ {D : Category lo′ la′ l≈′}
→ {E : Category lo″ la″ l≈″}
→ Functor D E → Functor C D → Functor C E
_∘_ {E = E} F G = record
{ fobj = fobj F ⊙ fobj G
; fmap = fmap F ⊙ fmap G
; fmap-resp = fmap-resp F ⊙ fmap-resp G
; fmap-id = ≈.trans (fmap-resp F (fmap-id G)) (fmap-id F)
; fmap-∘ = ≈.trans (fmap-∘ F) (fmap-resp F (fmap-∘ G))
}
where
open Category E
module _ {lo la l≈ lo′ la′ l≈′}
{C : Category lo la l≈} {D : Category lo′ la′ l≈′}
(F : Functor C D)
where
private
module C = Category C
module D = Category D
IsFaithful : Set (lo ⊔ la ⊔ l≈ ⊔ l≈′)
IsFaithful = ∀ {a b} → IsInjective (sfmap F {a} {b})
IsFull : Set (lo ⊔ la ⊔ la′ ⊔ l≈′)
IsFull = ∀ {a b} → IsSurjective (sfmap F {a} {b})
IsEmbedding : Set (lo ⊔ la ⊔ l≈ ⊔ la′ ⊔ l≈′)
IsEmbedding = ∀ {a b} → IsIso (sfmap F {a} {b})
Embedding→≅ : IsEmbedding → ∀ {a b} → C.Hom a b ≅ D.Hom (fobj F a) (fobj F b)
Embedding→≅ embedding = IsIso→≅ (sfmap F) embedding
Full∧Faithful→Embedding : IsFull → IsFaithful → IsEmbedding
Full∧Faithful→Embedding full faithful
= Injective∧Surjective→Iso faithful full
Embedding→Full : IsEmbedding → IsFull
Embedding→Full embedding = Iso→Surjective embedding
Embedding→Faithful : IsEmbedding → IsFaithful
Embedding→Faithful embedding = Iso→Injective embedding