I am a beginner to ML/Haskell and I am trying to create a list of structures. Actually, I am developing a web application in Urweb (functional web programming language, a lot of features from ML and Haskell.) I am trying to create an interface to Tinymce (open source rich text editor, and it consists of all the plugin such as print, link). So to manage all plugins, I am composing in the form of structure and I need one data structure to hold all the structures (Plugins in my case) and at the end stage in can be used to initialize my editor.
For example:
val plugins = [print, link, img];
and elements inside list plugins
such as print
is a structure:
structure print = struct
type t = string
.
.
end
How can I achieve this?
The general answer is that No you cannot create a list of structures, the same is true as well of signatures, and functors
however; if your plugin system is built in a way in which the entry types, and exit types of each plugin are the same across all plugins, you can build a kind of closure to a structure and embed that into a function.
you can then use functors, to build up the functions of your plugin system
We start out with the interface of each "plugin".
signature DANCER =
sig
type t;
val dancer : t
val tired : t -> bool
val dance : t -> t;
end
Followed by the interface through which our application interacts with the plugin.
datatype exhaustion = Exhausted;
signature DANCING_MANIA =
sig
val dance : unit -> exhaustion;
end
The implementation of the above DANCING_MANIA signature, accepts a DANCER, and hides the differences between plugins/structures
functor Dancer (D : DANCER) : DANCING_MANIA =
struct
fun dance() =
let fun until_exhaustion (dancer) =
if not (D.tired dancer)
then until_exhaustion(D.dance(dancer))
else Exhausted;
in until_exhaustion(D.dancer) end
end
Finally we can implement some plugins, and throw them in a list.
structure Tony :> DANCER =
struct
type t = int;
val dancer = 5;
fun tired x = x <= 0;
fun dance x = (print "tony dance!\n"; x - 1);
end
structure Annette :> DANCER =
struct
type t = real;
val dancer = 1.0;
fun tired x = x <= 0.0;
fun dance x = (print "annette dance!\n"; x - 0.2);
end
structure TonyDance = Dancer(Tony);
structure AnnetteDance = Dancer(Annette);
val dancers = [TonyDance.dance, AnnetteDance.dance];
fun danceOff (x::xs) = let val _ = x(); in danceOff(xs) end
| danceOff ([]) = ();
val _ = danceOff(dancers);
So, the idea is that while you cannot create a list of structures, you can create a list of things, that each contain a different structure, as long as the exposed types are uniform.