Hi,
I stumbled upon the following situation involving weak type variables:
# let x = ref None;;
val x : '_weak1 option ref = {contents = None}
# type 'a res =
| Done of 'a
| Undone of unit
;;
type 'a res = Done of 'a | Undone of unit
# x := Some (Done 5);;
Error: This expression has type 'a res but an expression was expected of type
'weak1
The type constructor res would escape its scope
# let x = ref None;;
val x : '_weak2 option ref = {contents = None}
# x := Some (Done 5);;
- : unit = ()
This is a simplified example, it actually occurred in “real” code, so it was quite hard for me to see where the error came from.
My interpretation is that weak type variables should ultimately be instantiated, which all manuals and books that I know of indeed say, but only with types existing in the environment when the weak type variable was introduced, which -I think- no manual or book says (most examples in the literature instantiate x
with an integer, but int
is already declared in the OCaml prelude).
So this a question for OCaml experts:
- Is my interpretation correct or at least sufficiently accurate for everyday programming?
- If so, would you agree that it would be relevant to update the OCaml manual (at least) (and why not RWO2) to explain this?
- In this specific case, would it be possible to implement in the compiler an improved error message with an hint saying that the type constructor
res
didn’t even exist in the environment when_weak1
was introduced, and so cannot even be used when mutatingx
?