Interfaces in Elm
In Elm, we don’t have the concept of interfaces as in Go. Instead, we use type aliases and custom types to define common structures. We’ll implement a similar concept using custom types and type aliases.
First, let’s define our basic structure for geometric shapes:
type alias Geometry =
{ area : Float
, perimeter : Float
}
type Shape
= Rectangle Float Float
| Circle Float
Now, let’s implement functions to calculate area and perimeter for each shape:
calculateRectangle : Float -> Float -> Geometry
calculateRectangle width height =
{ area = width * height
, perimeter = 2 * (width + height)
}
calculateCircle : Float -> Geometry
calculateCircle radius =
{ area = pi * radius * radius
, perimeter = 2 * pi * radius
}
We can create a function to measure any shape:
measure : Shape -> Geometry
measure shape =
case shape of
Rectangle width height ->
calculateRectangle width height
Circle radius ->
calculateCircle radius
Now, let’s put it all together in a main function:
import Html exposing (Html, div, text)
main : Html msg
main =
let
rect = Rectangle 3 4
circle = Circle 5
measureAndFormat : Shape -> String
measureAndFormat shape =
let
geometry = measure shape
in
String.join "\n"
[ Debug.toString shape
, "Area: " ++ String.fromFloat geometry.area
, "Perimeter: " ++ String.fromFloat geometry.perimeter
, ""
]
in
div []
[ text (measureAndFormat rect)
, text (measureAndFormat circle)
]
To run this Elm program, you would typically compile it to JavaScript and run it in a web browser. Here’s what the output might look like:
Rectangle 3 4
Area: 12
Perimeter: 14
Circle 5
Area: 78.53981633974483
Perimeter: 31.41592653589793
In this Elm version, we’ve implemented a similar concept to Go’s interfaces using custom types and type aliases. The Shape
type represents different geometric shapes, and the Geometry
type alias defines the structure for area and perimeter calculations. The measure
function acts similarly to the measure
function in the Go example, working with any Shape
.
Elm’s type system and pattern matching allow us to achieve a similar level of polymorphism as Go’s interfaces, but in a more functional programming style.