On 4.03.0.
I have this code, basically:
module rec First : sig
type field
type 'a target = <at_least_this_method: field; .. > as 'a
end = First
and Second : sig
class foo : object
method at_least_this_method : First.field
end
end = Second
and Third : sig
class usage :
object
method action : #Second.foo First.target -> unit
end
end = struct
class usage = object
method action (a : #Second.foo First.target) = ()
end
end
And the last line of method action
fails to type with error message:
Error: Some type variables are unbound in this type:
class usage :
object method action : #Second.foo First.target -> unit end
The method action has type (#Second.foo as 'a) First.target -> unit
where 'a is unbound
I also tried something like:
class usage = object
method action = fun (type t) (b : (#Second.foo as t) First.target) -> ()
end
But that didn't type either.
EDIT: please refer to @gariguejej's answer below for a better explanation.
I'm not an expert of type system of objects, but here are my two cents.
Change your code to:
module rec First : sig
type field
type 'a target = <at_least_this_method: field; .. > as 'a
end = First
and Second : sig
class foo : object
method at_least_this_method : First.field
end
end = Second
and Third : sig
class ['a] usage :
object
method action : 'a First.target -> unit
end
end = struct
class ['a] usage = object
method action : 'a First.target -> unit = fun a -> ()
end
end
Use ocaml -i
, we can see 'a
is constrained to constraint 'a = < at_least_this_method : First.field; .. >
.
module rec First :
sig
type field
type 'a target = 'a constraint 'a = < at_least_this_method : field; .. >
end
and Second :
sig class foo : object method at_least_this_method : First.field end end
and Third :
sig
class ['a] usage :
object
constraint 'a = < at_least_this_method : First.field; .. >
method action : 'a First.target -> unit
end
end
Of course, you can also manually constraint 'a
to <at_least_this_method: field>
if you want it to be a closed object type. For example,
module rec First : sig
type field
type 'a target = <at_least_this_method: field; .. > as 'a
end = First
and Second : sig
class foo : object
method at_least_this_method : First.field
end
end = Second
and Third : sig
class ['a] usage :
object
constraint 'a = <at_least_this_method:First.field>
method action : 'a First.target -> unit
end
end = struct
class ['a] usage = object
constraint 'a = <at_least_this_method:First.field>
method action : 'a First.target -> unit = fun a -> ()
end
end
See manual Chapter 3.10