Can Ocaml produce generic or generic like signatures?


#1

I noticed that it would be advantageous to have signatures(that allows the user to set a value type) in Ocaml but I’m not sure how produce such a thing. I played around a bit and arrived at the code below but it feels more like a hack than a real solution. Any comments or guidance?

module type MySig =
  sig

    type t
    type k (*nice to expose this type and set its type-value when used*)

    val createKey: k -> t
    val string_of_key: t -> string
    val compare: t -> t -> int

  end

module MyInt:(MySig with type k = int) =
  struct

    type t = int
    type k = t (*feels kind of hackish here*)

    let createKey key = key
    let string_of_key key = string_of_int key
    let compare = compare

  end

module MyStr:(MySig with type k = string) =
  struct

    type t = string
    type k = t (*feels kind of hackish here*)

    let createKey key = key
    let string_of_key key = key
    let compare = compare

  end

module MyIntMap = Map.Make(MyInt)

let myInt = 
  MyIntMap.empty
  |> MyIntMap.add (MyInt.createKey 4143) "G4143"
  |> MyIntMap.add (MyInt.createKey 8888) "me"
  |> MyIntMap.add (MyInt.createKey 7777) "you"
  |> MyIntMap.iter 
    (fun key value -> print_endline (MyInt.string_of_key key ^ "=>" ^ value))

let () = List.iter (fun _ -> print_newline()) [1;2;]

module MyStrMap = Map.Make(MyStr)

let myStr =
  MyStrMap.empty
  |> MyStrMap.add (MyStr.createKey "4143") "G4143"
  |> MyStrMap.add (MyStr.createKey "8888") "me"
  |> MyStrMap.add (MyStr.createKey "7777") "you"
  |> MyStrMap.iter 
    (fun key value -> print_endline (MyStr.string_of_key key ^ "=>" ^ value))

#2

Noticed the topic title was incorrect. It should be ‘signatures where the user can set a value type’.


#3

You can use destructive substitutions:

module MyInt:(MySig with type k := int) =
  struct

    type t = int
    (* no need for this line anymore
    type k = t (*feels kind of hackish here*) *)

    let createKey key = key
    let string_of_key key = string_of_int key
    let compare = compare

  end

Note the with type k := int, using a colon with the equal sign, which effectively replaces every occurence of k with int and removes the type declaration from the signature.

See the manual ( https://caml.inria.fr/pub/docs/manual-ocaml/extn.html#sec249 ) for more information


#4

Thanks! That’s exactly what I wanted.