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

Using extensible variant types in functor #6723

Closed
vicuna opened this issue Dec 18, 2014 · 4 comments
Closed

Using extensible variant types in functor #6723

vicuna opened this issue Dec 18, 2014 · 4 comments

Comments

@vicuna
Copy link

vicuna commented Dec 18, 2014

Original bug ID: 6723
Reporter: @zoggy
Status: closed (set by @zoggy on 2014-12-18T14:23:30Z)
Resolution: not a bug
Priority: normal
Severity: minor
Version: 4.02.1
Category: typing

Bug description

I'd like to create functors taking in parameter a module with an extensible type t:

module type P = sig type t = .. end

module F (P:P) = struct type P.t += TFoo of int end
module G (P:P) = struct type P.t += TBar of float end

module P1 = struct type t = .. end
module F1 = F(P1)
module G1 = F(P1)

Now the problem is that I can't refer to TFoo or TBar constructors, except of course respectively in the bodies of functors F an G.

I tried a workaround like this:
module G (P:P) = struct
type b = TBar of float
type P.t += TBar = TBar
end

But in this case, I get:
Error: The constructor TBar has type b but was expected to be of type P.t

The documentation is not clear about rebinding extensible variant constructors. The provided example, type Expr.attr += Str = Expr.Str seems of limited interest as Str is rebound to ... Str ?

@vicuna
Copy link
Author

vicuna commented Dec 18, 2014

Comment author: @yallop

Now the problem is that I can't refer to TFoo or TBar constructors, except of course respectively in the bodies of functors F an G.

You can write 'F1.TFoo' and 'G1.TBar' (assuming 'G1 = F(P1)' is a typo for 'G1 = G(P1)'):

let f = function
F1.TFoo x -> string_of_int x
| G1.TBar y -> string_of_float y
| _ -> "unknown"

The documentation is not clear about rebinding extensible variant constructors.

The syntax is as follows:

type P1.t +=
NewFoo = F1.TFoo
| NewBar = G1.TBar

Now you can write

let f = function
NewFoo x -> string_of_int x
| NewBar y -> string_of_float y
| _ -> "unknown"

@vicuna
Copy link
Author

vicuna commented Dec 18, 2014

Comment author: @alainfrisch

It's true that the manual does not say clearly that extension constructors are scoped by the module where they are defined. Developers are used to be able to access constructors directly when their type is in scope, but of course, this cannot work with extensible types.

@vicuna
Copy link
Author

vicuna commented Dec 18, 2014

Comment author: @zoggy

Thanks, indeed this was G and not F. I tried G1.TBar but with this error it of course did not work.

By the way, I'm surprised that this is not accepted:

type t = ..
type u = t
type u += Foo

Error: Cannot extend type definition u

@vicuna
Copy link
Author

vicuna commented Dec 18, 2014

Comment author: @zoggy

It seems to work with:
type t = ..
type u = t = ..
type u += Foo

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

1 participant