Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Ctype.Unify(_) error with higher-order example #15

Open
yallop opened this issue Sep 22, 2014 · 4 comments
Open

Ctype.Unify(_) error with higher-order example #15

yallop opened this issue Sep 22, 2014 · 4 comments

Comments

@yallop
Copy link
Contributor

yallop commented Sep 22, 2014

I expect this can be simplified further:

module type S = sig type _ t end
implicit module Id = struct type 'a t = 'a end

module R = struct type 'a t = (implicit T: S) -> 'a T.t ->  unit end

let g (f : (implicit X: S) -> _ X.t -> unit) (implicit U:S) =
  let module RU = struct type 'a t = 'a R.t U.t end in f (implicit RU) 

let j (implicit T: S) _ = ()
let h f = g f j
@yallop
Copy link
Contributor Author

yallop commented Jun 5, 2015

The following code also raises Ctype.Unify(_). Perhaps it's the same issue:

module type T1 = sig type _ t end
implicit module Id = struct type 'a t = 'a end
let g : (implicit C:T1) -> (<f:'g. 'g -> 'g C.t>) -> unit = assert false
let _  = g (object method f : 'g. 'g -> 'g = assert false end)

@let-def
Copy link
Contributor

let-def commented Jun 7, 2015

After b81ea30 fix, I think it is the same issue.

I don't know how these unifications should be handled. The code dealing with this is: typeimplicit.ml:165.

Here, tyvar is a type variable introduced during instantiation of the implicit arrow, ty is a type referring to the implicit module that should be unified with tyvar.
E.g when instantiating f : (implicit M : T) -> M.t -> unit a type variable 'a is introduced and the tuple (M.t,'a) is added to the constraint list.

This code is quite naive as I don't know enough about OCaml unification to properly handle all the cases… The environment and the unification function should be properly setup and selected so that call on line 168 succeed.

@let-def
Copy link
Contributor

let-def commented Jul 13, 2015

We spend some time looking at that issue with @lpw25 .

The unify error is likely because of unification with a univar which was put in the constraint list.
During normal typechecking this is an error as the univar will be ill-scoped (unifiying something under the forall quantifier with some variables potentially from the outside).

Luckily, with implicits, we can make sure by construction that all type variables introduced appear only in the correct scope.

typeimplicit.ml:62 is about sharing of introduced type variables: we introduce only one fresh type variable per equal types.
This is correct except for types which are syntactically equal but interpreted in different scopes, e.g. (<f:'g. 'g -> 'g C.t>) -> (<f:'g. 'g -> 'g C.t>) -> unit, or even more tricky, (<f:'g. 'g -> 'g C.t -> (<f:'g. 'g -> 'g C.t>) >) -> unit

The solution is:

  • keep track of scope in typeimplicit.ml:73, when entering and exiting a Tpoly.
  • relax unification typeimplicit.ml:165 now that we know that unification of Tunivar with fresh variable is correct.

@let-def
Copy link
Contributor

let-def commented Jul 13, 2015

Leo suggested we introduce a new constructor for type variables which are allowed to unify with some univars, something like:

Tpolyvar of string list (* allowed univars *) * string option (* like usual Tvar *)

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

2 participants