Custom Data Types

  • In order to create a custom data type, we use the data keyword.
  • For instance, the Bool type is defined in the standard library in this way:
data Bool = False | True

data means we are defining a new data type.

  • The parts after the = are value constructors. They specify the different values that this type can have.
  • The | symbol is interpreted as "or". Therefore, we can say that the Bool type can have a value of either True or False. Both the type name and its value constructors must be capitalized.

  • Now, let us consider how we could represent a shape in Haskell.

  • One approach is to use tuples. For example, a circle could be represented as (53.1, 30.0, 12.8) where the first two values are the coordinates of the circle's center, and the third is the radius.

  • While this works, those values could just as easily represent a 3D vector or something else entirely.

  • A more effective solution would be to define our own type to represent a shape. Let us say a shape can be either a circle or a square. Here's how:

data Shape = Circle Float Float Float | Square Float
  • The Circle value constructor has three fields, all of which are floats. Here, the first two fields represent the coordinates at its center, the third one its radius.
  • The Square value constructor has only one field (which accepts a float) that represents the side of the square.

  • Let us now make a function that, given a shape, returns its area.
area :: Shape -> Float
area (Circle _ _ r) = pi * r ^ 2
area (Square s) = s * s

Usage:

area (Circle 15 20 10)
-> 314.15927
area $ Circle 15 20 10
-> 314.15927
area $ Square 6
-> 36.0

  • Now, if we try to just print out Circle 15 10 5 in the prompt, we'll get an error.
  • This is because Haskell does not know yet how to display our data type as a string.
  • To fix this, simply change the type declaration to:
data Shape = Circle Float Float Float | Square Float
    deriving (Show)

And now:

Circle 15 10 5
-> Circle 15.0 10.0 5.0
Square 8
-> Square 8.0
map (Circle 5 10) [2, 3, 4, 4]
[Circle 5.0 10.0 2.0, Circle 5.0 10.0 3.0, Circle 5.0 10.0 4.0, Circle 5.0 10.0 4.0]

In the following lecture we will create a new data type and see how we can make it an instance of the Eq typeclass.