A more generic solution is to use functors:
module type Foldable = sig
type 'a t
val fold : 'a t -> init:'b -> f:('b -> 'a -> 'b) -> 'b
end
module MakeSum(Container : Foldable) = struct
let sum xs = Container.fold ~f:(+.) ~init:0.0
end
As you may noticed this extra parametricity comes with significant syntactic overhead. Indeed, we can reuse interfaces from Core
to reduce it:
module MakeSum(Container : Container.T) = struct
let sum xs = Container.fold ~f:(+.) ~init:0.0
end
or
module MakeSum(Container : Container.S1) = struct
let sum xs = Container.fold ~f:(+.) ~init:0.0
end
Also, as an example, you maybe mostly interested not in parametrizing over container types, but over the summation operation and zero value. This particular example is implemented using first class functors (another option) in OCaml Core library, and every container implements this function:
(** Returns the sum of [f i] for i in the container *)
val sum
: (module Commutative_group.S with type t = 'sum)
-> t -> f:(elt -> 'sum) -> 'sum
Update
Indeed, at your particular case we can generalize even without functors, since you do not need to know type in order to implement your code. So we can just define generic sum
as:
let sum fold xs = fold ~f:(+.) ~init:0.0