ocamlocaml-core

Switching between modules dynamically in OCaml


I have a module in OCaml that is parameterized by another module, which represents a data structure (H = Hashtable, M = Map, L = LossyMap). I would now like to let this data structure be selected via the command line.

The way I create the main processing module is:

module HashSampler = MakeSampler(HashtableMatrix)
module MapSampler = MakeSampler(MapMatrix)

etc.

Unfortunately, the code that multiplexes between these is ugly:

match representation with
| "Hashtable" ->
       let matrix = HashSampler.create () in
           HashSampler.process_file matrix file
| "Map" -> 
       let matrix = MapSampler.create () in
           MapSampler.process_file matrix file

Is there a better way of doing this that somehow prevents code duplication?


Solution

  • You can use first class modules. Here's some example code that shows one possibility.

    module type Sampler = sig
        type t
        val create : unit -> t
        val process_file : t -> string -> unit
    end
    module HashSampler : Sampler = struct
        type t = unit
        let create () = ()
        let process_file () file = ()
    end
    module MapSampler : Sampler = struct
        type t = unit
        let create () = ()
        let process_file () file = ()
    end
    
    let choose_sampler : string -> (module Sampler) = function
        | "Hashtable" -> (module HashSampler)
        | "Map" -> (module MapSampler)
    
    let process representation file =
        let (module M) = choose_sampler representation in
        let matrix = M.create () in M.process_file matrix file