File: generative.ml

package info (click to toggle)
ocaml 5.3.0-3
  • links: PTS, VCS
  • area: main
  • in suites: trixie
  • size: 43,124 kB
  • sloc: ml: 355,439; ansic: 51,636; sh: 25,098; asm: 5,413; makefile: 3,673; python: 919; javascript: 273; awk: 253; perl: 59; fortran: 21; cs: 9
file content (117 lines) | stat: -rw-r--r-- 3,496 bytes parent folder | download
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
(* TEST
 expect;
*)

(* Using generative functors *)

(* Without type *)
module type S = sig val x : int end;;
let v = (module struct let x = 3 end : S);;
module F() = (val v);; (* ok *)
module G (X : sig end) : S = F ();; (* ok *)
module H (X : sig end) = (val v);; (* ok *)
[%%expect{|
module type S = sig val x : int end
val v : (module S) = <module>
module F : () -> S
module G : (X : sig end) -> S
module H : (X : sig end) -> S
|}];;

(* With type *)
module type S = sig type t val x : t end;;
let v = (module struct type t = int let x = 3 end : S);;
module F() = (val v);; (* ok *)
[%%expect{|
module type S = sig type t val x : t end
val v : (module S) = <module>
module F : () -> S
|}];;
module G (X : sig end) : S = F ();; (* fail *)
[%%expect{|
Line 1, characters 29-33:
1 | module G (X : sig end) : S = F ();; (* fail *)
                                 ^^^^
Error: This expression creates fresh types.
       It is not allowed inside applicative functors.
|}];;
module H() = F();; (* ok *)
[%%expect{|
module H : () -> S
|}];;

(* Alias *)
module U = struct end;;
module M1 = F();; (* ok *)
module M2 = F(struct end);; (* accepted with a warning *)
[%%expect{|
module U : sig end
module M1 : S
Line 3, characters 14-24:
3 | module M2 = F(struct end);; (* accepted with a warning *)
                  ^^^^^^^^^^
Warning 73 [generative-application-expects-unit]: A generative functor
should be applied to '()'; using '(struct end)' is deprecated.

module M2 : S
|}];;
module M = F(U);; (* fail *)
[%%expect{|
Line 1, characters 11-12:
1 | module M = F(U);; (* fail *)
               ^
Error: This is a generative functor. It can only be applied to "()"
|}];;

(* Cannot coerce between applicative and generative *)
module F1 (X : sig end) = struct end;;
module F2 : () -> sig end = F1;; (* fail *)
[%%expect{|
module F1 : (X : sig end) -> sig end
Line 2, characters 28-30:
2 | module F2 : () -> sig end = F1;; (* fail *)
                                ^^
Error: Signature mismatch:
       Modules do not match:
         (X : sig end) -> ...
       is not included in
         () -> ...
       The functor was expected to be generative at this position
|}];;
module F3 () = struct end;;
module F4 : functor (X : sig end) -> sig end = F3;; (* fail *)
[%%expect{|
module F3 : () -> sig end
Line 2, characters 47-49:
2 | module F4 : functor (X : sig end) -> sig end = F3;; (* fail *)
                                                   ^^
Error: Signature mismatch:
       Modules do not match:
         () -> ...
       is not included in
         (X : sig end) -> ...
       The functor was expected to be applicative at this position
|}];;

(* tests for shortened functor notation () *)
module X (X: sig end) (Y: sig end) = functor (Z: sig end) -> struct end;;
module Y = functor (X: sig end) (Y:sig end) -> functor (Z: sig end) ->
  struct end;;
module Z = functor (_: sig end) (_:sig end) (_: sig end) -> struct end;;
module GZ : functor (X: sig end) () (Z: sig end) -> sig end
          = functor (X: sig end) () (Z: sig end) -> struct end;;
[%%expect{|
module X : (X : sig end) (Y : sig end) (Z : sig end) -> sig end
module Y : (X : sig end) (Y : sig end) (Z : sig end) -> sig end
module Z : sig end -> sig end -> sig end -> sig end
module GZ : (X : sig end) () (Z : sig end) -> sig end
|}];;

(* disabling warning 73 in the argument *)
module F5 () = struct end;;
module No_warn = F5 (struct end [@warning "-73"])

[%%expect{|
module F5 : () -> sig end
module No_warn : sig end
|}]