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

Open Polymorphic Variants, difference between 4.00.1 and 4.01.0 #6256

Closed
vicuna opened this issue Dec 1, 2013 · 1 comment
Closed

Open Polymorphic Variants, difference between 4.00.1 and 4.01.0 #6256

vicuna opened this issue Dec 1, 2013 · 1 comment
Assignees

Comments

@vicuna
Copy link

vicuna commented Dec 1, 2013

Original bug ID: 6256
Reporter: sebmondet
Assigned to: @garrigue
Status: closed (set by @xavierleroy on 2015-12-11T18:25:23Z)
Resolution: not a bug
Priority: normal
Severity: major
Version: 4.01.0
Category: typing

Bug description

This code used to compile fine with 4.00.1:

module type T = sig
type t
val f : t -> ([> A | B ] -> t) -> t
end

module Tt : T = struct
type t = [ A | B ]
let f t g = g (t :> [> A | B])
end

but with 4.01.0, I get:

Error: Signature mismatch:
Modules do not match:
sig
type t = [ A | B ]
val f : ([> A | B ] as 'a) -> ('a -> 'b) -> 'b
end
is not included in
T
Values do not match:
val f : ([> A | B ] as 'a) -> ('a -> 'b) -> 'b
is not included in
val f : t -> ([> A | B ] -> t) -> t

PS: Is there a more future proof work-around that does not imply expanding a match-with? like this:

module Tt : T = struct
type t = [ A | B ]
let f t g =
match t with
| A -> g A
| B -> g B
end

@vicuna
Copy link
Author

vicuna commented Dec 2, 2013

Comment author: @garrigue

If you look at the type inferred in 4.00 (and previous version) you can see that this is a bug in the type subsumption check, which was fixed in 4.01:

module Tt = struct

 type t = [ `A | `B ]
let f t g = g (t :> [> `A | `B])

end;;
module Tt :
sig
type t = [ A | B ]
val f : ([> A | B ] as 'a) -> ('a -> 'b) -> 'b
end

Clearly the type inferred for f does not contain "t -> [> A | B] -> t -> t", as it requires that t and the argument of g have the same type.

The right way to write f is:

let f (#t as t) g = g t;;

val f : [< t ] -> ([> t ] -> 'a) -> 'a

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

No branches or pull requests

2 participants