-
Notifications
You must be signed in to change notification settings - Fork 0
/
Copy pathFunctor.fm
96 lines (84 loc) · 2.59 KB
/
Functor.fm
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
// Functor.fm defines a lawful Functor type and
// the corresponding unlawful Mappable type
import Dependencies
import Relation
// ========================================================
// = Definition =
// ========================================================
T Mappable<F: Type -> Type>
| mappable ( map : (A; B;) -> (A -> B) -> F(A) -> F(B) )
map(F : Type -> Type, m : Mappable(F)) : (A; B;) -> (A -> B) -> F(A) -> F(B)
(A; B; f) =>
case m | mappable => m.map(A; B; f)
T Functor<F : Type -> Type, s : (X : Type) -> Setoid(F(X))>
| functor
( map : (A; B;) -> (A -> B) -> F(A) -> F(B)
identity : (A; fa : F(A)) -> Eq(F(A), s(A), map(A; A; id(A;), fa), fa),
compose : (A; B; C; g : B -> C, f : A -> B, fa : F(A)) ->
Eq(F(C), s(C),
map(A; C; (x) => g(f(x)), fa),
map(B; C; g, map(A; B; f, fa))
)
)
functor.map(
F : Type -> Type,
s : (X : Type) -> Setoid(F(X)),
f : Functor(F,s)
) : (A; B;) -> (A -> B) -> F(A) -> F(B)
case f
| functor => f.map
functor.identity(
F : Type -> Type,
s : (X : Type) -> Setoid(F(X)),
f : Functor(F,s)
) : (A; fa : F(A)) -> Eq(F(A),s(A),functor.map(F,s,f,A;A;id(A;),fa),fa)
case f
| functor => f.identity
: (A; fa : F(A)) -> Eq(F(A),s(A),functor.map(F,s,f,A;A;id(A;), fa), fa)
functor.compose(
F : Type -> Type,
s : (X : Type) -> Setoid(F(X)),
f : Functor(F,s)
)
: let map = functor.map(F,s,f)
(A; B; C; g : B -> C, f : A -> B, fa : F(A)) ->
Eq(F(C), s(C),
map(A; C; (x) => g(f(x)), fa),
map(B; C; g, map(A; B; f, fa))
)
case f
| functor => f.compose
: let map = functor.map(F,s,f)
(A; B; C; g : B -> C, f : A -> B, fa : F(A)) ->
Eq(F(C), s(C),
map(A; C; (x) => g(f(x)), fa),
map(B; C; g, map(A; B; f, fa))
)
// ========================================================
// = Conversion =
// ========================================================
//
functor_to_mappable(
F : Type -> Type,
s : (X : Type) -> Setoid(F(X)),
f : Functor(F,s),
)
: Mappable(F)
case f
| functor => mappable(F; f.map)
: Mappable(F)
mappable_to_functor(
F : Type -> Type,
m : Mappable(F),
s : (X : Type) -> Setoid(F(X)),
identity : let map = map(F, m)
(A; fa : F(A)) -> Eq(F(A), s(A), map(A; A; id(A;), fa), fa),
compose : let map = map(F, m)
(A; B; C; g : B -> C, f : A -> B, fa : F(A)) ->
Eq(F(C), s(C),
map(A; C; (x) => g(f(x)), fa),
map(B; C; g, map(A; B; f, fa))
)
)
: Functor(F,s)
functor(F;s;map(F,m), identity, compose)