Join GitHub today
GitHub is home to over 31 million developers working together to host and review code, manage projects, and build software together.Sign up
Ability to re-export a variant definition with renamed constructors? #7102
Original bug ID: 7102
We have a bit of an issue in Batteries for the 4.03 transition, as 4.03+dev includes a ('a result) type defined as
type ('a,'b) result = Ok of 'a | Error of 'b
while Batteries has distributed forever a datatype
type ('a, 'b) result = Ok of 'a | Bad of 'b
This should, of course, not be blocking for the addition of a result type in 4.02.3, but it would be nice if it were possible to provide a smooth transition path to our users. (We can provide both datatypes, using type-directed constructor disambiguation, but there is still the issue that a number of functions return values of BatPervasives.result type, and we'd rather not duplicate them to have versions returning Pervasives.result).
Would it be possible to declare an alias with constructors of the same structure, but different names?
type ('a, 'b) result = ('a, 'b) Pervasives.result = | Ok of 'a | Bad of 'b
Comment author: @garrigue
Unfortunately, I'm afraid this feature first requires some theoretical work.
A first problem is that it breaks the type-erasure semantics of the language: now two constructors are equal if they have the same type (otherwise you cannot compare them) and same name. If they are allowed to have different names, then constructors are something else.
A second problem, which is a consequence of the first, is the interaction with constructor disambiguation. Suppose that you define
in some module M1, and re-export it as
Then you have in the same scope two constructors C and D, which belong to the same type, and whose resolution is ambiguous...
Maybe there is a proper way to do that, but this requires some fundamental work.
Comment author: @gasche
This is probably due to my very naive point of view, but I don't see
I understand the feature as the ability to rebind constructors to
The elaboration semantics is just a partial-evaluation optimization of
This situation can be rejected at declaration-time (or lazily whenever
Ok, we'll have to find another solution then.
Comment author: @garrigue
Looking back at this discussion, Alain's approach could work if it is understood as just adding nicknames to constructors. I.e., there should be no way to hide the original name in the declaration, as this would break soundness for GADTs (it assumes that two variant types are distinct if their constructors are distinct).
This said, it still means that evaluation of an expression cannot be understood independently of the type definition, which I see as a downside (this is what I meant by type erasure, and elaboration is precisely what I want to avoid).
And the problem with disambiguation cannot be checked at definition time: you could have two conflicting redefinitions in different modules. This means that the meaning of a disambiguated expression may depend on the scope (i.e. which one is open) whereas the type is really the same. And this breaks your "interpretation" semantics.