Nosrettap
Nosrettap

Reputation: 11320

How to instantiate a functor in SML?

If I have the following functor, how can I instantiate it with a ListMapFn?

functor G(M: ORD_MAP where type Key.ord_key = string) :

Upvotes: 3

Views: 2391

Answers (2)

Andreas Rossberg
Andreas Rossberg

Reputation: 36088

Something like

structure S = G(ListMapFn(type ord_key = string; val compare = String.compare))

or, if you prefer to name the ListMap instance:

structure ListMap = ListMapFn(type ord_key = string; val compare = String.compare)
structure S = G(ListMap)

Upvotes: 4

Jesper.Reenberg
Jesper.Reenberg

Reputation: 5944

Just to elaborate a bit on the syntax of functors, here are some examples.

First some preliminary declarations so we have something to work with.

signature FOO =
sig
  val foo : unit -> unit
end


structure FooUnit : FOO =
struct
  fun foo () = ()
end


structure FooPrint : FOO =
struct
  fun foo () = print "Foo\n"
end

Now. when we create functors, which only take one structure as argument, it is optionally if we wan't to write functor FooFn (f : FOO) or functor FooFn (structure f : FOO). Actually this applies only when the functor takes one structure as an argument:

(* Optionally to write "structure f : FOO" as there is only one argument *)
functor FooFn (f : FOO) = struct
  val foo = f.foo
end

However when the functor takes two or more arguments, it is mandatory to use the keyword structure. Note that a functor may take other arguments as well, for example an integer value.

(* Note there is no delimiter, just a space and the structure keyword *)
functor FooFooFn (structure f1 : FOO
                  structure f2 : FOO) =
struct
  val foo1 = f1.foo
  val foo2 = f2.foo
end

We also have a few options when applying the functor, and getting the resulting structure back. The first one is straight forward.

structure f1 = FooFn (FooUnit)

However this one is a bit of a "special case", as we define it "inlined", omitting the struct and end part

structure f2 = FooFn (fun foo () = print "Inlined\n")

or we can be a bit more verbose, and include the struct and end part. However both of these only work, because the functor takes one argument

structure f2_1 = FooFn (struct fun foo () = print "Inlined\n" end)

The syntax is somewhat the same when the functor takes multiple arguments

(* Again note there is no delimiter, so we can have it on the same line *)
structure f3 = FooFooFn (structure f1 = FooUnit structure f2 = FooPrint)

it somewhat resembles records, as the order doesn't matter

(* And we can even switch the order *)
structure f4 = FooFooFn (structure f2 = FooUnit
                         structure f1 = FooPrint)

Upvotes: 5

Related Questions