Data Types
So far we have used simple data types, like Int and Bool, or data types that I have supplied, like Language or Image. It is time that we look at how we can define our own complex data types.
Suppose we wish to create a data type to represent geometric shapes such that users of this data type will be able to create instances of these shapes and compute their areas. Our first task will be to create this data type to represent different types of shapes. Let us start with a rectangle and ellipse shape from which we can then form squares and circles.
We can define such a data type as follows:
data Shape = Rectangle Side Side
| Ellipse Radius Radius
deriving Showtype Radius = Float
type Side = Float
This says that a Shape can be either a Rectangle, where two sides are given as parameters, or an Ellipse where two radius values are provided. We then use type synonyms to specify that the Side and Radius types are each Floats. The specification "deriving Show" is just a way to let Haskell be able to print out values of this type.
If we want to create a rectangle, r1, with one side of length 2.0 and another of length 3.5 we would use:
r1= Rectangle 2.0 3.5
We can also write specific constructors for creating squares and circles:
square s = Rectangle s s
circle r = Ellipse r r
We now want a selector which will compute the area of a shape object. We define the function area for its behavior on each of the Shape constructors:
area :: Shape -> Float
area (Rectangle s1 s2) = s1*s2
area (Ellipse r1 r2) = pi*r1*r2
We could find the area of our rectangle r1:
area r1
Haskell would then figure out which case for the area function would need to be applied by using a built-in pattern matching mechanism on its argument to see whether it is a rectangle or an ellipse.