12

For a class project I am writing a program that evaluates the performance of different implementations of the same abstract data structure. Since I am using identical code to test each of them, I would like to be able to set a module alias depending on user input and just run that module through the testing code.

In other words, I want something like:

let module M = 
  if model = "tree" then TreeModel else
  if model = "hash" then HashModel else
  ListModel
in ...

Is there a way I can make this work, or am I going about this all wrong?

Gilles 'SO- stop being evil'
  • 104,111
  • 38
  • 209
  • 254
Aniket Schneider
  • 904
  • 1
  • 8
  • 21

2 Answers2

13

There are no conditionals on the module level, but you can use first-class modules for this:

let m = match model with
  | "tree" -> (module TreeModel : MODEL)
  | "hash" -> (module HashModel : MODEL)
  | "list" -> (module ListModel : MODEL)
in let module M = (val m : MODEL)
in ...
Andreas Rossberg
  • 34,518
  • 3
  • 61
  • 72
0

As a follow-up to @Andreas, at least in recent ocaml versions you can also write:

let (module M : MODEL) = match model with
  | "tree" -> (module TreeModel : MODEL)
  | "hash" -> (module HashModel : MODEL)
  | "list" -> (module ListModel : MODEL)
in ...
ansiwen
  • 1,061
  • 8
  • 13
  • and with this form, you don't have to write the module type information in all match branches: `(module M : MODEL)` is enough and will propagate. – lavi Dec 06 '17 at 09:14
  • 1
    Not here. I would get `Error: The signature for this packaged module couldn't be inferred.` without the type annotation. – ansiwen May 29 '18 at 09:39
  • may be depend on the version of your compiler, but for me this is working: `let (module M : MODEL) = match model with | "tree" -> (module TreeModel) ...` – lavi May 29 '18 at 11:04