F#: Can't hide a type abbreviation in a signature? Why not?
f#
Solution
As Ganesh points out, this is a technical limitation of the F# compiler (and .NET runtime), because the type abbreviation is simply replaced by the actual type during the compilation. As a result, if you write a function:
let foo (a:MyType) : MyType = a + 1
The compiler will compile it as a .NET method with the following signature:
int foo(int a);
If the actual type of the abbreviation was hidden from the users of the library, then they wouldn't be able to recognize that the `foo` function is actually working with `MyType` (this information is probably stored in some F#-specific meta-data, but that is not accessible to other .NET languages...).
Perhaps the best workaround for this limiation is to define the type as a single-case discriminated union:
type MyType = MT of int
let foo (MT a) = MT(a + 1)
Working with this kind of type is quite convenient. It adds some overhead (there are new objects created when constructing a value of the type), but that shouldn't be a big issue in most of the situations.
Problem
In F#, I'd like to have what I see as a fairly standard Abstract Datatype: ``` // in ADT.fsi module ADT type my_Type // in ADT.fs module ADT type my_Type = int ``` In other words, code inside the module knows that my_Type is an int, but code outside does not. However, F# seems to have a restriction where type abbreviations specifically cannot be hidden by a signature. This code gives a compiler error, and the restriction is described here. If my_Type were instead a discriminated union, then there is no compiler error. My question is, why the restriction? I seem to remember being able to do this in SML and Ocaml, and furthermore, isn't this a pretty standard thing to do when creating an abstract datatype? Thanks