|
| 1 | + |
| 2 | +import data.functor |
| 3 | + |
| 4 | +universe variables u v w u' v' w' |
| 5 | + |
| 6 | +section lemmas |
| 7 | + |
| 8 | +open function applicative |
| 9 | + |
| 10 | +variables {α β γ : Type u} |
| 11 | +variables {f : Type u → Type v} |
| 12 | +variables [applicative f] |
| 13 | +variables (g : β → γ) |
| 14 | + |
| 15 | +lemma applicative.map_seq_assoc |
| 16 | + (x : f (α → β)) (y : f α) |
| 17 | +: @has_map.map f _ _ _ g (x <*> y) = comp g <$> x <*> y := |
| 18 | +by rw [← applicative.pure_seq_eq_map |
| 19 | + ,seq_assoc |
| 20 | + ,map_pure |
| 21 | + ,applicative.pure_seq_eq_map] |
| 22 | + |
| 23 | +lemma applicative.seq_map_comm |
| 24 | + (x : f (γ → α)) (y : f β) |
| 25 | +: x <*> g <$> y = flip comp g <$> x <*> y := |
| 26 | +begin |
| 27 | + rw [← pure_seq_eq_map _ y,seq_assoc,seq_pure,← functor.map_comp], |
| 28 | + refl, |
| 29 | +end |
| 30 | + |
| 31 | +end lemmas |
| 32 | + |
| 33 | +namespace identity |
| 34 | + |
| 35 | +open function |
| 36 | + |
| 37 | +variables {α : Type u} {β : Type v} {γ : Type u'} |
| 38 | + |
| 39 | +def pure : α → identity α := identity.mk |
| 40 | + |
| 41 | +def seq : identity (α → β) → identity α → identity β |
| 42 | + | ⟨ f ⟩ ⟨ x ⟩ := ⟨ f x ⟩ |
| 43 | + |
| 44 | +local infix <$> := map |
| 45 | +local infix <*> := seq |
| 46 | + |
| 47 | +lemma pure_seq_eq_map (g : α → β) : ∀ (x : identity α), pure g <*> x = g <$> x |
| 48 | + | ⟨ x ⟩ := rfl |
| 49 | + |
| 50 | +lemma map_pure (g : α → β) (x : α) |
| 51 | +: g <$> pure x = pure (g x) := |
| 52 | +rfl |
| 53 | + |
| 54 | +lemma seq_pure : ∀ (g : identity (α → β)) (x : α), |
| 55 | + g <*> pure x = (λ g : α → β, g x) <$> g |
| 56 | + | ⟨ g ⟩ x := rfl |
| 57 | + |
| 58 | +lemma seq_assoc : ∀ (x : identity α) (g : identity (α → β)) (h : identity (β → γ)), |
| 59 | + h <*> (g <*> x) = (@comp α β γ <$> h) <*> g <*> x |
| 60 | +| ⟨ x ⟩ ⟨ g ⟩ ⟨ h ⟩ := rfl |
| 61 | + |
| 62 | +end identity |
| 63 | + |
| 64 | +instance applicative_identity : applicative identity := |
| 65 | +{ map := @identity.map |
| 66 | +, id_map := @identity.id_map |
| 67 | +, pure := @identity.pure |
| 68 | +, seq := @identity.seq |
| 69 | +, pure_seq_eq_map := @identity.pure_seq_eq_map |
| 70 | +, map_pure := @identity.map_pure |
| 71 | +, seq_pure := @identity.seq_pure |
| 72 | +, seq_assoc := @identity.seq_assoc } |
| 73 | + |
| 74 | +lemma identity.seq_mk {α β : Type v} (f : α → β) (x : α) |
| 75 | +: identity.mk f <*> identity.mk x = identity.mk (f x) := rfl |
| 76 | + |
| 77 | +namespace compose |
| 78 | + |
| 79 | +open function |
| 80 | + |
| 81 | +variables {f : Type u → Type u'} {g : Type v → Type u} |
| 82 | + |
| 83 | +variables [applicative f] [applicative g] |
| 84 | +variables {α β γ : Type v} |
| 85 | + |
| 86 | +def seq : compose f g (α → β) → compose f g α → compose f g β |
| 87 | + | ⟨ h ⟩ ⟨ x ⟩ := ⟨ has_seq.seq <$> h <*> x ⟩ |
| 88 | + |
| 89 | +def pure (x : α) : compose f g α := |
| 90 | +⟨ pure $ pure x ⟩ |
| 91 | + |
| 92 | +local infix ` <$> ` := map |
| 93 | +local infix ` <*> ` := seq |
| 94 | + |
| 95 | +lemma map_pure (h : α → β) (x : α) : (h <$> pure x : compose f g β) = pure (h x) := |
| 96 | +begin |
| 97 | + unfold compose.pure comp compose.map, |
| 98 | + apply congr_arg, |
| 99 | + rw [applicative.map_pure,applicative.map_pure], |
| 100 | +end |
| 101 | + |
| 102 | +lemma seq_pure (h : compose f g (α → β)) (x : α) |
| 103 | +: h <*> pure x = (λ g : α → β, g x) <$> h := |
| 104 | +begin |
| 105 | + cases h with h, |
| 106 | + unfold compose.map compose.pure compose.seq comp, |
| 107 | + apply congr_arg, |
| 108 | + rw [applicative.seq_pure,← functor.map_comp], |
| 109 | + apply congr_fun, apply congr_arg, |
| 110 | + apply funext, intro y, |
| 111 | + unfold comp, |
| 112 | + apply applicative.seq_pure |
| 113 | +end |
| 114 | + |
| 115 | +lemma seq_assoc : ∀ (x : compose f g α) (h₀ : compose f g (α → β)) (h₁ : compose f g (β → γ)), |
| 116 | + h₁ <*> (h₀ <*> x) = (@comp α β γ <$> h₁) <*> h₀ <*> x |
| 117 | +| ⟨ x ⟩ ⟨ h₀ ⟩ ⟨ h₁ ⟩ := |
| 118 | +begin |
| 119 | + unfold compose.seq compose.map, |
| 120 | + apply congr_arg, |
| 121 | + repeat { rw [applicative.seq_assoc] }, |
| 122 | + apply congr_fun, |
| 123 | + apply congr_arg, |
| 124 | + rw [← functor.map_comp], |
| 125 | + rw [← functor.map_comp], |
| 126 | + rw [← applicative.pure_seq_eq_map has_seq.seq |
| 127 | + ,applicative.seq_assoc |
| 128 | + ,applicative.seq_pure _ has_seq.seq], |
| 129 | + repeat { rw [← functor.map_comp] }, |
| 130 | + rw [applicative.map_seq_assoc has_seq.seq,← functor.map_comp], |
| 131 | + apply congr_fun, |
| 132 | + apply congr_arg, |
| 133 | + apply congr_fun, |
| 134 | + apply congr_arg, |
| 135 | + { apply funext, intro i, |
| 136 | + unfold comp, |
| 137 | + apply funext, intro j, |
| 138 | + apply funext, intro k, |
| 139 | + rw [applicative.seq_assoc] }, |
| 140 | +end |
| 141 | + |
| 142 | +lemma pure_seq_eq_map (h : α → β) : ∀ (x : compose f g α), pure h <*> x = h <$> x |
| 143 | + | ⟨ x ⟩ := |
| 144 | +begin |
| 145 | + unfold compose.pure compose.seq compose.map comp, |
| 146 | + apply congr_arg, |
| 147 | + rw [applicative.map_pure,applicative.pure_seq_eq_map], |
| 148 | + apply congr_fun, |
| 149 | + apply congr_arg, |
| 150 | + apply funext, clear x, intro x, |
| 151 | + apply applicative.pure_seq_eq_map |
| 152 | +end |
| 153 | + |
| 154 | +instance applicative_compose |
| 155 | + {f : Type u → Type u'} {g : Type v → Type u} |
| 156 | + [applicative f] [applicative g] |
| 157 | +: applicative (compose f g) := |
| 158 | +{ map := @compose.map f g _ _ |
| 159 | +, id_map := @compose.id_map f g _ _ |
| 160 | +, map_comp := @compose.map_comp f g _ _ |
| 161 | +, seq := @compose.seq f g _ _ |
| 162 | +, pure := @compose.pure f g _ _ |
| 163 | +, pure_seq_eq_map := @compose.pure_seq_eq_map f g _ _ |
| 164 | +, map_pure := @compose.map_pure f g _ _ |
| 165 | +, seq_pure := @compose.seq_pure f g _ _ |
| 166 | +, seq_assoc := @compose.seq_assoc f g _ _ } |
| 167 | + |
| 168 | +end compose |
| 169 | + |
| 170 | +lemma compose.seq_mk {α β : Type u'} |
| 171 | + {f : Type u → Type v} {g : Type u' → Type u} |
| 172 | + [applicative f] [applicative g] |
| 173 | + (h : f (g (α → β))) (x : f (g α)) |
| 174 | +: compose.mk h <*> compose.mk x = compose.mk (has_seq.seq <$> h <*> x) := rfl |
0 commit comments