eatonphil
eatonphil

Reputation: 13672

Referring to a type involving the result of a functor in a signature

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

Answers (2)

sshine
sshine

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

Ionuț G. Stan
Ionuț G. Stan

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

Related Questions