Skip to content

Commit a7c6856

Browse files
Prove IsLawfulApplicative from monad laws
1 parent 65cd147 commit a7c6856

File tree

1 file changed

+129
-0
lines changed

1 file changed

+129
-0
lines changed
Lines changed: 129 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,129 @@
1+
module Haskell.Law.Applicative.FromMonad where
2+
3+
open import Haskell.Prim
4+
5+
open import Haskell.Prim.Applicative
6+
open import Haskell.Prim.Functor
7+
open import Haskell.Prim.Monad
8+
9+
open import Haskell.Law.Applicative.Def
10+
open import Haskell.Law.Monad.Def as Monad
11+
open import Haskell.Law.Equality
12+
open import Haskell.Law.Functor
13+
open import Haskell.Law.Functor.FromMonad
14+
15+
-------------------------------------------------------------------------------
16+
-- Prove the Applicative laws from the Monad laws
17+
18+
--
19+
prop-MonadLaws→IsLawfulApplicative
20+
: ∀ ⦃ _ : Monad m ⦄ ⦃ _ : MonadLaws m ⦄ ⦃ _ : IsDefaultMonad m ⦄
21+
IsLawfulApplicative m
22+
--
23+
prop-MonadLaws→IsLawfulApplicative {m} = record
24+
{ super = prop-MonadLaws→IsLawfulFunctor
25+
; identity = midentity
26+
; composition = mcomposition
27+
; homomorphism = mhomomorphism
28+
; interchange = minterchange
29+
; functor = mfunctor
30+
}
31+
where
32+
midentity : {a} (ma : m a) (pure id <*> ma) ≡ ma
33+
midentity {a} ma
34+
rewrite def-pure-return (id {a})
35+
| def-<*>->>= (return id) ma
36+
= begin
37+
return id >>= (λ f ma >>= (λ x return (f x)))
38+
≡⟨ Monad.leftIdentity _ _ ⟩
39+
ma >>= (λ x return (id x))
40+
≡⟨ Monad.rightIdentity _ ⟩
41+
ma
42+
43+
44+
mfunctor : {a b} (f : a b) (u : m a) fmap f u ≡ (pure f <*> u)
45+
mfunctor f u = begin
46+
fmap f u
47+
≡⟨ Monad.def-fmap->>= _ _ ⟩
48+
(do x u; return (f x))
49+
≡⟨ sym (Monad.leftIdentity _ _) ⟩
50+
(do f' return f; x u; return (f' x))
51+
≡⟨ cong (λ o o >>= _) (sym (def-pure-return _)) ⟩
52+
(do f' pure f; x u; return (f' x))
53+
≡⟨ sym (def-<*>->>= _ _) ⟩
54+
pure f <*> u
55+
56+
57+
mcomposition
58+
: {a b c} (u : m (b c)) (v : m (a b)) (w : m a)
59+
(pure _∘_ <*> u <*> v <*> w) ≡ (u <*> (v <*> w))
60+
mcomposition u v w
61+
= begin
62+
pure _∘_ <*> u <*> v <*> w
63+
≡⟨ cong (λ o o <*> u <*> v <*> w) (def-pure-return _∘_) ⟩
64+
return _∘_ <*> u <*> v <*> w
65+
≡⟨ cong (λ o o <*> v <*> w) (def-<*>->>= _ _ ) ⟩
66+
(do comp return _∘_; g u; return (comp g)) <*> v <*> w
67+
≡⟨ cong (λ o o <*> v <*> w) (Monad.leftIdentity _ _) ⟩
68+
(do g u; return (_∘_ g)) <*> v <*> w
69+
≡⟨ cong (λ o o <*> w) (def-<*>->>= _ _ ) ⟩
70+
(do g' (do g u; return (_∘_ g)); f v; return (g' f)) <*> w
71+
≡⟨ cong (λ o o <*> w) (sym (Monad.associativity u _ _)) ⟩
72+
(do g u; g' return (_∘_ g); f v; return (g' f)) <*> w
73+
≡⟨ cong (λ o o <*> w) (cong-monad u (λ g Monad.leftIdentity _ _)) ⟩
74+
(do g u; f v; return (g ∘ f)) <*> w
75+
≡⟨ def-<*>->>= _ _ ⟩
76+
(do gf (do g u; f v; return (g ∘ f)); x w; return (gf x))
77+
≡⟨ sym (Monad.associativity u _ _) ⟩
78+
(do g u; gf (do f v; return (g ∘ f)); x w; return (gf x))
79+
≡⟨ cong-monad u (λ g sym (Monad.associativity v _ _)) ⟩
80+
(do g u; do f v; gf return (g ∘ f); x w; return (gf x))
81+
≡⟨ cong-monad u (λ g cong-monad v (λ f Monad.leftIdentity _ _)) ⟩
82+
(do g u; f v; x w; return (g (f x)))
83+
≡⟨ cong-monad u (λ g cong-monad v λ f cong-monad w (λ x sym (Monad.leftIdentity _ _))) ⟩
84+
(do g u; f v; x w; y return (f x); return (g y))
85+
≡⟨ cong-monad u (λ g cong-monad v λ x Monad.associativity _ _ _) ⟩
86+
(do g u; f v; y (do x w; return (f x)); return (g y))
87+
≡⟨ cong-monad u (λ g Monad.associativity _ _ _) ⟩
88+
(do g u; y (do f v; x w; return (f x)); return (g y))
89+
≡⟨ sym (def-<*>->>= _ _) ⟩
90+
u <*> (do f v; x w; return (f x))
91+
≡⟨ cong (λ o u <*> o) (sym (def-<*>->>= _ _)) ⟩
92+
u <*> (v <*> w)
93+
94+
95+
mhomomorphism
96+
: {a b} (f : a b) (x : a)
97+
(pure {m} f <*> pure x) ≡ pure (f x)
98+
mhomomorphism f x = begin
99+
pure {m} f <*> pure x
100+
≡⟨ cong₂ (_<*>_) (def-pure-return f) (def-pure-return x) ⟩
101+
return {m} f <*> return x
102+
≡⟨ def-<*>->>= _ _ ⟩
103+
(do f' return f; x' return x; return (f' x'))
104+
≡⟨ Monad.leftIdentity _ _ ⟩
105+
(do x' return x; return (f x'))
106+
≡⟨ Monad.leftIdentity _ _ ⟩
107+
return (f x)
108+
≡⟨ sym (def-pure-return _) ⟩
109+
pure (f x)
110+
111+
112+
minterchange
113+
: {a b} (u : m (a b)) (y : a)
114+
(u <*> pure y) ≡ (pure (_$ y) <*> u)
115+
minterchange u y = begin
116+
u <*> pure y
117+
≡⟨ cong (u <*>_) (def-pure-return _) ⟩
118+
u <*> return y
119+
≡⟨ def-<*>->>= _ _ ⟩
120+
(do f u; y' return y; return (f y'))
121+
≡⟨ cong-monad u (λ f Monad.leftIdentity y _) ⟩
122+
(do f u; return (f y))
123+
≡⟨ sym (Monad.leftIdentity _ _) ⟩
124+
(do y'' return (_$ y); f u; return (y'' f))
125+
≡⟨ sym (def-<*>->>= _ _) ⟩
126+
return (_$ y) <*> u
127+
≡⟨ sym (cong (_<*> u) (def-pure-return _)) ⟩
128+
pure (_$ y) <*> u
129+

0 commit comments

Comments
 (0)