Interfaces in Idris
module Main
import System.REPL
-- Here's a basic interface for geometric shapes.
interface Geometry a where
area : a -> Double
perim : a -> Double
-- For our example we'll implement this interface on
-- 'Rect' and 'Circle' types.
record Rect where
constructor MkRect
width, height : Double
record Circle where
constructor MkCircle
radius : Double
-- To implement an interface in Idris, we need to create
-- instances for our types. Here we implement 'Geometry' on 'Rect'.
implementation Geometry Rect where
area r = r.width * r.height
perim r = 2 * r.width + 2 * r.height
-- The implementation for 'Circle'.
implementation Geometry Circle where
area c = pi * c.radius * c.radius
perim c = 2 * pi * c.radius
-- If a function takes an interface type as an argument, then we can call
-- methods that are in the named interface. Here's a
-- generic 'measure' function taking advantage of this
-- to work on any 'Geometry'.
measure : Geometry a => a -> IO ()
measure g = do
putStrLn $ "Area: " ++ show (area g)
putStrLn $ "Perimeter: " ++ show (perim g)
main : IO ()
main = do
let r = MkRect 3 4
let c = MkCircle 5
-- The 'Circle' and 'Rect' types both
-- implement the 'Geometry' interface so we can use
-- instances of these types as arguments to 'measure'.
measure r
measure c
This Idris code demonstrates the concept of interfaces, which are similar to type classes in Idris. Here’s a breakdown of the translation:
We define a
Geometry
interface witharea
andperim
methods.We create
Rect
andCircle
record types to represent rectangles and circles.We implement the
Geometry
interface for bothRect
andCircle
using theimplementation
keyword.The
measure
function takes any type that implementsGeometry
and prints its area and perimeter.In the
main
function, we create instances ofRect
andCircle
and callmeasure
on both of them.
To run this program, you would typically save it in a file with a .idr
extension (e.g., geometry.idr
) and then use the Idris compiler:
$ idris geometry.idr -o geometry
$ ./geometry
Area: 12.0
Perimeter: 14.0
Area: 78.53981633974483
Perimeter: 31.41592653589793
This example showcases how Idris handles interfaces (type classes) and how they can be used to create generic functions that work with multiple types. The concept is similar to interfaces in other languages, but Idris’s approach is more closely related to Haskell’s type classes.