Title here
Summary here
OCaml uses modules to organize code, and interfaces are implemented using modules and signatures. Here’s how we can translate the Go example to OCaml:
open Printf
(* Here's a basic interface (signature) for geometric shapes. *)
module type Geometry = sig
val area : unit -> float
val perim : unit -> float
end
(* For our example we'll implement this interface on rect and circle types. *)
module Rect = struct
type t = {width: float; height: float}
(* To implement an interface in OCaml, we just need to
implement all the functions in the signature. *)
let area {width; height} = width *. height
let perim {width; height} = 2.0 *. width +. 2.0 *. height
end
module Circle = struct
type t = {radius: float}
(* The implementation for circles. *)
let area {radius} = Float.pi *. radius *. radius
let perim {radius} = 2.0 *. Float.pi *. radius
end
(* If a module has the Geometry signature, then we can use it
with functions that expect that signature. Here's a generic
measure function taking advantage of this to work on any Geometry. *)
let measure (module G : Geometry) =
printf "Area: %f\n" (G.area ());
printf "Perimeter: %f\n" (G.perim ())
(* We can create modules that conform to the Geometry signature *)
module RectGeometry (R : sig val rect : Rect.t end) : Geometry = struct
let area () = Rect.area R.rect
let perim () = Rect.perim R.rect
end
module CircleGeometry (C : sig val circle : Circle.t end) : Geometry = struct
let area () = Circle.area C.circle
let perim () = Circle.perim C.circle
end
let () =
let r = Rect.{width = 3.0; height = 4.0} in
let c = Circle.{radius = 5.0} in
(* The Circle and Rect modules both implement the Geometry signature
so we can use instances of these modules as arguments to measure. *)
let module R = RectGeometry(struct let rect = r end) in
let module C = CircleGeometry(struct let circle = c end) in
measure (module R);
measure (module C)
To run this program, save it as interfaces.ml
and compile it with OCaml:
$ ocamlc -o interfaces interfaces.ml
$ ./interfaces
Area: 12.000000
Perimeter: 14.000000
Area: 78.539816
Perimeter: 31.415927
In this OCaml version:
Geometry
module type (signature) which is equivalent to the Go interface.Rect
and Circle
modules with their respective types and functions.measure
function that takes a module conforming to the Geometry
signature.RectGeometry
and CircleGeometry
) to create modules that implement the Geometry
signature for our Rect
and Circle
types.Rect
and Circle
, wrap them in modules that implement Geometry
, and pass these to the measure
function.This demonstrates how OCaml uses modules and signatures to achieve similar functionality to Go’s interfaces, albeit with a different syntax and approach.