Interfaces in PureScript
module Main where
import Prelude
import Effect (Effect)
import Effect.Console (log)
import Math (pi)
-- Here's a basic interface for geometric shapes.
class Geometry a where
area :: a -> Number
perim :: a -> Number
-- For our example we'll implement this interface on
-- `Rect` and `Circle` types.
data Rect = Rect { width :: Number, height :: Number }
data Circle = Circle { radius :: Number }
-- To implement an interface in PureScript, we need to create
-- an instance of the typeclass for our types.
-- Here we implement `Geometry` for `Rect`.
instance geometryRect :: Geometry Rect where
area (Rect r) = r.width * r.height
perim (Rect r) = 2.0 * r.width + 2.0 * r.height
-- The implementation for `Circle`.
instance geometryCircle :: Geometry Circle where
area (Circle c) = pi * c.radius * c.radius
perim (Circle c) = 2.0 * pi * c.radius
-- If a function takes a typeclass constraint, then we can call
-- methods that are in the named typeclass. Here's a
-- generic `measure` function taking advantage of this
-- to work on any `Geometry`.
measure :: forall a. Geometry a => a -> Effect Unit
measure g = do
log $ show g
log $ show $ area g
log $ show $ perim g
main :: Effect Unit
main = do
let r = Rect { width: 3.0, height: 4.0 }
let c = Circle { radius: 5.0 }
-- The `Circle` and `Rect` types both
-- implement the `Geometry` typeclass so we can use
-- instances of these types as arguments to `measure`.
measure r
measure c
In PureScript, we use typeclasses to achieve a similar functionality to Go’s interfaces. The Geometry
typeclass defines the methods area
and perim
, which are then implemented for the Rect
and Circle
types.
The measure
function takes a type constraint Geometry a =>
, which allows it to work with any type that implements the Geometry
typeclass.
To run this program, you would typically compile it with the PureScript compiler and then run it with Node.js:
$ pulp build
$ node output/Main.js
(Rect { width: 3.0, height: 4.0 })
12.0
14.0
(Circle { radius: 5.0 })
78.53981633974483
31.41592653589793
This example demonstrates how PureScript uses typeclasses to achieve polymorphism, similar to how interfaces are used in other languages. The typeclass system in PureScript is more powerful and flexible than traditional interfaces, allowing for features like multiple parameter typeclasses and functional dependencies.