{-# OPTIONS --type-in-type #-} open import NeilPrelude open import Equational module ApplicativeProps (F : Set → Set) (fmap : {A B : Set} → (A → B) → F A → F B) (pure : {A : Set} → A → F A) (_<*>_ : {A B : Set} → F (A → B) → F A → F B) -- applicative functor laws (fmapLaw : {A B : Set} → {g : A → B} → {fa : F A} → fmap g fa ≡ pure g <*> fa) (identityLaw : {A : Set} → {fa : F A} → pure id <*> fa ≡ fa) (compositionLaw : {A B C : Set} → {fa : F A} → {fbc : F (B → C)} → {fab : F (A → B)} → ((pure (_∘_) <*> fbc) <*> fab) <*> fa ≡ fbc <*> (fab <*> fa)) (homomorphismLaw : {A B : Set} → {f : A → B} → {a : A} → pure f <*> pure a ≡ pure (f a)) (interchangeLaw : {A B : Set} → {fab : F (A → B)} → {a : A} → fab <*> pure a ≡ pure (λ g → g a) <*> fab) where functorLaw1 : {A : Set} → {fa : F A} → fmap id fa ≡ fa functorLaw1 = trans fmapLaw identityLaw functorLaw2 : {A B C : Set} → {f : A → B} → {g : B → C} → {fa : F A} → fmap (g ∘ f) fa ≡ fmap g (fmap f fa) functorLaw2 {_} {_} {_} {f} {g} {fa} = fmap (g ∘ f) fa ≡⟨ fmapLaw ⟩ pure (g ∘ f) <*> fa ≡⟨ cong (flip _<*>_ fa) (sym homomorphismLaw) ⟩ (pure (_∘_ g) <*> pure f) <*> fa ≡⟨ cong (flip _<*>_ fa ∘ flip _<*>_ (pure f)) (sym homomorphismLaw) ⟩ ((pure _∘_ <*> pure g) <*> pure f) <*> fa ≡⟨ compositionLaw ⟩ pure g <*> (pure f <*> fa) ≡⟨ cong (_<*>_ (pure g)) (sym fmapLaw) ⟩ pure g <*> fmap f fa ≡⟨ sym fmapLaw ⟩ fmap g (fmap f fa) QED pointedLaw : {A B : Set} → {f : A → B} → {a : A} → fmap f (pure a) ≡ pure (f a) pointedLaw {_} {_} {f} {a} = fmap f (pure a) ≡⟨ fmapLaw ⟩ pure f <*> pure a ≡⟨ homomorphismLaw ⟩ pure (f a) QED import Applicative open Applicative F fmap pure _<*>_ import PointedProps open PointedProps F fmap pure functorLaw1 functorLaw2 pointedLaw public ---------------------------------------------- -- All Applicative Functors are Static Arrows -- arrowLaw1 : {A B : Set} → {f : F (A → B)} → fmap (_⋙_) (pure id) <*> f ≡ f -- arrowLaw1 {_} {_} {f} = fmap _⋙_ (pure id) <*> f -- ≡⟨ cong2R _<*>_ pointedLaw ⟩ -- pure id <*> f -- ≡⟨ identityLaw ⟩ -- f QED -- arrowLaw3 : {A B C D : Set} → {f : F (A → B)} → {g : F (B → C)} → {h : F (C → D)} → -- fmap (_⋙_) (fmap (_⋙_) f <*> g) <*> h ≡ -- fmap (_⋙_) f <*> (fmap (_⋙_) g <*> h) -- arrowLaw3 {_} {_} {_} {_} {f} {g} {h} = {!!} -- arrowLaw4 : {A B C : Set} → {f : A → B} → {g : B → C} → pure (g ∘ f) ≡ fmap (_⋙_) (pure f) <*> pure g -- arrowLaw4 {_} {_} {_} {f} {g} = pure (g ∘ f) -- ≡⟨ sym homomorphismLaw ⟩ -- pure (_⋙_ f) <*> pure g -- ≡⟨ cong2R _<*>_ (sym pointedLaw) ⟩ -- fmap _⋙_ (pure f) <*> pure g -- QED -- arrowLaw5 : {A B X : Set} → {f : A → B} → fmap (first {_} {X}) (pure f) ≡ pure (first f) -- arrowLaw5 = pointedLaw -- arrowLaw6 : {A B C D : Set} → {f : F (A → B)} → {g : F (B → C)} → -- fmap (first {_} {D}) (fmap (_⋙_) f <*> g) ≡ fmap (_⋙_) (fmap first f) <*> fmap first g -- arrowLaw6 {_} {_} {_} {D} {f} {g} = fmap (first {_} {D}) (fmap _⋙_ f <*> g) -- ≡⟨ fmapLaw ⟩ -- pure (first {_} {D}) <*> (fmap _⋙_ f <*> g) -- ≡⟨ cong2L _<*>_ (cong2R _<*>_ fmapLaw) ⟩ -- pure (first {_} {D}) <*> ((pure _⋙_ <*> f) <*> g) -- ≡⟨ {!!} ⟩ -- (pure (_⋙_ ∘ first) <*> f) <*> (pure first <*> g) -- ≡⟨ cong2R _<*>_ (sym fmapLaw) ⟩ -- fmap (_⋙_ ∘ first) f <*> (pure first <*> g) -- ≡⟨ cong2L _<*>_ (sym fmapLaw) ⟩ -- fmap (_⋙_ ∘ first) f <*> fmap first g -- ≡⟨ cong2R _<*>_ functorLaw2 ⟩ -- fmap _⋙_ (fmap first f) <*> fmap first g -- QED -- arrowLaw7 : {A B C D : Set} → {f : F (A → B)} → {g : C → D} → -- fmap (_⋙_) (fmap first f) <*> pure (second g) ≡ -- fmap (_⋙_) (pure (second g)) <*> fmap first f -- arrowLaw7 = {!!} -- arrowLaw8 : {A B C : Set} → {f : F (A → B)} → -- fmap (_⋙_) (fmap (first {_} {C}) f) <*> pure fst ≡ -- fmap (_⋙_) (pure fst) <*> f -- arrowLaw8 = {!!} -- arrowLaw9 : {A B C D : Set} → {f : F (A → B)} → -- fmap (_⋙_) (fmap (first {_} {C}) (fmap (first {_} {D}) f)) <*> pure ×-assocR ≡ -- fmap (_⋙_) (pure ×-assocR) <*> fmap first f -- arrowLaw9 = {!!} -- staticArrowLaw1 : {A B : Set} → {f : F (A → B)} → -- fmap (_⋙_) (pure (_,_ unit)) <*> -- (fmap (_⋙_) (fmap first (fmap const f)) <*> pure ×-apply) -- ≡ f -- staticArrowLaw1 = {!!} -- staticArrowLaw2 : {A B : Set} → {f : F (Unit → A → B)} → -- fmap const -- (fmap (_⋙_) (pure (_,_ unit)) <*> -- (fmap (_⋙_) (fmap first f) <*> pure ×-apply)) -- ≡ f -- staticArrowLaw2 = {!!} -- import StaticArrowProps -- open StaticArrowProps Arr pure (fmap2 _⋙_) (fmap first) (fmap const) force' -- arrowLaw1 arrowLaw3 arrowLaw4 arrowLaw5 arrowLaw6 arrowLaw7 arrowLaw8 arrowLaw9 staticArrowLaw1 staticArrowLaw2