Jason Perry
Jason Perry

Reputation: 55

Standard ML: making a type transparent with opaque signature ascription

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

Answers (1)

Andreas Rossberg
Andreas Rossberg

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

Related Questions