Welcome back to another episode of Functional Scala!

This one is the continuation of the last episode, where we introduced algebraic datatypes. Within this installment we’ll broaden the scope and find a more general definition for algebraic datatypes. Of course we don’t stop with definitions. Since we wanna write code (that’s Scala for, isn’t it?), we’ll see how to implement those *extended *new forms of algebraic datatypes (we’re going to meet today) within Scala!

Well, for a short recapitulation – and even better, serving as a smooth transition base to our current point of interest – let’s define a final enumerated data type, tagging again some of the main characteristics of an algebraic datatype. This time, imagine we need to define a new type *Color*. As with all algebraic datatypes we also need to define the values (the domain, if you like) of that type by defining a bunch of so called value constructors. Nothing easier than that, so let’s do it:

sealed abstract class Color case object Red extends Color case object Green extends Color case object Blue extends Color

Aaahhh, our new type *Color *consists of three values *Red*, *Green *and *Blue*. Those are mapped to singleton objects (serving as the underlying value constructors), since every value is a unique instance of the type. And just for the records, we can therefore see that *Color *is a so called *sum type*, since all values of that type are clearly expressed by the sum of all value constructors.

Well, ok. Is there perhaps some annoyance that might bother you about *Color*? If not, than your world must really look kind of funny, since there are apparently only three colors within. Of course there are some more colors in the world, but enumerating them all might be a bit to cumbersome! But if you pick the right fortune cookie, you might get hit to another color model, which is called additive color model or just RGB color modell (which is the most prominent representative of an additive color model). I won’t go into the details of that color model, since i guess that you’ve already heard of’em.

Now, how do we go and represent that model as an algebraic datatype, say type *RGBColor*? Again, enumerating all possible combinations of intensity for all components (that are the primary colors red, green and blue) of a certain color would take us some little amount of time! In that case, we simply extend the idea of an algebraic datatype by allowing to combine existing data types: every value constructor of a certain datatype (like our new type *RGBColor *we’re going to define now) might carry (or nest) some values of some other datatypes. In our case, there might be three *nested *values of type *Int*, each one representing the intensity for one of the primary colors:

sealed abstract class RGBColor case class RGB( red :Int, green :Int, blue :Int ) extends RGBColor

For this to work, a value constructor need to be defined in a more generic way. We can’t no longer define some singleton objects, since they only would represent one single value of a type each. Instead we defined our value constructor *RGB *as a case *class*, allowing to produce an arbitrary amount of color values by giving some concrete values for the nested intensity fields:

val black = RGB( 0, 0, 0 ) val white = RGB( 255, 255, 255 ) val red = RGB( 255, 0, 0 ) val hotPink = RGB( 255, 105, 180 ) val purple = RGB( 160, 32, 240 ) ...

Aaahh, oohh, that looks pretty much the same like *normal *object instantiation in an object oriented way. And in fact it is, since Scala provides a blendet world which tries to fuse both paradigms (now go and count how many times i’ve already said that and win a … magic number). And since we’re working with ordinary classes and require only one class for the one and only value constructor *RGB*, we could cheat in our OO-functional world and use exactly that class as a type *and *produce some instances of that type, too. In this case, we could get rid of the abstract base class:

sealed case class RGBColor( red :Int, green :Int, blue :Int )

Ok, that was nice and simple! Pretty much like working with *normal *classes in an OO world! Yep, that’s true. But there’s one big difference here! While *normal *(OO) classes typically also hold some behaviour (which may execute on the given fields), an algebraic datatype is – guess what – a pure data type. An algebraic datatype only *wraps* some values from other datatypes in some or all of its value constructors, but the value constructor doesn’t execute on that values (it simply *holds *that values, if you will). And as we said before, those wrapped values can be unwrapped and operated on by using a very powerful mechanism called pattern matching, which enables us to *deconstruct *a value constructor (the next big thing, we’re looking at).

Now that we’ve seen *RGBColor*, we also encountered what’s called a *product type*. In that case, we can’t sum up every single value of the given type, simply by enumerating value constructors (while each value constructor’s representing a single value). This time, all values of that type are expressed as the ‘product’ of all different combinations for those three intensity fields within the parameter list of our value constructor! So the constructors parameters can be seen as the single factors of that product.

### Summary

Up to now, we’ve only seen some examples for sum types (*Bool*, *Season*, *Color*) and a product type (*RGBColor*) in it’s purest form each. While a sum type will provide an individual value constructor for each and every value of that type (in its purest form), a product type will offer a value constructor which will stand for a potential set of different values. The potential set of values, which can be constructed is only limited by the combination of possible values for all fields (or constructor parameters) of that value constructor (you can see it as a kind of cartesian product).

We saw that a pure sum type was rather inappropriate for type *Color*, therefore we transformed it into a pure product type *RGBColor*. Within that transformation, we switched from case objects (which represents a separate value constructor for a single value of a given type) to case classes (which represents a whole bulk of potential values), offering some constructor parameters for those individual intensity values for the underlying primary colors (based on the underlying additive color model).

Of course there are also some hybrid types possible. There, we speak of algebraic datatypes which feature more than one value constructor (sum), while some (or all) of those available value constructors may offer some fields (constructor parameters) for some other datatypes to wrap (product). In fact, the vast majority of algebraic datatypes are expressed as hybrid types and that’s why algebraic datatypes are often described as ‘sum of products types’ (hence algebraic). Those hybrid types will be the main topic for the next episode! So stay tuned …

February 5, 2011 at 7:36 pm

[…] this installment we’ll broaden the scope and find a more general definition for algebraic… [full post] Mario Gleichmann brain driven development generalscala 0 0 0 […]

February 6, 2011 at 6:37 am

[…] Functional Scala: Algebraic Datatypes – Sum and Product Types … […]

February 7, 2011 at 6:12 am

Really good writeup, extremely useful, as a newbie, couldn’t have asked for anything more!!..

February 8, 2011 at 8:35 pm

[…] datatypes! We’ve already seen some simple sum types and a pure product type in the last two episodes. However, the vast majority of algebraic datatypes constitute a combination of a sum and product […]

February 20, 2011 at 8:00 pm

[…] the last episodes, we discovered how to define so called algebraic datatypes. So far, we’ve only […]

February 27, 2011 at 11:09 pm

[…] time, we’ll finally discover how to pattern match on product types. Within the last episodes we saw how to use pattern matching on some rather simple sum types. The […]

April 19, 2011 at 2:39 pm

[…] Functional Scala: Algebraic Datatypes – Sum and Product Types […]

December 4, 2011 at 4:06 pm

[…] our main actors in that game? Sounds good? Let’s start with a simple point. All we need is an algebraic datatype which just denotes a point within our two dimensional coordinate […]

May 29, 2012 at 12:40 am

[…] to this excellent article to learn about this concept. This is how your example would probably look like when modeled this […]