Trung Ta
Trung Ta

Reputation: 1722

How to implement a module signature in OCaml with some default implementation?

I want to implement a module signature in OCaml like below, where the function get_data depends on each module implementation and return an option type. I also want to provide the function get_data_exn which is a wrapping of get_data by un-optioning the result of get_data, and throwing an exception when the result returned by get_data is None

module type Foo = sig
  type t
  val get_data : int -> t option
  val get_data_exn : int -> t
end

In essence, the implementation of the function get_data_exn will be like below, and it will be the same for all modules that implement Foo:

let get_data_exn value = match get_data value with
  | Some data -> data
  | None -> raise DataNotFound

Is this possible for me to include this implementation of get_data_exn inside the signature Foo so that I don't have to repeat it for other modules? This is something similar to abstract class in Java.

Thank you for spending time to consider my question.

Upvotes: 1

Views: 1309

Answers (1)

octachron
octachron

Reputation: 18892

You can define a core module type

module type Foo_core = sig
  type t
  val get_data: int -> t option
end

and extend it with a functor:

module Get_data_exn(Core:Foo_core) = struct
  let get_data_exn value = match Core.get_data value with
  | Some data -> data
  | None -> raise DataNotFound
end

Depending on your use case, it might be useful to expose a standard Make_foo functor

module Make_full_Foo(X:Foo_core) = struct
  include X
  include Get_data_exn(X)
end

Upvotes: 3

Related Questions