Skip to content

Commit 2f4aa9e

Browse files
committed
[WIP] new traversable type class
1 parent e477400 commit 2f4aa9e

File tree

8 files changed

+872
-0
lines changed

8 files changed

+872
-0
lines changed

category/basic.lean

Lines changed: 48 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -15,6 +15,54 @@ variables {f : Type u → Type v} [applicative f]
1515
lemma pure_seq_eq_map : ∀ {α β : Type u} (g : α → β) (x : f α), pure g <*> x = g <$> x :=
1616
@applicative.pure_seq_eq_map f _
1717

18+
def mmap₂
19+
{α₁ α₂ φ : Type u}
20+
(g : α₁ → α₂ → f φ)
21+
: Π (ma₁ : list α₁) (ma₂: list α₂), f (list φ)
22+
| (x :: xs) (y :: ys) := (::) <$> g x y <*> mmap₂ xs ys
23+
| _ _ := pure []
24+
25+
def mmap₂' (g : α → β → f γ) : list α → list β → f punit
26+
| (x :: xs) (y :: ys) := g x y *> mmap₂' xs ys
27+
| [] _ := pure punit.star
28+
| _ [] := pure punit.star
29+
30+
private def mpartition_aux (x : α) : ulift bool → list α × list α → list α × list α
31+
| ⟨ tt ⟩ (xs,ys) := (x::xs,ys)
32+
| ⟨ ff ⟩ (xs,ys) := (xs,x::ys)
33+
34+
def list.mpartition' (g : α → f (ulift bool)) : list α → f (list α × list α)
35+
| [] := pure ([],[])
36+
| (x :: xs) := mpartition_aux x <$> g x <*> list.mpartition' xs
37+
38+
def list.mpartition {α : Type} {f : TypeType v} [applicative f] (g : α → f bool) :=
39+
list.mpartition' (λ x, ulift.up <$> g x)
40+
41+
variables {m : Type u → Type v} [applicative m]
42+
def lift₂
43+
{α₁ α₂ φ : Type u}
44+
(f : α₁ → α₂ → φ)
45+
(ma₁ : m α₁) (ma₂: m α₂) : m φ :=
46+
f <$> ma₁ <*> ma₂
47+
48+
def lift₃
49+
{α₁ α₂ α₃ φ : Type u}
50+
(f : α₁ → α₂ → α₃ → φ)
51+
(ma₁ : m α₁) (ma₂: m α₂) (ma₃ : m α₃) : m φ :=
52+
f <$> ma₁ <*> ma₂ <*> ma₃
53+
54+
def lift₄
55+
{α₁ α₂ α₃ α₄ φ : Type u}
56+
(f : α₁ → α₂ → α₃ → α₄ → φ)
57+
(ma₁ : m α₁) (ma₂: m α₂) (ma₃ : m α₃) (ma₄ : m α₄) : m φ :=
58+
f <$> ma₁ <*> ma₂ <*> ma₃ <*> ma₄
59+
60+
def lift₅
61+
{α₁ α₂ α₃ α₄ α₅ φ : Type u}
62+
(f : α₁ → α₂ → α₃ → α₄ → α₅ → φ)
63+
(ma₁ : m α₁) (ma₂: m α₂) (ma₃ : m α₃) (ma₄ : m α₄) (ma₅ : m α₅) : m φ :=
64+
f <$> ma₁ <*> ma₂ <*> ma₃ <*> ma₄ <*> ma₅
65+
1866
end applicative
1967

2068
section monad

control/applicative.lean

Lines changed: 174 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,174 @@
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

data/functor.lean

Lines changed: 94 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,94 @@
1+
2+
universe variables u v w u' v' w'
3+
4+
section functor
5+
6+
variables {F : Type u → Type v}
7+
variables {α β γ : Type u}
8+
variables [functor F]
9+
10+
lemma functor.id_map' : has_map.map id = (id : F α → F α) :=
11+
by { apply funext, apply functor.id_map }
12+
13+
lemma functor.map_comp' (f : α → β) (g : β → γ)
14+
: has_map.map (g ∘ f) = (has_map.map g ∘ has_map.map f : F α → F γ) :=
15+
by { apply funext, intro, apply functor.map_comp }
16+
17+
end functor
18+
19+
structure identity (α : Type u) : Type u :=
20+
(run_identity : α)
21+
22+
structure compose (f : Type u → Type u') (g : Type v → Type u) (α : Type v) : Type u' :=
23+
(run : f $ g α)
24+
25+
namespace identity
26+
27+
open function
28+
29+
variables {α : Type u} {β : Type v} {γ : Type u'}
30+
31+
def map (f : α → β) : identity α → identity β
32+
| ⟨ x ⟩ := ⟨ f x ⟩
33+
34+
local infixr <$> := map
35+
36+
lemma id_map : ∀ (x : identity α), map id x = x
37+
| ⟨ x ⟩ := rfl
38+
39+
lemma map_comp (f : α → β) (g : β → γ)
40+
: ∀ (x : identity α), map (g ∘ f) x = g <$> f <$> x
41+
| ⟨ x ⟩ := rfl
42+
43+
end identity
44+
45+
instance identity_functor : functor identity :=
46+
{ map := @identity.map
47+
, id_map := @identity.id_map
48+
, map_comp := @identity.map_comp }
49+
50+
lemma identity.map_mk {α β : Type v} (f : α → β) (x : α)
51+
: f <$> identity.mk x = identity.mk (f x) := rfl
52+
53+
namespace compose
54+
55+
variables {f : Type u → Type u'} {g : Type v → Type u}
56+
57+
variables [functor f] [functor g]
58+
variables {α β γ : Type v}
59+
60+
def map (h : α → β) : compose f g α → compose f g β
61+
| ⟨ x ⟩ := ⟨ has_map.map h <$> x ⟩
62+
63+
local infix ` <$> ` := map
64+
65+
lemma id_map : ∀ (x : compose f g α), map id x = x
66+
| ⟨ x ⟩ :=
67+
by { unfold map, rw [functor.id_map',functor.id_map], }
68+
69+
lemma map_comp (g_1 : α → β) (h : β → γ) : ∀ (x : compose f g α),
70+
map (h ∘ g_1) x = map h (map g_1 x)
71+
| ⟨ x ⟩ :=
72+
by { unfold map, rw [functor.map_comp' g_1 h,functor.map_comp], }
73+
74+
end compose
75+
76+
instance functor_compose {f : Type u → Type u'} {g : Type v → Type u}
77+
[functor f] [functor g]
78+
: functor (compose f g) :=
79+
{ map := @compose.map f g _ _
80+
, id_map := @compose.id_map f g _ _
81+
, map_comp := @compose.map_comp f g _ _ }
82+
83+
lemma compose.map_mk {α β : Type u'}
84+
{f : Type u → Type v} {g : Type u' → Type u}
85+
[functor f] [functor g]
86+
(h : α → β) (x : f (g α))
87+
: h <$> compose.mk x = compose.mk (has_map.map h <$> x) := rfl
88+
89+
namespace ulift
90+
91+
instance : has_map ulift :=
92+
{ map := λ α β f, up ∘ f ∘ down }
93+
94+
end ulift

0 commit comments

Comments
 (0)