Daniel Holden
Daniel Holden

Reputation: 59

Functor Structure extension and Multiple Ascription in SML

Is there any way in Standard ML to make a functor output a structure which has all of the functionality of the passed in structure, plus any new functionality.

In a similar way, is it possible to do multiple ascription? In the case of the above it would be immediately useful because you could ascribe the output of the functor to both the signature of the original structure and another signature which specifies the new functionality.

I understand the implications of doing such a thing, and why it might be a bad idea. Currently I've just been keeping a copy of the passed in structure within the functor output - but this means you have a long chain of "Foo.Bar.func" to access the base functionality.

Thanks

Upvotes: 1

Views: 834

Answers (2)

Jesper.Reenberg
Jesper.Reenberg

Reputation: 5944

Say I wanted to make a signature for "TestUp". Is there any way to do this without duplicating the contents of the "TEST" into a new signature?

If I understand your question correctly then you are looking for the include keyword, which will include the definition of a previous signature into a new and thus extending the signature with the previous definitions.

signature TEST_EXT =
sig
  include TEST

  val beep1 : meep -> unit
end

functor TestUp_EXT(T : TEST) : TEST_EXT =
struct
  open T

  fun localFun s = beep (10, s)
  val beep1 = localFun

end


structure Test2_EXT = TestUp_EXT (Test);

Test2_EXT.beep (5, "EXT: Hi");
Test2_EXT.beep1 "Hi";

print (Int.toString (Test2.rand ()) ^ "\n");


(* This will fail as the signature doesn't define this function,
however as seen the function can easily be used within the functor as
expected *)
(* Test2_EXT.localFun "Hi"; *)

Upvotes: 3

You can use open to bring the contents of a structure into the current scope. If used inside another structure (or functor), it'll do what I believe it is you want.

An example can be seen here:

signature TEST =
sig
    type meep;
    val beep : int * meep -> unit;
end;

structure Test : TEST =
struct
    type meep = string

    fun beep (0, _) = ()
      | beep (n, s) = (print (s^"\n"); beep (n-1, s));
end;

functor TestUp (T : TEST) =
struct
    open T

    fun rand () = 4
end;

structure Test2 = TestUp (Test);

Test.beep (5, "Hello");

Test2.beep (5, "Hi");

print (
    Int.toString (Test2.rand ()) ^ "\n"
);

Upvotes: 2

Related Questions