To understand ADTs, firstly, we have to understand what is the meaning of the word “**algebra**“.

Algebra

Algebra

Algebra is basically the study of mathematical symbols and the rules for manipulating these symbols. So, logically, an ** algebra** can be thought of as consisting of two things:

- A set of objects
- The operations that can be applied to those objects to create new objects

Numeric algebra

Numeric algebra

Numeric algebra is the algebra of numbers. You can think of it like this:

- A
, such as whole numbers, natural numbers, integers.**set of objects** - The
that can be used on those objects: + , – , * , / , etc.**operations**

Here, 1, 2, 3, 6 are the numbers i.e., belongs to the set of natural numbers and +, * are the operators. Now, one thing to notice here is that the *operators* are used on existing numbers (objects) to create new numbers (objects).

Relational algebra

Relational algebra

Relational algebra is the algebra of relational databases. Here,

- The database tables are the “
“**set of objects** - Query tools like SELECT, UPDATE, and JOIN are the “
” that let you create new objects from the existing objects.**operators**

Algebra in programming

Algebra in programming

We have been using algebra in FP throughout but possibly without knowing it. For example, take a look at this case class:

This code creates a new type * Coordinate* from two instances of the existing type

*. The*

**Int***class constructor*itself is an “

**operator**” that lets you create new types from existing Scala types, just like

**+**and

*****let you create new numbers from existing numbers.

**Algebraic Data Types: ADTs**

An * algebraic data type* is a kind of composite type, i.e., a type formed by combining other types. ADTs fall into three main categories

- Sum type
- Product type
- Hybrid type

The Sum type

The Sum type

Sum type enumerates all the possible instances of the type, hence it is also referred as “* enumerated type*“. Let’s understand this with a simple example

Sum types are typically created with a * sealed trait* as the base type, with instances created as

*. You use a sealed trait because you don’t want them to be extended.*

**case objects**The number of enumerated types you list is the only possible instances of the base type. In this example,

*has three possible values:*

**Gender***,*

**Male***, and*

**Female***.*

**Other****Why sealed trait?**

A great feature of using * sealed trait* is that it can only be extended in the file in which it was defined and it can’t be extended anywhere else, the compiler knows all of the subtypes of the trait that can possibly exist. Because of this, the compiler can exhaustively check the possible cases in

*expressions. This makes your programming easier, and your code clean and safe.*

**match****Why case object?**

Sum types use the * case object* as they only require

**instances. For instance, with the**

*singleton**example, it makes sense to have only one*

**Gender***instance in all of your code. There’s no need to create new*

**Male***and*

**Male***instances every time you work with*

**Female***values. Scala’s*

**Gender***gives you this singleton functionality.*

**case object**

The Product type

The Product type

Its name comes from the fact that you use the Scala * case class* constructor to create a data type whose number of possible concrete instances can be determined by multiplying the number of possibilities of all of its constructor fields.

What do you think the number of possibilities is for this class:

Infinite? That’s absolutely right. Because a String has an infinite number of possibilities, Person can have an infinite number of concrete instances.

Few important points about the Product type:

- Writing
and defining the constructor parameters is essentially the “**case class****product**” operator. - The number of possible values of a
type is the product of all possible combinations of the constructor parameters (i.e., a**Product**).**Cartesian product**

Hybrid types

Hybrid types

The Sum and Product types are the two base ADTs; all other ADTs are hybrids created from those base types. So there is no particular base hybrid type, but one popular hybrid type is known as the “* Sum of Products*” type.

These types represent a Sum type because **Parallelogram***is a* Square *or *Rectangle. * Square* is a Product type because it

*has a*

*and*

**side***is also a Product type because it has a*

**Rectangle***and a*

**length***.*

**height*** Sum* and

*types can be combined in many ways to form*

**Product***type to solve the problem at hand.*

**Hybrid**

Pattern Matching using Algebraic Data Type

Pattern Matching using Algebraic Data Type

A great benefit of ADTs is that they simplify and encourage the use of pattern matching in your code.

We can easily write an **isSquare** function using pattern matching:

**Conclusion**

- If you create your data models using (a)
with immutable fields, (b)**case classes**you’re already writing ADTs (probably without knowing).**case objects** - ADTs are the way of categorizing the code not designing the code.
- The two main types of ADTs are the Sum type and Product type. Other hybrid ADTs are derived from these base types.
- ADTs encourage a pattern-matching style of programming.

**References: **

Functional Programming Simplified by Alvin Alexander