This exercise I made up is intended to help me understand signatures, structures, and functors in Standard ML. I can't seem to get it to work. Just for reference, I'm using
Standard ML of New Jersey v110.75 [built: Sun Jan 20 21:55:21 2013]
I have the following ML signature for an "object for which you can compute magnitude":
signature MAG_OBJ =
sig
type object
val mag : object -> int
end
If I want to give a structure of "int sets with magnitude," I might have a structure for an ordered int to use with the standard library's ORD_SET signature as follows:
structure OrderedInt : ORD_KEY =
struct
type ord_key = int
val compare = Int.compare
end
Then I can create a functor to give me a structure with the desired types and properties:
functor MakeMagSet(structure ELT : ORD_KEY) : MAG_OBJ =
struct
structure Set : ORD_SET = RedBlackSetFn(ELT)
type object = Set.set
val mag = Set.numItems
end
So far so good (everything compiles, at least). Now I create an instance of the structure for my OrderedInt structure I made above:
structure IntMagSet = MakeMagSet(structure ELT = OrderedInt)
But when I try to use it (create a set and compute its magnitude), I get an error:
val X = IntMagSet.Set.addList(IntMagSet.Set.empty, [0,1,2,3,4,5,6,7,8,9])
gives the error:
Error: unbound structure: Set in path IntMagSet.Set.empty.addList
From what I understand, ascribing a signature opaquely using :> makes it so one can't access any structure internals which are not defined explicitly in the signature, but I ascribed MAG_OBJ transparently, so I should be able to access the Set structure, right? What am I missing here?
[EDIT]
Even rewriting the functor to specifically bind the functions I want to the struct is no good:
functor MakeMagSet(structure ELT: ORD_KEY) : MAG_OBJ =
struct
structure Set : ORD_SET = RedBlackSetFn(ELT)
type object = Set.set
val mag = Set.numItems
val empty = Set.empty
val addList = Set.addList
end
Trying to access "empty" and "addList" give unbound variable errors.
On the other hand, trying to explicitly define the Set structure outside of the struct and use its functions gives a type error upon calling mag:
Error: operator and operand don't agree [tycon mismatch]
operator domain: IntMagSet.object
operand: Set.set
in expression:
IntMagSet.mag X