ocaml-prog-pats / functor_inst / functor_inst.ml

(* Signature of module to be substituted *)
module type Arg = sig val (+) : float -> float -> float end

(* Module implementing functions to be substituted *)
module Std_float : Arg = struct
  let (+) = (+.)

(* Signature of module resulting from functor instantiation *)
module type S = sig val f : float -> float end

(* Here we define the body of the functor in which we want to substitute
   arguments.  Note that we have to use a first-class module here, because
   the DEFINE macro can unfortunately only deal with expressions, not
   structures. *)
  ((module struct
    let f x = Float.(x + x)
  end : S))

(* Here we instantiate the "functor" (actually: macro) using the macro
   preprocessor. *)
module Fast = struct
  module Float = Std_float
  include (val Body)

(* Here we define the generic functor using a function.  It is apparently
   impossible to use ordinary module functors, because we cannot call "include"
   on first-class modules within those due to a compiler limitation. *)
let func fl =
  let module Float = (val fl : Arg) in

(* Here we instantiate the generic functor, though using a function rather than
   a more traditional module functor due to the "include" restriction
   mentioned above.  It is apparently equivalent in performance to usual
   functor instantiations. *)
module Slow = (val func (module Std_float))

let main () =
  (* "Fast" is more than twice as fast as "Slow" *)
  let f x = Fast.(f x) in
  (* let f x = Slow.(f x) in *)
  for _i = 1 to 100_000_000 do ignore (f 42.) done

let () = main ()
Tip: Filter by directory path e.g. /media app.js to search for public/media/app.js.
Tip: Use camelCasing e.g. ProjME to search for ProjectModifiedEvent.java.
Tip: Filter by extension type e.g. /repo .js to search for all .js files in the /repo directory.
Tip: Separate your search with spaces e.g. /ssh pom.xml to search for src/ssh/pom.xml.
Tip: Use ↑ and ↓ arrow keys to navigate and return to view the file.
Tip: You can also navigate files with Ctrl+j (next) and Ctrl+k (previous) and view the file with Ctrl+o.
Tip: You can also navigate files with Alt+j (next) and Alt+k (previous) and view the file with Alt+o.