Reputation: 13672
How can I refer to a type in a signature used in a structure that derives the type from the result of a functor. Here is an example using the poly interpreter:
> signature Res = sig type f end;
signature Res = sig type f end
> functor F (A: sig type t end) : Res = struct datatype f = None | Some end;
functor F (A: sig type t end): Res
> structure S = struct local structure A = F(struct type t = int end) in type t = A.f list end end;
structure S: sig type t = A.f list end
First, I don't understand why A.f shows up in the resulting signature when it is local to the structure. Second, how can I create a signature that matches this structure S?
Something like this does not work:
signature SSig = sig type t = F(struct type t = int end).t list end
Also, if the type f is an int instead of a datatype, somehow S ultimately becomes aware that f is an int instead of it being hidden by the signature. This doesn't seem like reasonable behavior even if using opaque signatures doesn't show the int.
> functor F (A: sig type t end) : Res = struct type f = int end;
functor F (A: sig type t end): Res
> structure S = struct local structure A = F(struct type t = int end) in type t = A.f list end end;
structure S: sig type t = int list end
> functor F(A: sig type t end):> Res = struct type f = int end;
functor F (A: sig type t end): Res
> structure S = struct local structure A = F(struct type t = int end) in type t = A.f list end end;
structure S: sig type t = A.f list end
Upvotes: 2
Views: 136
Reputation: 16105
[...] why A.f shows up in the resulting signature when it is local to the structure.
This appears to be an artifact of Poly/ML. Moscow ML does not seem to leak the name:
Moscow ML version 2.10
Enter `quit();' to quit.
- signature Res = sig type f end;
> signature Res = /\f.{type f = f}
- functor F (A: sig type t end) : Res =
struct
datatype f = None | Some
end;
> functor F : !t.{type t = t}->?=f.{type f = f}
- structure S =
struct
local structure A = F(struct type t = int end)
in type t = A.f list
end
end;
> New type names: =f
structure S : {type t = f list}
How can I refer to a type in a signature used in a structure that derives the type from the result of a functor?
(Comment) The issue is that I don't want to make the type t opaque in SSig, but I also don't want to include R in the signature because I don't want consumers to have access to it. I could do a similar thing with an opaque type f = R.f but I'd have to include that in the signature and again that makes the signature messy.
A recent answer by Drup on how to decide whether to parameterize on the type-level or the module-level when designing modules discusses the drawbacks of monomorphising a module's input types.
Aren't "making t opaque in SSig" and "not including R in the signature of SSig" equivalent when all R contains is type t? Perhaps Res contains more things than type t, in which case you could supply structure R : sig type t end
instead. Or perhaps this variation of Ionuț's answer is preferable:
signature Res =
sig
type t (* rather than structure R *)
type f = t list
end
functor F (A : sig type t end) : Res =
struct
type t = A.t
type f = t list
end
structure S = F(struct type t = int end)
I am unsure of how to avoid the duplication of type f = t list
.
Upvotes: 1
Reputation: 179109
I don't really have an answer to your first question, just a guess, so I won't comment on that. Andreas Rossberg will probably clarify things there :)
Regarding your second question. I don't understand why you'd want to instantiate a functor inside a signature. Maybe you want this?
signature Res =
sig
type f
end
signature SSig =
sig
structure R : Res
type t = R.f list
end
And then, whoever implements SSig
is free to assign the result of calling F
to the R
sub-structure.
Regarding your last point. Types are not hidden unless you opaquely implement a signature.
Upvotes: 2