Reputation: 55
As I understand it, in SML modules, to prevent every type from being hidden by opaque signature ascription, you can specify concrete types in the signature.
I'm trying to do that with a functor for making symbol tables, hiding the table type but leaving the entry type transparent. But whenever I do opaque ascription I can't access the entry type. Here are my signatures and functor:
signature ST_ENTRY = sig
type entry
val name : entry -> string
end
signature SYMTABLE = sig
structure E: ST_ENTRY
type symentry = E.entry
type symtable
val empty: symtable
val insert: symtable -> E.entry -> symtable
val lookup: symtable -> string -> E.entry option
end
functor SymtableFn (Ent:ST_ENTRY) :> SYMTABLE = struct
structure E = Ent
type symentry = E.entry
type symtable = E.entry list
val empty: symtable = []
fun fromList symlist = symlist
fun insert (tab: symtable) e = e::tab
end
Then, when I create an entry struct and instantiate the functor with it, like this:
structure Myentry : ST_ENTRY = struct
type entry = {name: string, typ: string}
fun name (e:entry) = #name e
end
structure Mytable = SymtableFn (Myentry)
val tab = Mytable.insert (Mytable.empty) {name="x", typ="str"}
I get a type clash for the last line, but if I turn off opaque ascription, it works fine. I tried with both SML/NJ and Moscow ML and get the same error. Why isn't this working like I think it should? Is there any way to make the entry type transparent?
Upvotes: 3
Views: 980
Reputation: 36098
You also need to specify that the resulting type E.entry
relates to the functor parameter. Just change the declaration of the functor to
functor SymtableFn (Ent:ST_ENTRY) :> (SYMTABLE where type E.t = Ent.entry) = struct ...
In fact, I'd drop substructure E
from signature SYMTABLE
and change the above to
functor SymtableFn (Ent:ST_ENTRY) :> (SYMTABLE where type symentry = Ent.entry) = struct ...
Upvotes: 4