-
Notifications
You must be signed in to change notification settings - Fork 4
Expand file tree
/
Copy pathgeneric_core_equal.ml
More file actions
210 lines (196 loc) · 8.55 KB
/
Copy pathgeneric_core_equal.ml
File metadata and controls
210 lines (196 loc) · 8.55 KB
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
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
open Generic_core
open Generic_util
open App.T
open Ty.T
let local_invalid_arg s = invalid_arg (__MODULE__ ^ "." ^ s)
(* type equality,
x : ('a,'b) equal is a witness that 'a and 'b are intensionally equal. *)
type (_,_) equal = Refl : ('a,'a) equal
type ('a,'b) t = ('a,'b) equal
type tag = Tag
type (_,_) app += App : {f : 'b . 'b Ty.t -> ('a, 'b) equal option} -> ('a, tag) app
let equal_closure = Extensible.create "Generic_core_equal.equal" (* private *)
let equal a b = match equal_closure.f a with
| App x -> x.f b
| _ -> assert false
type equal_fun =
{ f : 'a 'b . 'a Ty.t -> 'b Ty.t -> ('a, 'b) equal option }
let ext t f = equal_closure.ext t { f = fun a -> App {f = fun b -> f.f a b} }
let coerce : type a b . a ty -> b ty -> a -> b option
= fun a b x ->
match equal a b with
| Some Refl -> Some x
| None -> None
(* equal for core types *)
let () =
ext Int32 { f = fun (type a) (type b) (a : a ty) (b : b ty) ->
match a , b with
| Int32, Int32 -> Some (Refl : (a, b) equal)
| _ , _ -> None };
ext Int64 { f = fun (type a) (type b) (a : a ty) (b : b ty) ->
match a , b with
| Int64, Int64 -> Some (Refl : (a, b) equal)
| _ , _ -> None };
ext Nativeint { f = fun (type a) (type b) (a : a ty) (b : b ty) ->
match a , b with
| Nativeint, Nativeint -> Some (Refl : (a, b) equal)
| _ , _ -> None };
ext Exn { f = fun (type a) (type b) (a : a ty) (b : b ty) ->
match a , b with
| Exn, Exn -> Some (Refl : (a, b) equal)
| _ , _ -> None };
ext Bool { f = fun (type a) (type b) (a : a ty) (b : b ty) ->
match a , b with
| Bool, Bool -> Some (Refl : (a, b) equal)
| _ , _ -> None };
ext Int { f = fun (type a) (type b) (a : a ty) (b : b ty) ->
match a , b with
| Int, Int -> Some (Refl : (a, b) equal)
| _ , _ -> None };
ext Float { f = fun (type a) (type b) (a : a ty) (b : b ty) ->
match a , b with
| Float, Float -> Some (Refl : (a, b) equal)
| _ , _ -> None };
ext Char { f = fun (type a) (type b) (a : a ty) (b : b ty) ->
match a , b with
| Char, Char -> Some (Refl : (a, b) equal)
| _ , _ -> None };
ext Bytes { f = fun (type a) (type b) (a : a ty) (b : b ty) ->
match a , b with
| Bytes, Bytes -> Some (Refl : (a, b) equal)
| _ , _ -> None };
ext String { f = fun (type a) (type b) (a : a ty) (b : b ty) ->
match a , b with
| String, String -> Some (Refl : (a, b) equal)
| _ , _ -> None };
ext Unit { f = fun (type a) (type b) (a : a ty) (b : b ty) ->
match a , b with
| Unit, Unit -> Some (Refl : (a, b) equal)
| _ , _ -> None };
ext (Lazy Any) { f = fun (type a) (type b) (a : a ty) (b : b ty) ->
match a , b with
| Lazy x, Lazy y -> (match equal x y with
| Some Refl -> Some (Refl : (a, b) equal)
| None -> None)
| _ , _ -> None };
ext (Option Any) { f = fun (type a) (type b) (a : a ty) (b : b ty) ->
match a , b with
| Option x, Option y -> (match equal x y with
| Some Refl -> Some (Refl : (a, b) equal)
| None -> None)
| _ , _ -> None };
ext (List Any) { f = fun (type a) (type b) (a : a ty) (b : b ty) ->
match a , b with
| List x, List y -> (match equal x y with
| Some Refl -> Some (Refl : (a, b) equal)
| None -> None)
| _ , _ -> None };
ext (Array Any) { f = fun (type a) (type b) (a : a ty) (b : b ty) ->
match a , b with
| Array x, Array y -> (match equal x y with
| Some Refl -> Some (Refl : (a, b) equal)
| None -> None)
| _ , _ -> None };
ext (Ref Any) { f = fun (type a) (type b) (a : a ty) (b : b ty) ->
match a , b with
| Ref x, Ref y -> (match equal x y with
| Some Refl -> Some (Refl : (a, b) equal)
| None -> None)
| _ , _ -> None };
ext (Ty Any) { f = fun (type a) (type b) (a : a ty) (b : b ty) ->
match a , b with
| Ty x, Ty y -> (match equal x y with
| Some Refl -> Some (Refl : (a, b) equal)
| None -> None)
| _ , _ -> None };
ext Ty.pair { f = fun (type a) (type b) (a : a ty) (b : b ty) ->
match a , b with
| Pair (x,y), Pair (x',y') -> (match equal x x', equal y y' with
| Some Refl, Some Refl -> Some (Refl : (a, b) equal)
| _ , _ -> None)
| _ , _ -> None };
ext Ty.triple { f = fun (type a) (type b) (a : a ty) (b : b ty) ->
match a , b with
| Triple (x,y,z), Triple (x',y',z') ->
(match equal x x', equal y y', equal z z' with
| Some Refl, Some Refl, Some Refl -> Some (Refl : (a, b) equal)
| _, _, _ -> None)
| _ , _ -> None };
ext Ty.quadruple { f = fun (type a) (type b) (a : a ty) (b : b ty) ->
match a , b with
| Quadruple (a,b,c,d), Quadruple (a',b',c',d') ->
(match equal a a', equal b b', equal c c', equal d d' with
| Some Refl, Some Refl, Some Refl, Some Refl -> Some (Refl : (a, b) equal)
| _, _, _, _ -> None)
| _ , _ -> None };
ext Ty.quintuple { f = fun (type a) (type b) (a : a ty) (b : b ty) ->
match a , b with
| Quintuple (a,b,c,d,e), Quintuple (a',b',c',d',e') ->
(match equal a a', equal b b', equal c c', equal d d', equal e e' with
| Some Refl, Some Refl, Some Refl, Some Refl, Some Refl -> Some (Refl : (a, b) equal)
| _, _, _, _, _ -> None)
| _ , _ -> None };
ext Ty.sextuple { f = fun (type a) (type b) (a : a ty) (b : b ty) ->
match a , b with
| Sextuple (a,b,c,d,e,f), Sextuple (a',b',c',d',e',f') ->
(match equal a a', equal b b', equal c c', equal d d', equal e e', equal f f' with
| Some Refl, Some Refl, Some Refl, Some Refl, Some Refl, Some Refl -> Some (Refl : (a, b) equal)
| _, _, _, _, _, _ -> None)
| _ , _ -> None };
ext Ty.septuple { f = fun (type a) (type b) (a : a ty) (b : b ty) ->
match a , b with
| Septuple (a,b,c,d,e,f,g), Septuple (a',b',c',d',e',f',g') ->
(match equal a a', equal b b', equal c c', equal d d', equal e e', equal f f', equal g g' with
| Some Refl, Some Refl, Some Refl, Some Refl, Some Refl, Some Refl, Some Refl -> Some (Refl : (a, b) equal)
| _, _, _, _, _, _, _ -> None)
| _ , _ -> None };
ext Ty.octuple { f = fun (type a) (type b) (a : a ty) (b : b ty) ->
match a , b with
| Octuple (a,b,c,d,e,f,g,h), Octuple (a',b',c',d',e',f',g',h') ->
(match equal a a', equal b b', equal c c', equal d d', equal e e', equal f f', equal g g', equal h h' with
| Some Refl, Some Refl, Some Refl, Some Refl, Some Refl, Some Refl, Some Refl, Some Refl -> Some (Refl : (a, b) equal)
| _, _, _, _, _, _, _, _ -> None)
| _ , _ -> None };
ext Ty.nonuple { f = fun (type a) (type b) (a : a ty) (b : b ty) ->
match a , b with
| Nonuple (a,b,c,d,e,f,g,h,i), Nonuple (a',b',c',d',e',f',g',h',i') ->
(match equal a a', equal b b', equal c c', equal d d', equal e e', equal f f', equal g g', equal h h', equal i i' with
| Some Refl, Some Refl, Some Refl, Some Refl, Some Refl, Some Refl, Some Refl, Some Refl, Some Refl -> Some (Refl : (a, b) equal)
| _, _, _, _, _, _, _, _, _ -> None)
| _ , _ -> None };
ext Ty.decuple { f = fun (type a) (type b) (a : a ty) (b : b ty) ->
match a , b with
| Decuple (a,b,c,d,e,f,g,h,i,j), Decuple (a',b',c',d',e',f',g',h',i',j') ->
(match equal a a', equal b b', equal c c', equal d d', equal e e', equal f f', equal g g', equal h h', equal i i', equal j j' with
| Some Refl, Some Refl, Some Refl, Some Refl, Some Refl, Some Refl, Some Refl, Some Refl, Some Refl, Some Refl -> Some (Refl : (a, b) equal)
| _, _, _, _, _, _, _, _, _, _ -> None)
| _ , _ -> None };
ext (Fun (Any,Any)) { f = fun (type a) (type b) (a : a ty) (b : b ty) ->
match a , b with
| Fun (x,y), Fun (x',y') -> (match equal x x', equal y y' with
| Some Refl, Some Refl -> Some (Refl : (a, b) equal)
| _ , _ -> None)
| _ , _ -> None };
ext (Ty.Typed Any)
{
f = fun (type a) -> fun (type b) ->
fun (a : a ty) ->
fun (b : b ty) ->
match (a, b) with
| (Ty.Typed x1,Ty.Typed y1) ->
(match equal x1 y1 with
| Some (Refl ) ->
Some (Refl : (a,b) equal)
| _ -> None)
| (_,_) -> None
};
ext Ty.Dynamic
{
f = fun (type a) -> fun (type b) ->
fun (a : a ty) ->
fun (b : b ty) ->
match (a, b) with
| (Ty.Dynamic, Ty.Dynamic ) ->
Some (Refl : (a,b) equal)
| (_,_) -> None
};