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
GEOMETRY
signature that specifies the interface for geometric shapes. It includesarea
andperim
functions.We create
Rect
andCircle
structures that implement theGEOMETRY
signature. Each structure has its own internal state (width and height for rectangles, radius for circles) and implements the required functions.The
measure
function takes aGEOMETRY
module and calls itsarea
andperim
functions, printing the results.In the
main
function, we initialize a rectangle and a circle, then callmeasure
on each of them.
To run this program:
$ sml geometry.sml
Rectangle:
Area: 12.0
Perimeter: 14.0
Circle:
Area: 78.53981633974483
Perimeter: 31.41592653589793
This 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.