Interfaces in Standard ML
Standard ML (SML) doesn’t have a direct equivalent to interfaces, but we can use modules and signatures to achieve similar functionality. Here’s how we can implement the geometry example in SML:
(* Basic signature for geometric shapes *)
signature GEOMETRY = sig
val area : unit -> real
val perim : unit -> real
end
(* Implementation for rectangles *)
structure Rect :> GEOMETRY = struct
val width = ref 0.0
val height = ref 0.0
fun area () = !width * !height
fun perim () = 2.0 * !width + 2.0 * !height
fun init (w: real, h: real) =
(width := w; height := h)
end
(* Implementation for circles *)
structure Circle :> GEOMETRY = struct
val radius = ref 0.0
fun area () = Math.pi * !radius * !radius
fun perim () = 2.0 * Math.pi * !radius
fun init (r: real) = radius := r
end
(* Generic measure function *)
fun measure (geom: GEOMETRY) =
let
val area = geom.area()
val perim = geom.perim()
in
(print ("Area: " ^ Real.toString area ^ "\n");
print ("Perimeter: " ^ Real.toString perim ^ "\n"))
end
(* Main function *)
fun main () =
(Rect.init(3.0, 4.0);
Circle.init(5.0);
print "Rectangle:\n";
measure Rect;
print "\nCircle:\n";
measure Circle)
(* Run the main function *)
val _ = main()In this SML implementation:
We define a
GEOMETRYsignature that specifies the interface for geometric shapes. It includesareaandperimfunctions.We create
RectandCirclestructures that implement theGEOMETRYsignature. Each structure has its own internal state (width and height for rectangles, radius for circles) and implements the required functions.The
measurefunction takes aGEOMETRYmodule and calls itsareaandperimfunctions, printing the results.In the
mainfunction, we initialize a rectangle and a circle, then callmeasureon each of them.
To run this program:
$ sml geometry.sml
Rectangle:
Area: 12.0
Perimeter: 14.0
Circle:
Area: 78.53981633974483
Perimeter: 31.41592653589793This implementation showcases how SML’s module system can be used to create abstractions similar to interfaces in other languages. The GEOMETRY signature defines a contract that both Rect and Circle structures adhere to, allowing us to write generic functions like measure that can work with any structure implementing the GEOMETRY signature.