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 cThis 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
Geometryinterface withareaandperimmethods.We create
RectandCirclerecord types to represent rectangles and circles.We implement the
Geometryinterface for bothRectandCircleusing theimplementationkeyword.The
measurefunction takes any type that implementsGeometryand prints its area and perimeter.In the
mainfunction, we create instances ofRectandCircleand callmeasureon 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.41592653589793This 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.