Exploring ReasonML

  1. Definition

function that takes one or more modules as input and returns a new module

/* Repetition.re */
module type Count = {
  let count: int;
};

/* Repetition.re */
module type S = {
  let repeat: (~times: int=? , string) => string; }; module Make = (RC: Count): S => {let rec repeat = (~times=RC.count, str: string) =>
    if (times< = 0) {"";
    } else {
      str ++ repeat(~times=times-1, str);
    };
};
Copy the code
  1. Functors for data structures
  • The parameters of the functor specify the elements managed by the data structure. Due to the parameters being modules, you can not only specify the types of the elements, but also helper functions that the data structure may need for managing them.

  • The result of the functor is a module that is tailor-made for the specified elements.

module type PrintableType = {
  type t;
  let print: t => string;
};

module type S = {
  type fst;
  type snd;
  type t;
  let make: (fst, snd) => t;
  let print: (t) => string;
};

module Make = (Fst: PrintableType, Snd: PrintableType)
: (S with type fst = Fst.t and type snd = Snd.t) => {
  type fst = Fst.t;
  type snd = Snd.t;
  type t = (fst, snd);
  let make = (f: fst, s: snd) => (f, s);
  let print = ((f, s): t) =>
    "(" ++ Fst.print(f) ++ "," ++ Snd.print(s) ++ ")";
};

/* abbreviation */
module Make = (Fst: PrintableType, Snd: PrintableType)
: (S with type fst := Fst.t and type snd := Snd.t) => {
  type t = (Fst.t, Snd.t);
  let make = (fst: Fst.t, snd: Snd.t) => (fst, snd);
  let print = ((fst, snd): t) =>
    "(" ++ Fst.print(fst) ++ "," ++ Snd.print(snd) ++ ")";
};
Copy the code