kuniga.me > NP-Incompleteness > Haskell – Algebraic Data Types
25 Sep 2011
Haskell uses an elegant syntax to represent a type of data structure, analogous to many other structures present in languages such as C and C++. These structures are called algebraic data types.
This is the second post about my studies in Haskell. The first can be found here.
This post makes analogies with some basic C++ features but prior knowledge is not required.
Consider the following C++ struct
representing a book through its code, title and authors:
In haskell we can write:
To define this structure, start with the keyword data
and give a name to this new type, in this case BookInfo
, called the type constructor.
In addition, we define a constructor of this type, which in the example is named Book
, called a value constructor or data constructor, but could have the same name as the type. Both the constructor name and the type name must be capitalized.
The deriving (Show)
line is being used in this and other examples in this post so that an instance of this structure can be printed to the terminal. We can instantiate the structure BookInfo
as follows:
Note that the input parameters must be in the same order as they are defined in the structure. Also note that the “members” of this structure are implicit, being represented only by their type.
To improve readability a bit, it is possible to use type synonyms, through the keyword type
(similar to the typedef
C++).
Another C++ structure that can be represented succinctly in Haskell is the enumation structure. Consider an enum
representing RGB colors:
An algebraic data type admits more than one constructor, as long as they have different names. Also, constructors don’t need to have parameters, which allows you to write the enum abovelike this:
Still taking advantage of the fact that we can have several constructors with different parameters, we can also represent a union. Consider the following C++ example of a union representing two geometric shapes – a circle or a polygon:
In Haskell, you can do the following:
When working with classes, we occasionally want to protect read/write access to their members using getters and setters, for example:
There is a similar mechanism in Haskell, implemented by the so-called record syntax. In an analogous example to the previous one:
This more verbose syntax allows you to instantiate the structure by assigning the parameters to the members explicitly like:
The getter member is given by:
While setter would correspond to:
Types of algebraic data also represent other functionality present in C ++: templates. Let’s take as an example a class representing a generic pointer to any type:
By instantiating this class we can define the types we want to represent:
Here we have pointers for types int and double, where NULL
is a generic value to say that the pointer doesn’t point anywhere.
A (forced) analogy in Haskell would be as follows:
Although in Haskell we don’t have the value NULL
, we can simulate it through a constructor as in the example above. This encapsulation is particularly interesting for providing an exception condition. For example, consider a function that returns the first element of a list:
What to return if the list is empty? One solution would be to use encapsulation:
In the example, the character _
works as a wildcard, that is, any parameter matches it. As it was put after the other pattern, it behaves like an else
and will only be called when the list has no elements.
Another application of an algebraic data types is to define recursive types, that is, members of the structure are of the type of that structure. In C and C++ it is possible to do this using pointers. For example, we can implement a linked list of generic elements as follows:
In Haskell we have something like:
To represent a linked list containing 3, 1 and 2, in that order, we use the following syntax:
A binary tree is also quite simple to represent:
Haskell has a succinct syntax for describing algebraic data types, which in turn are quite versatile, being able to represent both structures and unions, enumerations, classes, etc.
I still know very little about the language, but for now I’m finding it quite interesting.