~ubuntu-branches/ubuntu/vivid/typerep/vivid

« back to all changes in this revision

Viewing changes to lib/std_internal.ml

  • Committer: Package Import Robot
  • Author(s): Hilko Bengen
  • Date: 2014-09-24 23:51:02 UTC
  • Revision ID: package-import@ubuntu.com-20140924235102-0qeq851f02otnnxp
Tags: upstream-111.17.00
ImportĀ upstreamĀ versionĀ 111.17.00

Show diffs side-by-side

added added

removed removed

Lines of Context:
 
1
module Name_of = struct
 
2
  let typename_of_int =
 
3
    let module M = Typename.Make0(struct type t = int let name = "int" end) in
 
4
    M.typename_of_t
 
5
 
 
6
  let typename_of_int32 =
 
7
    let module M = Typename.Make0(struct type t = int32 let name = "int32" end) in
 
8
    M.typename_of_t
 
9
 
 
10
  let typename_of_int64 =
 
11
    let module M = Typename.Make0(struct type t = int64 let name = "int64" end) in
 
12
    M.typename_of_t
 
13
 
 
14
  let typename_of_nativeint =
 
15
    let module M = Typename.Make0(struct
 
16
      type t = nativeint
 
17
      let name = "nativeint"
 
18
    end) in
 
19
    M.typename_of_t
 
20
 
 
21
  let typename_of_char =
 
22
    let module M = Typename.Make0(struct type t = char let name = "char" end) in
 
23
    M.typename_of_t
 
24
 
 
25
  let typename_of_float =
 
26
    let module M = Typename.Make0(struct type t = float let name = "float" end) in
 
27
    M.typename_of_t
 
28
 
 
29
  let typename_of_string =
 
30
    let module M = Typename.Make0(struct type t = string let name = "string" end) in
 
31
    M.typename_of_t
 
32
 
 
33
  let typename_of_bool =
 
34
    let module M = Typename.Make0(struct type t = bool let name = "bool" end) in
 
35
    M.typename_of_t
 
36
 
 
37
  let typename_of_unit =
 
38
    let module M = Typename.Make0(struct type t = unit let name = "unit" end) in
 
39
    M.typename_of_t
 
40
 
 
41
  module M_option = Typename.Make1(struct type 'a t = 'a option let name = "option" end)
 
42
  let typename_of_option = M_option.typename_of_t
 
43
 
 
44
  module M_list = Typename.Make1(struct type 'a t = 'a list let name = "list" end)
 
45
  let typename_of_list = M_list.typename_of_t
 
46
 
 
47
  module M_array = Typename.Make1(struct type 'a t = 'a array let name = "array" end)
 
48
  let typename_of_array = M_array.typename_of_t
 
49
 
 
50
  module M_lazy_t = Typename.Make1(struct type 'a t = 'a lazy_t let name = "lazy_t" end)
 
51
  let typename_of_lazy_t = M_lazy_t.typename_of_t
 
52
 
 
53
  module M_ref = Typename.Make1(struct type 'a t = 'a ref let name = "ref" end)
 
54
  let typename_of_ref = M_ref.typename_of_t
 
55
 
 
56
  module M_function = Typename.Make2(struct
 
57
    type ('a, 'b) t = 'a -> 'b
 
58
    let name = "function"
 
59
  end)
 
60
  let typename_of_function = M_function.typename_of_t
 
61
 
 
62
  type tuple0 = unit
 
63
  module M_tuple0 = Typename.Make0(struct type t = tuple0 let name = "tuple0" end)
 
64
  let typename_of_tuple0 = M_tuple0.typename_of_t
 
65
 
 
66
  module M_tuple2 = Typename.Make2(struct
 
67
    type ('a, 'b) t = 'a * 'b
 
68
    let name = "tuple2"
 
69
  end)
 
70
  let typename_of_tuple2 = M_tuple2.typename_of_t
 
71
 
 
72
  module M_tuple3 = Typename.Make3(struct
 
73
    type ('a, 'b, 'c) t = 'a * 'b * 'c
 
74
    let name = "tuple3"
 
75
  end)
 
76
  let typename_of_tuple3 = M_tuple3.typename_of_t
 
77
 
 
78
  module M_tuple4 = Typename.Make4(struct
 
79
    type ('a, 'b, 'c, 'd) t = 'a * 'b * 'c * 'd
 
80
    let name = "tuple4"
 
81
  end)
 
82
  let typename_of_tuple4 = M_tuple4.typename_of_t
 
83
 
 
84
  module M_tuple5 = Typename.Make5(struct
 
85
    type ('a, 'b, 'c, 'd, 'e) t = 'a * 'b * 'c *'d * 'e
 
86
    let name = "tuple5"
 
87
  end)
 
88
  let typename_of_tuple5 = M_tuple5.typename_of_t
 
89
end
 
90
 
 
91
module rec Typerep : sig
 
92
 
 
93
  type _ t =
 
94
    | Int        : int t
 
95
    | Int32      : int32 t
 
96
    | Int64      : int64 t
 
97
    | Nativeint  : nativeint t
 
98
    | Char       : char t
 
99
    | Float      : float t
 
100
    | String     : string t
 
101
    | Bool       : bool t
 
102
    | Unit       : unit t
 
103
    | Option     : 'a t -> 'a option t
 
104
    | List       : 'a t -> 'a list t
 
105
    | Array      : 'a t -> 'a array t
 
106
    | Lazy       : 'a t -> 'a Lazy.t t
 
107
    | Ref        : 'a t -> 'a ref t
 
108
    | Function   : ('dom t * 'rng t) -> ('dom -> 'rng) t
 
109
    | Tuple      : 'a Typerep.Tuple.t -> 'a t
 
110
    | Record     : 'a Typerep.Record.t -> 'a t
 
111
    | Variant    : 'a Typerep.Variant.t -> 'a t
 
112
    | Named      : ('a Typerep.Named.t * 'a t Lazy.t option) -> 'a t
 
113
 
 
114
  type packed = T : 'a t -> packed
 
115
 
 
116
  module Named : sig
 
117
    module type T0 = sig
 
118
      type named
 
119
      type t
 
120
      val typename_of_named : named Typename.t
 
121
      val typename_of_t : t Typename.t
 
122
      val witness : (t, named) Type_equal.t
 
123
    end
 
124
    module type T1 = sig
 
125
      type 'a named
 
126
      type a val a : a Typerep.t
 
127
      type t
 
128
      val typename_of_named : 'a Typename.t -> 'a named Typename.t
 
129
      val typename_of_t : t Typename.t
 
130
      val witness : (t, a named) Type_equal.t
 
131
    end
 
132
    module type T2 = sig
 
133
      type ('a, 'b) named
 
134
      type a val a : a Typerep.t
 
135
      type b val b : b Typerep.t
 
136
      type t
 
137
      val typename_of_named :
 
138
        'a Typename.t
 
139
        -> 'b Typename.t
 
140
        -> ('a, 'b) named Typename.t
 
141
      val typename_of_t : t Typename.t
 
142
      val witness : (t, (a, b) named) Type_equal.t
 
143
    end
 
144
    module type T3 = sig
 
145
      type ('a, 'b, 'c) named
 
146
      type a val a : a Typerep.t
 
147
      type b val b : b Typerep.t
 
148
      type c val c : c Typerep.t
 
149
      type t
 
150
      val typename_of_named :
 
151
        'a Typename.t
 
152
        -> 'b Typename.t
 
153
        -> 'c Typename.t
 
154
        -> ('a, 'b, 'c) named Typename.t
 
155
      val typename_of_t : t Typename.t
 
156
      val witness : (t, (a, b, c) named) Type_equal.t
 
157
    end
 
158
    module type T4 = sig
 
159
      type ('a, 'b, 'c, 'd) named
 
160
      type a val a : a Typerep.t
 
161
      type b val b : b Typerep.t
 
162
      type c val c : c Typerep.t
 
163
      type d val d : d Typerep.t
 
164
      type t
 
165
      val typename_of_named :
 
166
        'a Typename.t
 
167
        -> 'b Typename.t
 
168
        -> 'c Typename.t
 
169
        -> 'd Typename.t
 
170
        -> ('a, 'b, 'c, 'd) named Typename.t
 
171
      val typename_of_t : t Typename.t
 
172
      val witness : (t, (a, b, c, d) named) Type_equal.t
 
173
    end
 
174
    module type T5 = sig
 
175
      type ('a, 'b, 'c, 'd, 'e) named
 
176
      type a val a : a Typerep.t
 
177
      type b val b : b Typerep.t
 
178
      type c val c : c Typerep.t
 
179
      type d val d : d Typerep.t
 
180
      type e val e : e Typerep.t
 
181
      type t
 
182
      val typename_of_named :
 
183
        'a Typename.t
 
184
        -> 'b Typename.t
 
185
        -> 'c Typename.t
 
186
        -> 'd Typename.t
 
187
        -> 'e Typename.t
 
188
        -> ('a, 'b, 'c, 'd, 'e) named Typename.t
 
189
      val typename_of_t : t Typename.t
 
190
      val witness : (t, (a, b, c, d, e) named) Type_equal.t
 
191
    end
 
192
    (* there the module is necessary because we need to deal with a type [t] with
 
193
       parameters whose kind is not representable as a type variable: ['a 't], even with
 
194
       a gadt. *)
 
195
    type 'a t =
 
196
    | T0 of (module T0 with type t = 'a)
 
197
    | T1 of (module T1 with type t = 'a)
 
198
    | T2 of (module T2 with type t = 'a)
 
199
    | T3 of (module T3 with type t = 'a)
 
200
    | T4 of (module T4 with type t = 'a)
 
201
    | T5 of (module T5 with type t = 'a)
 
202
 
 
203
    val arity : _ t -> int
 
204
    val typename_of_t : 'a t -> 'a Typename.t
 
205
    val name : _ t -> string
 
206
  end
 
207
 
 
208
  module Tuple : sig
 
209
    (* these constructors could be plunged at toplevel of Typerep.t, however it is less
 
210
       verbose that way *)
 
211
    type _ t =
 
212
    | T2 : ('a Typerep.t * 'b Typerep.t)
 
213
      -> ('a * 'b) t
 
214
    | T3 : ('a Typerep.t * 'b Typerep.t * 'c Typerep.t)
 
215
      -> ('a * 'b * 'c) t
 
216
    | T4 : ('a Typerep.t * 'b Typerep.t * 'c Typerep.t * 'd Typerep.t)
 
217
      -> ('a * 'b * 'c * 'd) t
 
218
    | T5 : ('a Typerep.t * 'b Typerep.t * 'c Typerep.t * 'd Typerep.t * 'e Typerep.t)
 
219
      -> ('a * 'b * 'c * 'd * 'e) t
 
220
 
 
221
    val arity : _ t -> int
 
222
    val typename_of_t : 'a t -> 'a Typename.t
 
223
  end
 
224
 
 
225
  include Variant_and_record_intf.S with type 'a t := 'a Typerep.t
 
226
 
 
227
  val same : _ t -> _ t -> bool
 
228
  val same_witness : 'a t -> 'b t -> ('a, 'b) Type_equal.t option
 
229
  val same_witness_exn : 'a t -> 'b t -> ('a, 'b) Type_equal.t
 
230
  val typename_of_t : 'a t -> 'a Typename.t
 
231
  val head : 'a t -> 'a t
 
232
end = struct
 
233
 
 
234
  type _ t =
 
235
    | Int : int t
 
236
    | Int32 : int32 t
 
237
    | Int64 : int64 t
 
238
    | Nativeint : nativeint t
 
239
    | Char : char t
 
240
    | Float : float t
 
241
    | String : string t
 
242
    | Bool : bool t
 
243
    | Unit : unit t
 
244
    | Option : 'a t -> 'a option t
 
245
    | List : 'a t -> 'a list t
 
246
    | Array : 'a t -> 'a array t
 
247
    | Lazy : 'a t -> 'a Lazy.t t
 
248
    | Ref : 'a t -> 'a ref t
 
249
    | Function : ('dom t * 'rng t) -> ('dom -> 'rng) t
 
250
    | Tuple : 'a Typerep.Tuple.t -> 'a t
 
251
    | Record : 'a Typerep.Record.t -> 'a t
 
252
    | Variant : 'a Typerep.Variant.t -> 'a t
 
253
    | Named : ('a Typerep.Named.t * 'a t Lazy.t option) -> 'a t
 
254
 
 
255
  type packed = T : 'a t -> packed
 
256
 
 
257
  module Named = struct
 
258
    module type T0 = sig
 
259
      type named
 
260
      type t
 
261
      val typename_of_named : named Typename.t
 
262
      val typename_of_t : t Typename.t
 
263
      val witness : (t, named) Type_equal.t
 
264
    end
 
265
    module type T1 = sig
 
266
      type 'a named
 
267
      type a val a : a Typerep.t
 
268
      type t
 
269
      val typename_of_named : 'a Typename.t -> 'a named Typename.t
 
270
      val typename_of_t : t Typename.t
 
271
      val witness : (t, a named) Type_equal.t
 
272
    end
 
273
    module type T2 = sig
 
274
      type ('a, 'b) named
 
275
      type a val a : a Typerep.t
 
276
      type b val b : b Typerep.t
 
277
      type t
 
278
      val typename_of_named :
 
279
        'a Typename.t
 
280
        -> 'b Typename.t
 
281
        -> ('a, 'b) named Typename.t
 
282
      val typename_of_t : t Typename.t
 
283
      val witness : (t, (a, b) named) Type_equal.t
 
284
    end
 
285
    module type T3 = sig
 
286
      type ('a, 'b, 'c) named
 
287
      type a val a : a Typerep.t
 
288
      type b val b : b Typerep.t
 
289
      type c val c : c Typerep.t
 
290
      type t
 
291
      val typename_of_named :
 
292
        'a Typename.t
 
293
        -> 'b Typename.t
 
294
        -> 'c Typename.t
 
295
        -> ('a, 'b, 'c) named Typename.t
 
296
      val typename_of_t : t Typename.t
 
297
      val witness : (t, (a, b, c) named) Type_equal.t
 
298
    end
 
299
    module type T4 = sig
 
300
      type ('a, 'b, 'c, 'd) named
 
301
      type a val a : a Typerep.t
 
302
      type b val b : b Typerep.t
 
303
      type c val c : c Typerep.t
 
304
      type d val d : d Typerep.t
 
305
      type t
 
306
      val typename_of_named :
 
307
        'a Typename.t
 
308
        -> 'b Typename.t
 
309
        -> 'c Typename.t
 
310
        -> 'd Typename.t
 
311
        -> ('a, 'b, 'c, 'd) named Typename.t
 
312
      val typename_of_t : t Typename.t
 
313
      val witness : (t, (a, b, c, d) named) Type_equal.t
 
314
    end
 
315
    module type T5 = sig
 
316
      type ('a, 'b, 'c, 'd, 'e) named
 
317
      type a val a : a Typerep.t
 
318
      type b val b : b Typerep.t
 
319
      type c val c : c Typerep.t
 
320
      type d val d : d Typerep.t
 
321
      type e val e : e Typerep.t
 
322
      type t
 
323
      val typename_of_named :
 
324
        'a Typename.t
 
325
        -> 'b Typename.t
 
326
        -> 'c Typename.t
 
327
        -> 'd Typename.t
 
328
        -> 'e Typename.t
 
329
        -> ('a, 'b, 'c, 'd, 'e) named Typename.t
 
330
      val typename_of_t : t Typename.t
 
331
      val witness : (t, (a, b, c, d, e) named) Type_equal.t
 
332
    end
 
333
    (* there the module is necessary because we need to deal with a type [t] with
 
334
       parameters whose kind is not representable as a type variable: ['a 't], even with
 
335
       a gadt. *)
 
336
    type 'a t =
 
337
    | T0 of (module T0 with type t = 'a)
 
338
    | T1 of (module T1 with type t = 'a)
 
339
    | T2 of (module T2 with type t = 'a)
 
340
    | T3 of (module T3 with type t = 'a)
 
341
    | T4 of (module T4 with type t = 'a)
 
342
    | T5 of (module T5 with type t = 'a)
 
343
 
 
344
    let arity = function
 
345
      | T0 _ -> 0
 
346
      | T1 _ -> 1
 
347
      | T2 _ -> 2
 
348
      | T3 _ -> 3
 
349
      | T4 _ -> 4
 
350
      | T5 _ -> 5
 
351
 
 
352
    let typename_of_t (type a) = function
 
353
      | T0 rep ->
 
354
        let module T = (val rep : T0 with type t = a) in
 
355
        T.typename_of_t
 
356
      | T1 rep ->
 
357
        let module T = (val rep : T1 with type t = a) in
 
358
        T.typename_of_t
 
359
      | T2 rep ->
 
360
        let module T = (val rep : T2 with type t = a) in
 
361
        T.typename_of_t
 
362
      | T3 rep ->
 
363
        let module T = (val rep : T3 with type t = a) in
 
364
        T.typename_of_t
 
365
      | T4 rep ->
 
366
        let module T = (val rep : T4 with type t = a) in
 
367
        T.typename_of_t
 
368
      | T5 rep ->
 
369
        let module T = (val rep : T5 with type t = a) in
 
370
        T.typename_of_t
 
371
 
 
372
    let name rep =
 
373
      Typename.Uid.name (Typename.uid (typename_of_t rep))
 
374
  end
 
375
 
 
376
  module Tuple = struct
 
377
    (* these constructors could be plunged at toplevel of Typerep.t, however it is less
 
378
       verbose this way *)
 
379
    type _ t =
 
380
    | T2 : ('a Typerep.t * 'b Typerep.t)
 
381
      -> ('a * 'b) t
 
382
    | T3 : ('a Typerep.t * 'b Typerep.t * 'c Typerep.t)
 
383
      -> ('a * 'b * 'c) t
 
384
    | T4 : ('a Typerep.t * 'b Typerep.t * 'c Typerep.t * 'd Typerep.t)
 
385
      -> ('a * 'b * 'c * 'd) t
 
386
    | T5 : ('a Typerep.t * 'b Typerep.t * 'c Typerep.t * 'd Typerep.t * 'e Typerep.t)
 
387
      -> ('a * 'b * 'c * 'd * 'e) t
 
388
 
 
389
    let arity : type a. a t -> int = function
 
390
      | Typerep.Tuple.T2 _ -> 2
 
391
      | Typerep.Tuple.T3 _ -> 3
 
392
      | Typerep.Tuple.T4 _ -> 4
 
393
      | Typerep.Tuple.T5 _ -> 5
 
394
 
 
395
    let typename_of_t : type a. a t -> a Typename.t = function
 
396
      | T2 (a, b) ->
 
397
        Name_of.typename_of_tuple2
 
398
          (Typerep.typename_of_t a)
 
399
          (Typerep.typename_of_t b)
 
400
      | T3 (a, b, c) ->
 
401
        Name_of.typename_of_tuple3
 
402
          (Typerep.typename_of_t a)
 
403
          (Typerep.typename_of_t b)
 
404
          (Typerep.typename_of_t c)
 
405
      | T4 (a, b, c, d) ->
 
406
        Name_of.typename_of_tuple4
 
407
          (Typerep.typename_of_t a)
 
408
          (Typerep.typename_of_t b)
 
409
          (Typerep.typename_of_t c)
 
410
          (Typerep.typename_of_t d)
 
411
      | T5 (a, b, c, d, e) ->
 
412
        Name_of.typename_of_tuple5
 
413
          (Typerep.typename_of_t a)
 
414
          (Typerep.typename_of_t b)
 
415
          (Typerep.typename_of_t c)
 
416
          (Typerep.typename_of_t d)
 
417
          (Typerep.typename_of_t e)
 
418
  end
 
419
 
 
420
  include Variant_and_record_intf.M (struct type 'a rep = 'a t type 'a t = 'a rep end)
 
421
 
 
422
  let rec typename_of_t : type a. a t -> a Typename.t = function
 
423
    | Int        -> Name_of.typename_of_int
 
424
    | Int32      -> Name_of.typename_of_int32
 
425
    | Int64      -> Name_of.typename_of_int64
 
426
    | Nativeint  -> Name_of.typename_of_nativeint
 
427
    | Char       -> Name_of.typename_of_char
 
428
    | Float      -> Name_of.typename_of_float
 
429
    | String     -> Name_of.typename_of_string
 
430
    | Bool       -> Name_of.typename_of_bool
 
431
    | Unit       -> Name_of.typename_of_unit
 
432
 
 
433
    | Option rep -> Name_of.typename_of_option (typename_of_t rep)
 
434
    | List rep   -> Name_of.typename_of_list   (typename_of_t rep)
 
435
    | Array rep  -> Name_of.typename_of_array  (typename_of_t rep)
 
436
    | Lazy rep   -> Name_of.typename_of_lazy_t (typename_of_t rep)
 
437
    | Ref rep    -> Name_of.typename_of_ref    (typename_of_t rep)
 
438
 
 
439
    | Function (dom, rng) ->
 
440
      Name_of.typename_of_function (typename_of_t dom) (typename_of_t rng)
 
441
 
 
442
    | Tuple rep -> Typerep.Tuple.typename_of_t rep
 
443
 
 
444
    | Record rep -> Typerep.Record.typename_of_t rep
 
445
    | Variant rep -> Typerep.Variant.typename_of_t rep
 
446
 
 
447
    | Named (name, _) -> Named.typename_of_t name
 
448
  ;;
 
449
 
 
450
  let rec same_witness : type a b. a t -> b t -> (a, b) Type_equal.t option = fun t1 t2 ->
 
451
    let module E = Type_equal in
 
452
    match t1, t2 with
 
453
    | Named (name1, r1), Named (name2, r2) -> begin
 
454
      match Typename.same_witness
 
455
        (Named.typename_of_t name1)
 
456
        (Named.typename_of_t name2) with
 
457
      | Some E.T as x -> x
 
458
      | None ->
 
459
        match r1, r2 with
 
460
        | Some (lazy t1), Some (lazy t2) -> same_witness t1 t2
 
461
        | Some (lazy t1), None           -> same_witness t1 t2
 
462
        | None, Some (lazy t2)           -> same_witness t1 t2
 
463
        | None, None -> None
 
464
    end
 
465
    | Named (_, r1), t2 -> begin
 
466
      match r1 with
 
467
      | Some (lazy t1) -> same_witness t1 t2
 
468
      | None -> None
 
469
    end
 
470
    | t1, Named (_, r2) -> begin
 
471
      match r2 with
 
472
      | Some (lazy t2) -> same_witness t1 t2
 
473
      | None -> None
 
474
    end
 
475
    | Int       , Int        -> Some E.T
 
476
    | Int32     , Int32      -> Some E.T
 
477
    | Int64     , Int64      -> Some E.T
 
478
    | Nativeint , Nativeint  -> Some E.T
 
479
    | Char      , Char       -> Some E.T
 
480
    | Float     , Float      -> Some E.T
 
481
    | String    , String     -> Some E.T
 
482
    | Bool      , Bool       -> Some E.T
 
483
    | Unit      , Unit       -> Some E.T
 
484
    | Option r1, Option r2 -> begin
 
485
      match same_witness r1 r2 with
 
486
      | None     as x -> x
 
487
      | Some E.T as x -> x
 
488
    end
 
489
    | List r1, List r2 -> begin
 
490
      match same_witness r1 r2 with
 
491
      | None     as x -> x
 
492
      | Some E.T as x -> x
 
493
    end
 
494
    | Array r1, Array r2 -> begin
 
495
      match same_witness r1 r2 with
 
496
      | None     as x -> x
 
497
      | Some E.T as x -> x
 
498
    end
 
499
    | Lazy r1, Lazy r2 -> begin
 
500
      match same_witness r1 r2 with
 
501
      | None     as x -> x
 
502
      | Some E.T as x -> x
 
503
    end
 
504
    | Ref r1, Ref r2 -> begin
 
505
      match same_witness r1 r2 with
 
506
      | None     as x -> x
 
507
      | Some E.T as x -> x
 
508
    end
 
509
    | Function (dom1, rng1), Function (dom2, rng2) -> begin
 
510
      match same_witness dom1 dom2, same_witness rng1 rng2 with
 
511
      | Some E.T, Some E.T -> Some E.T
 
512
      | None, _ | _, None  -> None
 
513
    end
 
514
    | Tuple t1, Tuple t2 -> begin
 
515
      let module T = Typerep.Tuple in
 
516
      match t1, t2 with
 
517
      | T.T2 (a1, b1), T.T2 (a2, b2) -> begin
 
518
        match same_witness a1 a2, same_witness b1 b2 with
 
519
        | Some E.T, Some E.T -> Some E.T
 
520
        | None, _ | _, None  -> None
 
521
      end
 
522
      | T.T3 (a1, b1, c1), T.T3 (a2, b2, c2) -> begin
 
523
        match
 
524
          same_witness a1 a2,
 
525
          same_witness b1 b2,
 
526
          same_witness c1 c2
 
527
        with
 
528
        | Some E.T, Some E.T, Some E.T -> Some E.T
 
529
        | None, _, _
 
530
        | _, None, _
 
531
        | _, _, None
 
532
          -> None
 
533
      end
 
534
      | T.T4 (a1, b1, c1, d1), T.T4 (a2, b2, c2, d2) -> begin
 
535
        match
 
536
          same_witness a1 a2,
 
537
          same_witness b1 b2,
 
538
          same_witness c1 c2,
 
539
          same_witness d1 d2
 
540
        with
 
541
        | Some E.T, Some E.T, Some E.T, Some E.T -> Some E.T
 
542
        | None, _, _, _
 
543
        | _, None, _, _
 
544
        | _, _, None, _
 
545
        | _, _, _, None
 
546
          -> None
 
547
      end
 
548
      | T.T5 (a1, b1, c1, d1, e1), T.T5 (a2, b2, c2, d2, e2) -> begin
 
549
        match
 
550
          same_witness a1 a2,
 
551
          same_witness b1 b2,
 
552
          same_witness c1 c2,
 
553
          same_witness d1 d2,
 
554
          same_witness e1 e2
 
555
        with
 
556
        | Some E.T, Some E.T, Some E.T, Some E.T, Some E.T -> Some E.T
 
557
        | None, _, _, _, _
 
558
        | _, None, _, _, _
 
559
        | _, _, None, _, _
 
560
        | _, _, _, None, _
 
561
        | _, _, _, _, None
 
562
          -> None
 
563
      end
 
564
      | T.T2 _, _ -> None
 
565
      | T.T3 _, _ -> None
 
566
      | T.T4 _, _ -> None
 
567
      | T.T5 _, _ -> None
 
568
    end
 
569
    | Record r1, Record r2 ->
 
570
      Typename.same_witness
 
571
        (Typerep.Record.typename_of_t r1)
 
572
        (Typerep.Record.typename_of_t r2)
 
573
    | Variant r1, Variant r2 ->
 
574
      Typename.same_witness
 
575
        (Typerep.Variant.typename_of_t r1)
 
576
        (Typerep.Variant.typename_of_t r2)
 
577
    | Int, _         -> None
 
578
    | Int32, _       -> None
 
579
    | Int64, _       -> None
 
580
    | Nativeint, _   -> None
 
581
    | Char, _        -> None
 
582
    | Float, _       -> None
 
583
    | String, _      -> None
 
584
    | Bool, _        -> None
 
585
    | Unit, _        -> None
 
586
    | Option _, _    -> None
 
587
    | List _, _      -> None
 
588
    | Array _, _     -> None
 
589
    | Lazy _, _      -> None
 
590
    | Ref _, _       -> None
 
591
    | Function _, _  -> None
 
592
    | Tuple _, _     -> None
 
593
    | Record _, _    -> None
 
594
    | Variant _, _   -> None
 
595
  ;;
 
596
 
 
597
  let same a b = same_witness a b <> None
 
598
  let same_witness_exn a b =
 
599
    match same_witness a b with
 
600
    | Some proof -> proof
 
601
    | None -> assert false
 
602
 
 
603
  let rec head = function
 
604
    | Typerep.Named (_, Some (lazy t)) -> head t
 
605
    | t -> t
 
606
end
 
607
 
 
608
let typerep_of_int        = Typerep.Int
 
609
let typerep_of_int32      = Typerep.Int32
 
610
let typerep_of_int64      = Typerep.Int64
 
611
let typerep_of_nativeint  = Typerep.Nativeint
 
612
let typerep_of_char       = Typerep.Char
 
613
let typerep_of_float      = Typerep.Float
 
614
let typerep_of_string     = Typerep.String
 
615
let typerep_of_bool       = Typerep.Bool
 
616
let typerep_of_unit       = Typerep.Unit
 
617
 
 
618
let typerep_of_option rep = Typerep.Option rep
 
619
let typerep_of_list   rep = Typerep.List   rep
 
620
let typerep_of_array  rep = Typerep.Array  rep
 
621
let typerep_of_lazy_t rep = Typerep.Lazy   rep
 
622
let typerep_of_ref    rep = Typerep.Ref    rep
 
623
 
 
624
let typerep_of_function dom rng = Typerep.Function (dom, rng)
 
625
 
 
626
let typerep_of_tuple0 = Typerep.Unit
 
627
let typerep_of_tuple2 a b = Typerep.Tuple (Typerep.Tuple.T2 (a, b))
 
628
let typerep_of_tuple3 a b c = Typerep.Tuple (Typerep.Tuple.T3 (a, b, c))
 
629
let typerep_of_tuple4 a b c d = Typerep.Tuple (Typerep.Tuple.T4 (a, b, c, d))
 
630
let typerep_of_tuple5 a b c d e = Typerep.Tuple (Typerep.Tuple.T5 (a, b, c, d, e))
 
631
 
 
632
include Name_of
 
633
let value_tuple0 = ()