As said some time before, we’ve by far not reached the end when it comes to all those basic concepts of functional programming. One of the most powerful ideas we’ve discovered so far, was that of so called higher order functions. Since functions can be treated as values (like Numbers or Strings), we can pass them as ordinary arguments to some other functions. You may remember our function *filter*, which not only takes a list of elements to be filtered, but also a function (a so called predicate function, resulting into a boolean value) which decides for every list element to be in the filtered list or not.

In this episode, we’ll see that we’re not only restricted to accept another function as an argument but could also come up with some sensible functions which may return another function as their result. Again, this is nothing special if you look at a function as an ordinary value which can be passed around like any other value of any other type. While on that road, we’ll naturally discover how that idea is closely related to what’s called *function currying*. So hold on, you’ll see what’s that all about in the next minutes …

Let’s pretend we wanna write a ‘Game of sight’. Within that game, it’s critical to detect if a certain object is within a certain area so that it’s visible or just not (hence invisible). To keep things easy, let’s play that game on a two dimensional area which can be described using a cartesian coordinate system. Further, let’s use a circle (described as a center with a radius) and a simple point on that coordinate system and try to calculate if that point (as a representative for the position of an object) is within that circle (hence visible from the center of that circle) or just outside of that circle (hence invisible from the center of that circle).

First, what about defining 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 system:

case class Point( val x :Int, val y :Int )

As you’ve might seen, we’ve annotated our constructor parameters with *val*, making absolutely clear that a point is an immutable value (hence, we can’t mutate a given point, but only deriving new points from existing points, e.g. for moving the position of an object). From here, it’s just a very short jump to come up with the definition of a circle. It’s just a point to depict the center of that circle and a certain radius. That’s all for describing a full featured circle in our game world:

case class Circle( val center :Point, val radius :Int )

Before we get down to our initial question, what about some small functions in order to warm up? Let’s say we wanna completely exclude the use of Scala’s object oriented features and hence don’t wanna call a* Circles* getter methods in order to retrieve its center or radius. Hugh? But how we’re supposed to get those fields then? Well, we could leverage Pattern Matching in order to retrieve a circles components. Observe:

val radius : Circle => Int = circle => { val Circle( center , radius ) = circle radius }

What we have here is a so called *selector* function. In fact, you could see the *constructor* as a function which takes some arguments and creates a new value of the given type. Then, a *selector* is nothing else than another function which takes such a constructed value and picks a certain component from *within* that value. In our case, we did that with a certain form of pattern matching: we just introduced a new value by revealing all its components with a name (*center and radius*). Those are then bound to the actual values of the given circle. In fact, we could’ve make use of our famous underscore for the first component, since we’re only interested in the radius here.

With that knowledge on board, it’s rather easy to come up with a selector function for the center of a circle:

val center: Circle => Int = circle => { val Circle( center , _ ) = circle center }

Given those two key players and our two selectors, we only need to come up with an idea on how to detect if a certain point is within the area of a certain circle. There’s a simple solution, thanks to the genius of Pythagoras …

It turns out, that the Pythagorean theorem is a perfect model for calculating the distance of two points (with the center of our circle as the one and the point in question as the other point) in a cartesian coordinate system (what a fortunate coincidence, since our game’s based on such). If the distance is shorter than the radius of our circle, then the point in question is clearly within the circle (otherwise not).

As you can see from the picture, we simply need to calculate the difference of our two points both x-coordinates and the same with both y-coordinates to come up with the length for the adjacent and the opposite leg (with the distance between our two points as the hypotenuse then). Then the only thing left to do is to solve the famous equation *a² + b² = c²*. If the point in question is within the circle (or on the circles edge), then a² + b² need to be smaller or equals than *radius²*.

Let’s pour our hard earned knowledge into a Function:

val isWithin : ( Circle, Point ) => Boolean = ( circle, point ) => { val Point(a, b) = center( circle ) val Point(x, y) = point pow( x-a, 2 ) + pow( y-b, 2 ) <= pow( radius( circle ), 2 ) }

Aaahh, a neat function which takes two arguments – a circle and a point, resulting into a Boolean value which indicates if the given point lies within the circles area. Again we’re leveraging pattern matching to reveal the x- and y-coordinates of the given center and point. We then simply utilize our knowledge about Phytagoras for the final answer.

With our new function at hand, let’s just try some scenarios:

val observerView = Circle( Point( 2, 2 ), 3 ) val observesFirstPoint = isWithin( observerView, Point( 3, 4 ) // => true val observesSecondPoint = isWithin( observerView, Point( 2, 2 ) // => true val observesThirdPoint = isWithin( observerView, Point( 6, 6 ) // => false val observesFourthPoint = isWithin( observerView, Point( 8, 2 ) // => false

Wow, our function seems to work … but at what price?

If you take a closer look at our scenario, there might be a little annoyance which comes into mind. We always want to know if different objects (points) become visible to always the one and same observer (circle). So we always need to pass the same circle to our function, over and over again. Even worse, since our function does not *know*, that we’re always passing the same circle, it also calculates the quadratic power of the circles radius over and over again, which might be a waste of resources.

Can we do better? Yes we can! What if we could say ‘here’s a (fixed) circle. Now provide me a function which always calculates if an arbitrary point is within the area of that (fixed) circle’ ? As a little hint, think about our *bronze bullet* – those higher order functions. I bet your bell’s already ringing, right? What we need is a *function maker*, a function which produces (and returns) another function! Hey, and as we know that functions are nothing special or better than values of other types, let’s do it:

val isWithin : Circle => ( Point => Boolean ) = circle => { val radSquare = pow( radius( circle ), 2 ) val Point(a, b) = center( circle ) point => { val Point(x, y) = point pow( x-a, 2 ) + pow( y-b, 2 ) <= radSquare } }

Oh boy, not so fast! Let’s anatomize what we have here and strip it down to its single pieces! The first interesting element is the type signature, given at line 1. The type says that we have a function which just takes a single circle (before the first function arrow) and results into something we’ll inspect in a moment (all within that round brackets after the first function arrow). So we have clearly a function in front. Now take a closer look at the type of the functions result (all inside that round brackets). But look, it must be again a function, taking a single Point and resulting into a boolean value! Clearly, the whole construction must be our function maker!

Let’s inspect how it’s going to produce that function. We can detect it as the last expression (which also becomes the return value in Scala automatically) within the body of our function maker, beginning at line 8 upto line 13. This function only takes a single point and then starts our well known calculation. An instance (value) of that function is created whenever our function maker is called with a certain circle. And since this ad hoc created, resulting function is anonymous (look, it even lacks a name) it must be a … tataaa … lambda expression!

But wait, where come those values like *x*, *y* or even *radSquare*? Since those values aren’t defined as arguments of our resulting function, we have some free variables which only got bound by closing over into the lexical scope where the function is created (that is the body of our function maker, were we’ve calculated the square of the circles radius only once). So the delivered function must be a … tataaa … closure!

Now let’s look how we could bring our function maker into use:

val observerView = Circle( Point( 2, 2 ), 3 ) val observes : Point => Boolean = isWithin( observerView ) val observesFirstPoint = observes( Point( 3, 4 ) ) val observesSecondPoint = observes( Point( 2, 2 ) ) val observesThirdPoint = observes( Point( 6, 6 ) ) val observesFourthPoint = observes( Point( 8, 2 ) )

Please direct your attention to line 3, where we just called our function maker *isWithin* which returns another function *observes* which in turn can be used further on to test if all those arbitrary points lie in the area of the predefined circle (which is kind of fixed within the resulting function *observes*)! Of course we could still use our function maker and the resulting function in one go:

val firstObserverView = Circle( Point( 2, 2 ), 3 ) val obervedByFirst = isWithin( firstObserverView )( Point( 3, 4 ) ) ... val secondObserverView = Circle( Point( 17, 21 ), 5 ) val obervedBySecond = isWithin( secondObserverView )( Point( 23, 17 ) )

So if we want to use our new construction just once for different circles, we can just apply that circle to our function maker, which in turn results into our function for doing the final calculation, which in turn is immediately applied to the given point. Since we do two function calls in a row, we provide those two arguments (one for each function) within two different argument lists.

Now, look where we’ve come from. We started with a function, taking two arguments, resulting into a boolean value:

( Circle , Point ) => Boolean

We then massaged that function into another function which we called a function maker. Now if you look at the type of that higher order function, you’ll see that they are not so different from each other:

Circle => Point => Boolean

I’ve omitted the round brackets – they’re not needed since our function arrow is right associative (of course you can always keep the brackets for your own clarity). So if we look at the players of both types, they’re the same! Further, given the same circle and point, the final result also remains the same, no matter if you call the first or second version. We’ve only *translated* the first version which takes two arguments (a circle and a point) into a version which is taking a single argument (a circle), resulting into another function which in turn takes a single argument (a point), resulting into a boolean.

We could generalize this idea, taking any function with an arbitrary number of arguments and translate it into a function which just takes the first argument, resulting into a function which just takes the second argument, resulting into another function which just takes the third argument, which … (you get the idea) … resulting into the final result.

This transformation process is well known in the functional world where it deserves its own name. It’s called ‘*Currying*‘ (according to the name of *Haskell Brooks Curry*, a famous mathematician and logician). The result of *currying* a given function is then called a *curried function*. In fact, this kind of transformation could be done in a pure mechanical way. Let’s try to define a function *curry*, which takes a function of two arguments and returning a curried version of it:

def curry[A,B,C]( func : (A, B) => C ) : A => B => C = a => b => func( a, b )

Wow, let’s take a closer look at it. First of all, we need to fall back to a method definition (starting with a *def*), since Scala doesn’t support polymorphic functions: because we wanna preserve the given arguments and return types of the function to curry, we need to introduce those types as type parameters. Now look at the argument *func* of method *curry*: it’s a function, taking two arguments (of type *A* and *B*) resulting into a value of type *C*. The curried version of such a function would be a function taking a single argument of type *A*, resulting into another function which in turn accepts a single argument of type *B*, finally resulting into a value of type *C*. But look at the return type of our *curry* method – it’s exactly of that type – hurray! In fact, the method body can’t do anything other than what the return type already predicts …

Now we could use our new function *curry* in order to apply it to our inital version of *isWithin* …

val isWithin : ( Circle, Point ) => Boolean = ... val curriedIsWithin : Circle => Point => Boolean = curry( isWithin )

So this kind of mechanical currying is surely a no brainer. It’s so no brained, that it’s of course already provided within the interface of Scala’s *FunctionN* types:

val isWithin : ( Circle, Point ) => Boolean = ... val curriedIsWithin : Circle => Point => Boolean = isWithin.curried

You’ve surely already noticed, that this kind of mechanical currying is only able to solve the problem of not handing a circle (as the first argument) to our function over and over again. It simply pulls the arguments apart, providing a chain of nested function makers which only take one single argument each. Of course it can’t provide any optimization, e.g. calculating the square of the circles radius only once, serving as a value to close over.

Within this episode, we transformed a given function by hand: we took a function with more than one argument and massaged it into a function (we called it a function maker) which always took a single argument at a time, resulting into another function until there’s no argument left, resulting into the final result. Again, we saw that functions are nothing better than ordinary values which can be produced and returned by other (then higher order) functions.

We also saw that this kind of transformation can also be done in a more mechanical way, but then lacking some more intelligent separation strategies like optimization of resource usage. Either way, that transformation process is so prominent in the functional world, that it’s marked with an own name: *Currying*. We’ll see some more interesting usage scenarios of Currying and its result – curried functions – in some future episodes.

So far we only used Currying on functions. But what about methods? Is there a similar way to produce some kind of *curried methods* where we could provide only one (or some) arguments at a time? And if so, can we also apply some optimization strategies like we did with our function *isWithin* or use a function *curry* to transform a method into a curried one? If you’re eager to know, that’s good! We’ll solve all those questions in the next episode. Would be glad to see you again …

Side Note

The idea of transforming a function with multiple arguments into a curried one was not invented by Haskell Curry. Curry was only the one which popularized the idea in the field of combinatory logic. The initial idea came from a russian mathematician of name Moses Schönfinkel. So whenever to use *Currying*, we should not forget about Moses! At least, i guess not calling the process after him, is that *Schönfinkeling* doesn’t sound that good …

First of all, there isn’t any ‘Java Joe’ (as a synonym for all those so called ‘dumb’ Programmers) out there. Well ok, if it is, then i’m the ideal protoype of that Joe! And as such i can tell you, if you’re willing to learn some new ideas and try to improve your programming skills, than Scala may provide you with a bunch of whole new concepts, not only from the functional world (and i’m not even talking about type systems here).

In fact, i don’t care if it’s Scala, Haskell or any other language, as soon as it may widen my horizon. But i would answer to all those who think Scala is to hard to grasp, that it’s only a matter of how you would pick up those persons. Granted, it may be difficult to meet those ‘newcomers’ at their common ground – there are some complaints out there that some Scala community members might behave too elitist when it comes to blaming Scala as being too difficult (like ‘it’s not Scala which is too difficult, it’s only you who don’t understand it’).

Frankly, i can follow those complaints. If you’re willing to learn and may have some problems to grasp some blog posts about Scala (or any other language) or even some code snippets, it is by way no solution to retreat to a position, saying your just to dumb (or lazy or whatsoever) to get it. Spitting out some code snippets or short articles everey now and then is easy – especially if they come without any context or any larger explanation. That’s really the easy part! The hard part is meeting that so called average Java Joe at his level and escort him intellectually!

So as a community of Scala fellows (or in any other way), we need to stop judge over those large herd of programmers as being too dumb. That’s simply not true! There may be some individuals too sluggish to learn and excel. But for all those others, who may have a hard job and having no chance to deal and become proficient with Scala at day (and therefore have only some hours at night) , we need to provide a way of guidance. And that’s best done to face that before mentioned reality. It’s not the people who are dumb. We as a community are dumb if we don’t react to that reality and welcome those people on their ground!

In order to walk the talk, i decided to resume my work on writing about functional Scala! Hopefully some may still find it a useful intro to get into the ideas of functional programming in Scala.

]]>As promised within the last episode, we’re going to take another detailed look at some more commonly used list functions. As we wanna become well acquainted with the functional side of Scala, we’re again going to implement those list functions one by one. Along the way, we’ll get a better and better understanding on how to apply some of the typical tools within the world of functional programming, like pattern matching, recursion or function composition.

As it turned out, most of us learn best in a synthetical way (that is not by dissecting the frog, but to build one). For that, we’re gonna change the style of the following sections. For every useful function, we’re first looking at their intended *behaviour*, maybe along with some exemplary showcases. Only when we grasp the intention, we’re trying to come up with a sensible idea for their realization and finally with an implementation. You might consider the whole episode like a little quiz and try to come up with your own solutions before you’ll take a closer look at the presented ones.

I promise, if you take the approach of thinking first of your own, you’ll become much more proficient in writing your own list functions in a more functional style after the end of this episode. So start your favoured development environment and have fun to hack …

All solutions are based on our own list-like data structure, which we’ve *invented* over the past episodes. For a short refreshment, take a look at the underlying algebraic datatype:

sealed abstract class Lst [+A]{ def +:[S >: A] ( x :S ) :Lst[S] = new +:( x, this ) } case object Nl extends Lst[Nothing] case class +:[A]( x :A, tail :Lst[A] ) extends Lst[A]

You may detected two changes here: first, we renamed our object which represents the empty list from *EmptyLst* to *Nl*. This is first of all a conveniance thing. It’s shorter and in the tradition of naming the empty list after the latin word for *nothing* (nil, nihil). Second, we also renamed our value constructor for *consing *a head to a given list (as the tail of the newly constructed list). It’s now named *+:* instead of *Cons*. This way, we just saved our extractor for doing list deconstruction symmetric to list construction, since we can naturally pattern match on case classes.

Ok, without any further ado, let’s start with some really basic list functions. We’ve already encountered some of them within the last episode, so i’m not gonna repeat them here again.

Our first function just provides information if a given list is just the empty list or not. So it should behave like in the following samples:

empty( Nl ) // >> true ... empty( 1 +: 2 +: 3 +: 4 +: 2 +: 5 +: Nl ) // >> false ... empty( "a" +: "b" +: "c" +: Nl ) // >> false

In this case, we just make use of the fact, that Scalas case classes come with a sensible implementation of *==* for testing two instances for equality:

def empty( lst :Lst[_] ) = lst == Nl

Here, we’re interested in the head (alas the *first *element) of a given list. Just look at the examples:

head( Nl ) // >> None ... empty( 1 +: 2 +: 3 +: 4 +: 2 +: 5 +: Nl ) // >> Some( 1 ) ... empty( "a" +: "b" +: "c" +: Nl ) // >> Some( "a" )

In this case, we can again leverage pattern matching for simply splitting the problem space into two simpler cases – the empty list (for which we return None) and a list with at least one element (for which we return just the *first *element):

def head[A]( lst :Lst[A] ) : Option[A] = lst match { case a +: _ => Some(a) case _ => None }

Of course we also could’ve come up with an unsafe version, which throws an exception in case of an empty list:

def head[A]( lst :Lst[A] ) : A = lst match { case a +: _ => a case _ => error( "no head on empty list" ) }

This is the complement of the *head* function, which just returns everything but the head.

tail( Nl ) // >> Nl ... tail( 1 +: 2 +: 3 +: 4 +: 2 +: 5 +: Nl ) // >> 2 +: 3 +: 4 +: 2 +: 5 +: Nl ... tail( "a" +: "b" +: "c" +; Nl ) // >> "b" +: "c" +: Nl

The implementation might look like quite similar to the one for *head*. Maybe pattern matching is a good idea …

def tail[A]( lst :Lst[A] ) : Lst[A] = lst match{ case _ +: as => as case _ => lst }

You may remember function *last *from the last episode, which results into the last element of a given list. Now again, *init *can be seen as the complement of *last*, which just returns everything but the last element:

init( Nl ) // >> Nl ... init( 1 +: 2 +: 3 +: 4 +: 2 +: 5 +: Nl ) // >> 1 +: 2 +: 3 +: 4 +: 2 +: Nl ... init( "a" +: "b" +: "c" +; Nl ) // >> "a" +: "b" +: Nl

This one might be a bit trickier. Again, we could split the whole problem into some simpler sub cases: for the empty list, init is just again the empty list. The first successful and easiest case would be a list which only consists of two elements, so we could just return a new list without the last element before the empty list. For all other cases (where the list consists of more than two elements) we just call *init *on the tail of the list (which must consist of at least two elements). This recursive call will result into a list without the last element, for which we just prepend the given head of the list:

def init[A]( lst :Lst[A] ) : Lst[A] = lst match { case Nl => Nl case a +: last +: Nl => a +: Nl case a +: as => a +: init( as ) }

Within this section, we’ll regard some functions which will be convenient to use for constructing some special list instances. Some other functions will also construct new list instances based on some already given lists.

Say we wanna create a list which consists repeadetly of one and the same given value (we’ll see shortly for what this is good for). Since we can’t produce a list which is going to be produced lazily (this is a topic catched by Scalas *Stream* type, we’re also going to detect in some further eposide), we can’t come up with a *potentially infinite* list. So in our case we need to give a number for the length of a list for which we’re saying about how often that value should be repeated within the list:

val as :Lst[String] = repeat( "a", 4 ) // >> "a" +: "a" +: "a" +: "a" +:Nl ... val ones :Lst[Int] = repeat( 1, 6 ) // >> 1 +: 1 +: 1 +: 1 +: 1 +: 1 +:Nl ... val succs :Lst[Int=>Int] = repeat( (x :Int) => x + 1, 3 ) // >> (x :Int) => x + 1 +: (x :Int) => x + 1 +: ...

Ok, what about taking an element and a counter and recursively calling repeat by decrementing that counter each time (until we want to repeat that element zero times, which therefor results into an empty list)? Since repeat results into a list, we simply prepend the given value in each recursion step to that produced list:

def repeat[A]( a :A , times :Int ) :Lst[A] = if( times == 0 ) Nl else a +: repeat( a , times - 1 )

Ok, this is a very limited function, since it only creates lists of integer values. In this case, we simply wanna create a list which consists of all integer values from a given starting point upto a given end value (which we presume to be greater as the starting point). In addition to that, we might also wanna give an increment which determines the spread between two neighbor values within that list. Since it’s only a simple helper function (as we’re going to see), let’s just give an implementation for it directly:

def interval( start :Int, end :Int, step :Int ) :Lst[Int] = ( start, end ) match { case( s, e ) if s > e => Nl case( s, e ) => s +: interval( s + step, e, step ) }

Of course we could’ve come up with a more general version which might operate on arbitrary types allowing for enumerating its elements (and therefore providing a sensible order for its values, too).

So far, we’re only *prepending* a new value to a given list to become the head of a new list. But what if we need to append a new value to be the new last element of a given list. Of course, we also wanna do so in a non-destructive way like we did within the last episode when we inserted a new element at an arbitrary position of a given list. Hey, wait a minute! What was that? If appending is like inserting, only limited to a fixed position (namely the last position within a list), why not simply delegating to function *insertAt*? Luckily we’re able to determine the last position of any given list, simply by using function length, which we’ve also introdiced in the last episode:

def append[A]( a :A, lst :Lst[A] ) : Lst[A] = insertAt( length( lst ), a, lst )

Just keep in mind that appending a value to a given list is really expensive (at least for our list-like data structure), since we need to reassemble the whole list while inserting the new value at the last position!

Now that we know how to *add* a single value to a given list (no matter at which side), what about concatenating two lists? In this case we wanna receive a new list which just consists of all elements of both lists.

val ints :Lst[Int] = 1 +: 2 +: 3 +: Nl val moreInts :Lst[Int] = 6 +: 7 +: 8 +: 9 +: Nl val strings :Lst[String] = "a" +: "b" +: "c" +: Nl ... val allInts :Lst[Int] = concat( ints, moreInts ) // >> 1 +: 2 +: 3 +: 6 +: 7 +: 8 +: 9 +: Nl ... val mixed :Lst[Any] = concat( ints, strings ) // >> 1 +: 2 +: 3 +: "a" +: "b" +: "c" +: Nl

In this case, we simply prepend the elements of the first list recursively to the second one (which’s then already concatenated with the rest of the first list):

def concat[A,B>:A]( lxs :Lst[A], lys :Lst[B] ) :Lst[B] = ( lxs, lys ) match { case ( Nl, ys ) => ys case ( x +: xs, ys ) => x +: concat( xs, ys ) }

We just saw how to concatenate two lists resulting into a single list. What about having more than two lists? Say we have a list of lists which elements should all be collected within a single list.You might see it as flattening the list of lists: the inner lists get dissolved within the outer one. Of course are the original lists not deconstructed! We wanna construct a new list, leaving the outer list as well as the inner lists untouched.

You might see the whole process as concatenating two lists repeatedly until all (inner) lists are concatenated:

def flatten[A]( xxs :Lst[Lst[A]] ) :Lst[A] = xxs match { case Nl => Nl case x +: xs => concat( x, flatten( xs ) ) }

As the last section within this episode, we’ll take a closer look at some functions which will deliver a certain sublist for a given list.

Imagine we need a function which just returns the first n elements of a given list. So clearly we need to give a number how many elements we wanna take from a given list and the list from which the elements are taken from:

val ints :Lst[Int] = 1 +: 2 +: 3 +: +: 4 +: 5 +: Nl ... val firstThree :Lst[Int] = take( 3, ints ) // >> 1 +: 2 +: 3 +: Nl ... val moreThanExists :Lst[Int] = take( 10, ints ) // >> 1 +: 2 +: 3 +: +: 4 +: 5 +: Nl ... val nope = take( 0, ints ) // => Nl

Let’s try to split the problem into some simpler sub problems, once more: first, if we want to take some elements from the empty list, we surely can’t deliver anything else as the empty list itself. second, if we want to take zero elements from any given list, we again receive only the empty list. Finally, if we want an arbitrary number from a non-empty list, we just deliver the first element of the list and take a a decremented number of elements from the rest of the list:

def take[A]( count :Int, lst :Lst[A] ) :Lst[A] = ( count, lst ) match { case ( _ , Nl ) => Nl case ( 0 , _ ) => Nl case ( i, a +: as ) => a +: take( i-1, as ) }

This one is just the opposite of function *take*. this time we don’t wanna take the first n elements but drop them, resulting into a list with all elements but the first n ones.

The cases here are almost the same: droping from an empty list results into an empty list. Second, dropping zero elements from a given list just result into that list. And finally, dropping an arbitrary number of elements from a given list is just omitting the head of the list and dropping a decremented number from the rest of the list:

def drop[A]( count :Int, lst :Lst[A] ) :Lst[A] = ( count, lst ) match { case ( _ , Nl ) => Nl case ( 0 , as ) => as case ( i, a +: as ) => drop( i-1, as ) }

Here, we wanna split a given list at a certain position, resulting into a pair of two sublists. The first sublist will contain all elements from head until the element before the position to split. The second one will contain all elements from the position to split upto the last element:

val ints :Lst[Int] = 1 +: 2 +: 3 +: 4 +: 5 +: Nl ... val (firstTwo,lastThree) = splitAt( 2, ints ) // >> ( 1 +: 2 +: Nl , 3 +: 4 +: 5 +: Nl )

You may wanna think back to those two introduced functions *take* and *drop*: Splitting a list can be seen as *taking* some elements for the first sublist and *droping* them for the second sublist. So here we go:

def splitAt[A]( pos :Int, lst :Lst[A] ) : (Lst[A],Lst[A]) = ( take( pos, lst ), drop( pos, lst ) )

Of course you may say, that we’ll traversionf the original list twice (well, in the worst case for splitting near the end of a list). First for taking the first n elements and then again for dropping them. Of course we could come up with another implementation, which just traverses the list only once:

def splitAt[A]( pos :Int, lst :Lst[A] ) : (Lst[A],Lst[A]) = ( pos, lst) match { case( _ , Nl ) => (Nl,Nl) case( 0, as ) => ( Nl, as ) case( i, a +: as ) => val (p1,p2) = splitAt( i-1, as ); ( a +: p1, p2 ) }

See that thirs case expression? It’s a bit ugly since we need to put prepending the given head after the recursive split for the rest of the list (otherwise you would end up with a reversed list)

We could continue with that quiz for hours and hours. There are far more useful list functions we haven’t discovered yet! Hopefully you did some ruminations and experimentation for yourself for getting an even better understanding and feeling on how to operate on lists in a more functional style.

In this episode we just saw some of those commonly used list functions and gave a rather straightforward implementation. We did all this by only using pattern matching, recursion and delegation to some other known functions.

We’re by far not at the end. As promised within the last episode, we’ll encounter some very powerful functions which we’ll levrage to build most of the functions we discovered today in a more concise (but also more abstract) way! But before we’ll get there, we need to extend our functional tool box. We’ll see how to kind of *derive* new functions out of some already given functions by using currying. Don’t be afraid! It’s not about indian food but receiving another mighty tool which allows us to become an even more powerful apprentice of functional programming in Scala. So hope to see you there …

For a smooth entry into the world of functions on persistent list structures, let’s first take a look at some non-destructive functions. First we might wanna know if a certain value is an element of a given list. Again we’re going to cheat a bit, since we’ll make an implicit assumption that the elements of a list can be tested for equality using *==* (we’ll adress that issue in more detail when looking at type classes):

def element[A]( x :A, lst :Lst[A] ) : Boolean = lst match { case EmptyLst => false case a +: _ if( a == x ) => true case _ +: as => element( x, as ) }

That wasn’t too difficult. For getting an even better feeling (and might see some recurring patterns), let’s take another look at a read-only function: it’s surely comfortable to have a function for retrieving a certain element within a given list. Typically, a list structure preserves the order in which their elements got *inserted*. Let’s say the element at the head of the list sits on position zero. The next element (which is the head of the lists tail) is at position one and so on and so on. So our function clearly needs two arguments: the position of the element we wanna retrieve and the list itself. Again, we want to preserve the type of the element which is going to be returned, so we’ll use parametric polymorphism. We also need to handle the absence of a reasonable return value (that is requesting a position which is out of scope for a given list), so we’ll again returning a value of type Option, parameterized with the type of the lists content. Just watch the following definition for a first feeling:

def elemAt[A]( pos :Int, lst :Lst[A] ) :Option[A] = ( lst, pos ) match { case( EmptyLst , _ ) => None case( a +: _ , 0 ) => Some( a ) case( _ +: as , i ) => elemAt( i-1, as ) }

So what’s going on here? We’ll just make use of the recursive structure which is given by the value constructors of our list type. If we’re requesting an arbitrary position on an empty List (line 2), we can only return *None*, since we have no element to give. Otherwise, we’re trying to step through the list until we’re reaching the requested position: If we request position zero on a given list (line 3), then we’re immediately done, since we only need to return the head of the given list. For any other position (line 4) we can’t deliver the lists head but need to step into the tail of the given list (which’s also a list) recursively, while also reducing the position which is requested within the rest of the list.

Again, we just saw a very natural way for operating on recursive, algebraic datatypes. Since pattern matching can be seen as the counterpart of list construction, we used it for reasoning and react upon the structure of a given list instance: we just splitted the *problem *into three smaller problem cases which we can handle independently. Secondly we just reflected the recursive nature of our datatype by defining a recursive function which just makes use of the fact that the tail of a list is also a list which can be treated in the same way.

Now that we saw a very natural way for operating on our list type, let’s see if we’re able to make use of it when trying to operate on a list which typically *destroys *the structure of a given list instance in an imperative environment. As we’ve said, a persistent data structure represents an immutable value. So every operation – like inserting another element at an arbitrary position into a given list – just results into a new version (read a new value) of a list.

So how could we achieve it? Maybe we could take a look at our three cases we used for retrieving an element within a given list. In doing so, we might find an answer for all of those three smaller *problems*:

- Inserting an element into the empty list, at an arbitrary position

In this case, we might simply return a new list which just consists of the new element , prepended to the empty list. We just don’t care about the position, since we already*arrived*at the end of the list. - Inserting an element into a given list at position zero

In this case, we also just prepend the new element to the given list. The result is a new list with the new element as head and the given list as the tail. Of course, the old list instance isn’t destroyed since we only constructed a new list version which*refers*to the old list version as its tail. - Inserting an element into a given list at any other position

In this case, we can’t simply prepend the new element as the head of a new list. Like we already did, we also need to step through the rest of the list, until we reached the right position. And here comes the exciting part: while we’re stepping though the list, we just reassemble all the list elements we’ve already passed so far, creating a new list version. We’ll doing this in a recursice way, by just prepending every element we’re passing to the list which results from the recursive call of inserting the element into the rest of the list (which should result into a list, were the new element is already inserted successfully).

Now we achieved a master plan for inserting elements into a given list, just resulting into a new list which also holds a new element at the requested position. Implementing that function should be easy now:

def insertAt[A,B>:A]( pos :Int, b :B, lst :Lst[A] ) :Lst[B] = ( lst, pos ) match { case ( EmptyLst , _ ) => b +: EmptyLst case( as , 0 ) => b +: as case( a +: as , i ) => a +: insertAt( i-1, b, as ) }

Remember the covariant nature of our list type? Again, we reflected that fact just by allowing to insert an arbitrary element for a possible supertype of the given type of the lists content. The function then results into a new list which holds for the most specific type for the new element and the given elements. Most important, we didnt destroyed the old list version. We only constructed a new list instance by reassembling every single element on our way to the position for the new element to insert. When we reached that position, we simply result into a list which refers to that new element as the head and refering the rest of the given list as the tail.

You might see the whole process splitted into two phases: reconstruction of a new list by reassembling all elements until we reached the position for the new element and just refering (and thus sharing with the original list version) to the rest of the list after we reached the position for the new element. So for inserting a new element near the start of a list you might need to reassemble only a few list elements (sharing the most part of the list with the former version), while inserting a new element at the end of a list results in reassembling all given elements of the original list value. So in this worst case the cost for inserting a new element (the way we did above) raise linear with the number of the lists elements.

We shouldn’t have any new poblems for that kind of quest. It’s quite similar to the idea of inserting a new element. The only difference is to just skip the given element at the requested position when reassembling the new list version. Observe:

def replaceAt[A,B>:A]( pos :Int, b:B, lst :Lst[A] ) :Lst[B] = ( lst, pos ) match { case ( EmptyLst , _ ) => b +: EmptyLst case ( a +: as, 0 ) => b +: as case ( a +: as, i ) => a +: replaceAt( i-1, b, as ) }

See the pattern at line 3. There we now deconstructed the list into its head and tail, just to leave out the head when it comes to constructing the new list on the right side of the case expression!

Removing an element should be very similar to replacing an element. What? Yep, it’s like replacing without any new element (to replace with) at all. Just watch:

def removeAt[A]( pos :Int, lst :Lst[A] ) :Lst[A] = ( lst, pos ) match { case ( EmptyLst , _ ) => EmptyLst case ( a +: as, 0 ) => as case ( a +: as, i ) => a +: removeAt( i-1, as ) }

Another way would be to give an arbitrary value which is intented to be removed from the list if it’s an element of it. Again, we’ll rely on == for identifying that value within a given list instance. The idea is again very similar to element removal on a certain position. In this case, we just regard every element while stepping through the list:

def remove[A]( x :A, lst :Lst[A] ) :Lst[A] = lst match{ case EmptyList => EmptyLst case a +: as if( a == x ) => remove( x, as ) case a +: as => a +: remove( x, as ) }

In this episode, we saw how to come up with a bulk of some of the most common, essential list functions, operating on lists in a non-destructive way. There, we detected some common patterns.

First, we used pattern matching for reasoning and reacting upon the structure of a given list instance, allowing us to split the *problem *into some smaller problem cases which we can handle independently.

Second, our functions reflected the recursive nature of our datatype. At least one case within our function was defined in a recursice way, which just makes use of the fact that the tail of a list is also a list which can be treated by the function in the very same way.

And finally, we saw the non-destructive *processing *of a given list version, mostly reflected by reassembling a new list structure by the given elements of the original version until we reached a situation (or case) were we could handle the problem immediately, followed by simply referring to the rest of the original list, which can be seen as structural sharing this part of the list between the old and the new list version. In either way, we always come up with a new list value which is kind of derived from the old list. All of the functions we’ve looked so far are leaving the original version untouched, which is so to say the essence of persistent data structures.

Of course there are many more list functions which we haven’t considered yet. What about concatenating two list values for example? Not only for that, we’re going to explore some very powerful functions, which will constitute the basis for a bunch of other functions on lists (like concatenation). That will be the topic for the next episode. So stay tuned …

]]>Bear with me. We’re going to inspect a bulk of widely accepted, commonly used list functions, operating on persistent data structures in a non-destructive way! But before, we’ll need to prepare ourself with a set of tools for an easier way of tinkering with our list-like data structure.

First of all, let’s add some syntactic sugar to our list type. You may remember that building a list was a bit cumbersome. We always needed to use our value constructor *Cons *in a nested form, beginning with the empty list object *EmptyLst* as the final tail:

val intList :Lst[Int] = Cons( 1, Cons( 2, Cons( 3, EmptyLst ) ) ) val stringList :Lst[String] = Cons( "a", Cons( "b", Cons( "c", EmptyLst ) ) )

Clearly we can see the recursive structure of our list type, but declaring or reading a certain list instance seems a bit laborious. Unfortunately, Scala doesn’t allow infix notation for function application, so we can’t come up with a function which simply prepends another element to a given list and use that for cushy list construction, like* 1 ‘prep’ 2 ‘prep’ EmptyLst*. For a kind of *workaround*, we’ll now leave the pure functional path for a moment and make use of Scalas object oriented features. What about adding a (pure) method to our list type, which let’s us apply a new element to a given list instance. The method then simply constructs a new list for us by prepending the passed value as the new head and the given list as the tail. Observe:

sealed abstract class Lst [+A]{ // compile error: covariant type A occurs in contravariant position in type A of value x def +: ( x :A ) :Lst[A] = Cons( x, this ) }

Before we get to that compile error, let’s firstly take a look at the methods *+:* core intention: we just wanna apply a new value *x* to our *function*, which should be of the same type as the already given type of the given lists content. We then simply construct and return a new list value which consists of the new element *x* as the head and the given list as the tail, just as said. It’s just a helper function which hides the manual list construction based on the value constructor *Cons*.

Unfortunately it won’t compile! Remember the last episode were we introduced covariance for type parameter *A*? We did so, because we wanted to share our empty List as a single object for all of our list instances as the final tail. For that, this single object needed to be a subtype for all possible list instances in *A*. Now we have to play the game of covariance for *A*! And this means, that we have to allow to prepend an element which might be of a supertype of *A*. In that case, the newly constructed list is type parametrized by that more general type. So the following definition should work, since we just leverage Scalas power to simply apply a lower type bound for our new element to prepend:

sealed abstract class Lst [+A]{ def +:[S >: A] ( x :S ) :Lst[S] = Cons( x, this ) }

Now *x* can be of any type *S* which may be of the same type as *A* or a supertype of *A*. We finally result into a list which contains elements, for which *S* is the most specific type. Now, with our new helper method *+:* at hand, list construction can be done in a more concise way:

val lst :Lst[Int] = 1 +: 2 +: 3 +: 4 +: 5 +: EmptyLst val anotherLst :Lst[Any] = 1 +: "a" +: 2 +: "b" +: EmptyLst

Ahhh, now we got a much shorter way of defining new list instances. As you could see with *anotherLst*, the type of the lists content is *Any*, since it’s the most specific type for *Int* and *String*. There’s only one little thing that may get you into baffling mode. Taking above list *anotherLst* for example, it looks like we’re calling method *+:* on value *1* for prepending it to value *“a”*. But that’s not the case! As soon as our method ends with a colon, it’s gonna be called in a right associative manner. That is, *+:* is first called on *EmptyLst *for prepending value *“b”*, resulting into an instance of *Lst[String]*. Then *+:* is again called on that list instance, prepending value *2*. Since that value is of type *Int*, we end up with a new list of type *Lst[Any]* and so on and so on …

Ok, now we got a fancy tool for list construction, but what about deconstructing lists by pattern matching? As you surely remember from some older episodes, pattern matching is one of the main tools for operating on algebraic datatypes. And since our list type is defined in the tradition of algebraic datatypes, we shouldn’t have any problems to use pattern matching upon the given value constructors of our list type. For example, let’s determine the length of a given list by defining an appropriate function:

val length : Lst[_] => Int = _ match{ case EmptyLst => 0 case Cons( _ , tail ) => 1 + length( tail ) }

That wasn’t too complicated. We just accept arbitrary lists with an arbitrary content type by stating an existential type for our list argument in the functions signature. We then simply deconstruct the given list, decomposing it into its head and tail (the rest of the list) until we reach the empty list, each time adding 1 to the length for each element we’ll find all the way down. If you’re not worrying about the unbalance for using value constructor *Cons *for deconstruction while using our new method *+:* for construction, everything is fine. But things get more ugly pretty fast again, if we need to pattern match against more than a single head and tail of a list.

For example, let’s write a function which delivers the last element of a list. For doing that, we need to get past two considerations. First, we wanna preserve the type of the lists content. If we want to retrieve the last element for a list of Strings, we should return a String. If it’s a list of Ints, we’d like to return an Int value! For that to achieve, our function need to be polymorphic in the type of the lists content. As we figured out in an earlier episode, this is best done (and even the idiomatic way) by providing a polymorphic method instead of a function value within a polymorphic environment:

def last[A]( lst :Lst[A] ) : A = ...

Second, how do we wanna operate upon an empty list, since there’s simply no last element which we could hand out. For handling the possible absence of a last element we’re going to use type *Option*, which suits this kind of dilemma to a T: we simply return a value of *Option[A]* which is just *None *in the case of an empty list. That way, we stay really honest about the type of our return value (while simply returning null wouldn’t be honest at all, as Dr. Erik Meijer now would say). So we end up with a function like this:

def last[A]( lst :Lst[A] ) : Option[A] = lst match { case EmptyLst => None case Cons( x, EmptyLst ) => Some( x ) case Cons( _ , Cons( x, xs ) ) => last( Cons( x, xs ) ) }

Admitted, it’s a somewhat contrived example, since we needn’t to pattern match againt the first two elements and the rest of the list explicitly (as you may see in the third case expression at line four). Let’s simply say we wanted to communicate that constitution of the list (in that the list contains at least two elements) in a very definite way. Anyway, you might see, that using value constructor *Cons *for deconstructing more than a single head and tail leads again to very cumbersome patterns!

Fortunately, we already know about Extractors as another way to define patterns which are somewhat independent of the structure of value constructors. So what speaks against an Extractor which allows us to form patterns, kind of mimicing the way we construct lists via method *+:* ? Therefore, we just name such an Extractor object like our construction method. Just watch:

object +: { def unapply[A]( x: Lst[A] ) : Option[ (A, Lst[A]) ] = x match { case Cons( hd, tl ) => Some( (hd, tl) ) case _ => None } }

So now we just could come up with a nice pattern declaration which really looks like list notations at the construction side. This way, we just recovered the balance between the form of construction and deconstruction:

def last[A]( lst :Lst[A] ) : Option[A] = lst match { case EmptyLst => None case x +: EmptyLst=> Some( x ) case _ +: x +: xs => last( x +: xs ) }

Now pattern matching is fun again, since forming patterns don’t differ from forming list instances any more. In fact, we could kind of hide our value constructor *Cons *from the eyes of our users. We simply don’t need to know about it, wether on construction, nor on deconstruction side.

Now, to bring this episode to a close, let’s define just another little function *show*, which simply converts a given list into an appropriate string representation. This string representation might also resemble the form of a list, like we use for construction and deconstruction:

def show( lst :Lst[_] ) :String = lst match { case EmptyLst => "EmptyLst" case x +: xs => x + " +: " + show( xs ) } ... val lst :Lst[Int] = 1 +: 2 +: 3 +: 4 +: 5 +: EmptyLst ... val lstShow :String = show( lst ) // results into ''1 +: 2 +: 3 +: 4 +: 5 +: EmptyLst''

Here we just cheated a bit, since we rely on method *toString *for the string representation of the given list values. To get back to a more functional style, there should be another *show *function for turning those values into an appropriate string representation, too. The question is how do we enforce that such a function need to exist for any list value type. There we just detected the need for some more powerful constraints which we’ll adress when looking at type classes (but that will be within an episode in the distant future).

In this eposide we just set the stage for writing all those commonly used list functions in a more comfortable way.

First, we added some syntactic sugar for easier list construction. For there’s no way of doing infix function application, we provided an appropriate helper method for our list type which simply takes a new element and builds a new list, obeying covariance. We’re now able to construct a new list in a right associative way, since Scala calls every method which ends with a colon on the object at the right side of the method call.

We finally found a nice way to form pattern expressions to use within pattern matching which kind of mimic the same notation as for list construction. There, we just leveraged the idea of Extractors for providing an appropriate instance which is named after the method for building lists by prepending values. This way, we kind of established a nice notational balance between list construction and deconstruction.

Now we got some nice tools for defining a whole bunch of list functions, like inserting, replacing or removing elements in an easy, concise way. As you’ll see, we’ll doing so in a completely non-destructive way. But that’s the topic for another episode. Hope to see you there …

]]>What do you know about Frogs? Well, i mean beyond the most common facts you learn from books. One way to learn more about Frogs might be to dissect one, as you may have done back in school. That would be the *analytic* way. But there’s a better way: if you really want to learn about the nature of a frog, you should build one! By building a being that has froglike characteristics, you’re going to learn what makes a frog a frog and how frogs are adapted to their particular environment. It’s a perfect example of learning by *synthesis*!

Well, as this isn’t a series about biology but about Functional Programming with Scala, we’re going to focus on another research object, which will be list-like data structures in a functional environment. We’re going to construct a simple, *functional* list type and explore its characteristics along the way. So let’s start and play Tinkerbell …

If you’re coming from a more imperative background, chances are good that you already heard of a List. Unfortunately, they are also implemented in an imperative way. What does that mean? Take a look at the following examples in Java:

List primes = new LinkedList(){{ add(3); add(5); add(7); }}; List oddNums = primes; ... oddNums.add( 15 ); primes.add( 2 );

Uhm, what happened? You can’t do that! Well, i shouldn’t do that, but i’m allowed to! What we have here is a nice example of sharing a single list instance. Holding more than one reference to a single list isn’t bad as such. But it might get really, really bad when performing so called *destructive updates* in an unproper way! In this case, an update to *oddNums *will destroy the initial structure of the original list – the *old version* of the data structure won’t be available any longer. There’s simply only one version of that list instance, which gets updated *by assignment*. In doing so, we just triggered a kind of side effect, since *primes *also refers to that one and only, *mutable* version of our list! A data structure which only supports a single version at a time – even across updates – is called *ephemeral* and it turns out, that most imperative data structures are ephemeral.

While reading the last section, this should set off some alarm bells in your mind when thinking in a more functional way. There’s simply no mutable state, since there isn’t anything like (re-)assignment, hence no destructive updates and also no side effects at all. Just look back at our algebraic datatypes we produced so far. There, we also can’t mutate a given *Shape *for example:

sealed abstract class Shape case class Circle( radius : Double ) extends Shape case class Rectangle( width : Double, height : Double ) extends Shape ... val rectangle = Rectangle( width = 5, height = 2 ) val anotherRectangle = Rectangle( 10, 5 )

Once we created a certain version (or value) of a shape, it stays forever – just immutable. But how can we ever provide a functional version of a list type which allows for updating their *content* then? Again, we only need to look back at the very basic characteristics of functional programming: all values which ever exist are just … values (in contrast to variables, which refer to a specific area within memory, which is occupied by a value and might be changed in place). So any operation upon a specific value can only produce or result into another value. For a first grasp, just watch again our well-known friend:

val scale : ( Int, Shape ) => Shape = ( times :Int, shape :Shape ) => shape match { case Circle( r ) => Circle( times * r ) case Rectangle( w, h ) => Rectangle( times * w, times * h ) } val rectangle = Rectangle( 10, 15 ) val anotherRectangle = scale( 2, rectangle )

Aaahhh, by scaling a shape instance, we didn’t mutate the given one in place, but produce a new instance, which is kind of *derived *from the old one. The same should be true for lists: an operation upon a specific *list value* might result into a new *list value*. In other words: updating a certain version of a functional list should produce another, new version of a list without destroying the old one! Such functional data structures also got a fancy name, to contrast them from their ephemeral relatives: a (immutable) data structure which supports multiple versions at a time is called a *persistent* data structure.

So how could we achieve a persistent list? First of all, the above examples might give us a first hint: in a functional environment, it’s common to characterize values of a certain type by defining and finally using some value constructors of an algebraic datatype. Now, we need to think hard about the possible structure of a list (or any sequential data structure if you will) and how to represent them as an algebraic datatype. Remember our last example, where we introduced a datatype for representing an infinite set of algebraic expressions? There, we defined some value constructors for atoms (our basic building blocks) and operations, which recursively act on sub-expressions. What about a list? Could we also identify some atoms and some recursive structure, say for a list of integers? Maybe there should be a representation for an empty integer list. So let’s start with that:

sealed abstract class IntList case object EmptyIntList extends IntList

Ok, now we’re able to create an empty integer list, using that singleton case object *EmptyIntList* as our first value constructor, hurray! Now comes the interesting part. Think of *EmptyIntList *as the *atom *of our list type. Like with our arithmetic expressions, can we create another list which uses the empty list just as a component for creating another, new list instance (just like we used two integer literals and created a new instance of an *Add *expression)? Well, then we might add another value constructor which just takes our empty list (as a representative of an IntList) and another integer value and say that this is a valid list, too. Observe:

sealed abstract class IntList case object EmptyIntList extends IntList case class NonEmptyIntList( hd :Int, tl :IntList ) extends IntList

This second value constructor just takes an arbitrary integer value and an arbitrary, existing list and *composes *both into a new list instance. If you look carefully at the structure of that value constructor, you might compare the construction of such a list instance to kind of *prepending *the new integer value to that existing list:

val intList = NonEmptyIntList( 3, NonEmptyIntList( 2, NonEmptyIntList( 1, EmptyIntList ) ) ) ... val anotherIntList = NonEmptyIntList( 4, intList )

Under this point of view, you might wanna identify the given integer value as the head of the new list and the already existing list as the tail of the new list. Note, that we didn’t destroyed *intList *while constructing *anotherIntList*! It looks like we prepended another integer value to *intList*, but the original structure stays untouched. We’ve only used *intList *to be the tail of that newly constructed list. And since both lists are immutable, we can be very confident that no evil rascal might destroy our list instance. Again, this characteristic also received a snazzy name with which you might swank in front of your team members from now on: ist’s called *structural sharing*.

So far, we’re only able to produce lists of integer values. If we would like to build another list of say string values, we couldn’t use our *IntList*! Because it would be pretty dense to come up with an individual list-like data structure for every type we wanna hold within that list, we might consider another, better solution! In fact, we’re able to leverage parametric polymorphism again and abstract over the type of the lists content:

sealed abstract class Lst[A] case class EmptyLst[A] extends Lst[A] case class Cons[A]( head :A, tail :Lst[A] ) extends Lst[A]

Aahhh, by introducing parametric polymorphism, we’re able to produce lists of different types. We just added a type parameter to our new type *Lst* (remember, it’s a very simple implementation – for a full blown list, we’re going to add that missing i). In that case, our value constructors need to provide that polymorphism and therefore be polymorph in the type of its elements, too (since the concrete type isn’t chosen until we define a certain list instance). Also note that we’ve renamed our second value constructor to *Cons*, as its a widely used name (for *cons*tructing a new list). Let’s take a look at building some list instances of different types:

val intList :Lst[Int] = Cons( 1, Cons( 2, Cons( 3, EmptyLst[Int] ) ) ) val stringList = Cons( "a", Cons( "b", Cons( "c", EmptyLst[String] ) ) )

Hm, anything annoying so far? By adding that type parameter, our list-like data structure become a bit more complex: take a look at our *atom*, the empty list. We needed to change it from a singleton case object to a case class, in order to provide polymorphism. In that case we also needed to come up with a different instance of an empty list for every individual type of the lists content, e.g. an *EmptyLst[Int]* and an *EmptyLst[String]*. Since our data structure is immutable, there’s really no need to have more than one instance of an empty list (since all lists we ever create might refer to the one and same immutable empty list object as their final tail).

Is there a way to get back to the empty list as a single case object *and *provide parametric polymorphism? Yes, there is. It turns out that Scala provides a ‘special’ type *Nothing*, which praises itself as the sub-type of all types. Come again? Well, in almost the same manner *as Any *is the super-type of all types, *Nothing *can be considered as the sub-type of all types. You build a new type? *Nothing *is a subtype of it – it sits always at the bottom of your type hierarchy in Scala. So what should speak against leveraging that fact into our list type, like this:

sealed abstract class Lst[A] case object EmptyLst extends Lst[Nothing] case class Cons[A]( head :A, tail :Lst[A] ) extends Lst[A]

Wow, the compiler seems to be statisfied with that. *EmptyLst *is again a singleton case object, extending *Lst[Nothing]*. And since *Nothing *is the sub-type of all types, so for our yet parametric type *A*, too. But take a look at the compiler if we now try to come up with a concrete list instance:

val intList = Cons( 1, Cons( 2, Cons( 3, EmptyLst ) ) ) // error: type mismatch; found EmptyLst.type ... required: EmptyLst[Int]

Hold on, what’s that? Didn’t we just say *Nothing *is the sub-type of all types, so also for type *Int*? Yep, we did! And that’s why the compiler didn’t complain when declaring *EmptyLst *that way! But what’s that error message sayin’ then? Well, in this case, we simply didn’t allow the tail of a list to be of a subtype of *A* (which is *Int* in that case) when applying *tail *to our value constructor *Cons*. This is due to the fact, that we declared our list type to be *invariant *in our type parameter *A* (which i’m not going to explain in this episode, since there are many good ressources out there explaining type variance in Scala). So what’s left to do is to declare our type to be covariant in type parameter *A* and we’re done:

sealed abstract class Lst[+A] ... val intList = Cons( 1, Cons( 2, Cons( 3, EmptyLst ) ) ) val stringList = Cons( "a", Cons( "b", Cons( "c", EmptyLst ) ) )

See that *+* before our type parameter *A*? It’s the sign for telling Scala that our list type will behave covariant in *A*. Now constructing some list instances with different types – all refering to our singleton empty list – shouldn’t be a problem anymore! Wow, it seems that we’re now constructed a full blown persistent, polymorphic, recursive, list-like algebraic datatype.

Hey, we did not bad as Tinkerbells! We’ve just accomplished the first step on our way to understand the deeper meaning and characteristics of persistent list-like data structures! We started with a comparison of ephemeral, destructive data structures (which are widely used in the imperative world) and so called persistent data structures, coming from the functional world! While ephemeral data structures are mutable and therefore change in place over time, a persistent data structure can be seen as an immutable value which might result into another independend value when operating upon the orginial one. The new value might be seen as a consecutive version of the original one, which then co-exist in parallel, maybe exploiting some structural sharing.

On our way to set up an appropriate list type, we saw that parametric polymorphism may be a good option to come up with a single algebraic datatype which abstracts over the type of the lists content. By introducing a type parameter, our list type became a member of what’s called a type constructor: from now on, we need to give a concrete type (for the lists content) in order to get a proper list instance. That’s what usually happen when you move from a monomorphic type (like *IntList*) to a polymorphic type: our *Lst* type alone isn’t viable anymore. We first need to do type parametrization in order to get to a full blown type (like *Lst[Int]*).

We’re by far not finished yet. What about ‘updating’ or ‘replacing’ a single element within a given list? What about the concatenation of to lists? Can we still rely on structural sharing? And what about the *cost *of those operations? Is there a way to put some syntatctic sugar to our list type, say when constructing lists or do pattern matching on them? As these are all valid questions, we’re going to answer them within the next episode, while also taking a closer look on some basic and more advanced functions on lists. So don’t be afraid of the frog …

This one is the sequel to our extended sample on representing and resolving arithmetic expressions using algebraic datatypes and pattern matching. In this second part i try to answer a legitimate question: what are the advantages and disadvantages of algebraic datatypes (consisting of pure data, no behaviour), espacially if we wanna expand our expression language – and what’s that all to do with the visitor pattern?

The expansion of our expression language might come in two flavors: on the one hand we might add some new functionality (for most of us are highly influenced by an object oriented paradigm, let’s call it behaviour), like simplifying arbitrary expressions before evaluating them. On the other hand, we might wanna extend the building blocks of our expression language itself, like mixing in some more operations or adding some variables beside our integer literals.

First, let’s see how easy it is to add some new functionality. You may remember our function *reduce *(and with it function *resolve *for a stepwise reduction of an arbitrary expression). Let’s repeat that again, using a rather complex expression:

val expr = Mult( Sub(Literal(6), Mult(Sub( Literal(5), Literal(3)), Literal(3))), Add(Literal(3), Mult(Literal(5), Literal(8)))) for( e <- resolve( expr ) ) println( format( e ) ) // will print ... // ( ( 6 - ( ( 5 - 3 ) * 3 ) ) * ( 3 + ( 5 * 8 ) ) ) // ( ( 6 - ( 2 * 3 ) ) * ( 3 + ( 5 * 8 ) ) ) // ( ( 6 - 6 ) * ( 3 + ( 5 * 8 ) ) ) // ( 0 * ( 3 + ( 5 * 8 ) ) ) // ( 0 * ( 3 + 40 ) ) // ( 0 * 43 ) // 0

Now take a closer look at line 11. While the first sub-expression’s already evaluated to zero, we still continue to reduce the second sub-expression, only to discover that the whole expression comes down to zero finally. Let’s say that executing a single reduction step (and with it the evaluation of a basic expression) is real expensive. What we need is a way to simplify a given expression, if we detect some trivial *patterns *which let us skip further reduction (like multiplying an arbitrary expression with zero finally results in zero). In other words, let’s add that functionality. Going the functional way by using algebraic datatypes and pattern matching, this is a rather easy task: we don’t need to touch the different building blocks of our language, but simply add another function which scans for some trivial patterns to reduce:

val simplify : Expression => Expression = ( expr :Expression) => expr match { case Add( Literal(0), expr ) => expr case Add( expr, Literal(0) ) => expr case Add( left, right ) => Add( simplify( left ), simplify( right ) ) case Mult( Literal(0), _ ) => Literal(0) case Mult( _, Literal(0) ) => Literal(0) case Mult( Literal(1), expr ) => expr case Mult( expr, Literal(1) ) => expr case Mult( left, right ) => Mult( simplify( left ), simplify( right ) ) case Sub( Literal(x), Literal(y) ) if x == y => Literal(0) case Sub( left, right ) => Sub( simplify( left ), simplify( right ) ) case _ => expr }

Ok, in order to make use of those simplifications, we need to adapt our function *reduce*. We could do that in a way of just composing those two functions:

val simplifiedReduce = ( expr :Expression ) => reduce( simplify( expr ) )

This works fine while calling our new function directly. But what about our function *stepResolve*, which still calls *reduce *directly? Well, in this case we just won the silver medal. We might need to adapt *stepResolve* and all other functions which might also rely on *resolve*, which clearly violates open closed principle! So another option left would be to adapt function *resolve *directly:

val reduce : Expression => Expression = ( expr :Expression ) => simplify( expr ) match { case Literal(_) => expr ... }

Ahhh, ok – before we’re going to pattern match, we just simplify the given expression. Everything ok? If we did pattern matching the right way, everything would be fine. But take a closer look at line 5. Do you spot the risk? This will result in a nice but nevertheless endless recursion when doing stepwise reduction! Again, watch what we’re returning in that case. It’s the original expression, not the simplified one! So while simplification results into a literal, the original expression might be a more complex, nested one. And since we return the original expression, stepwise reduction wouldn’t stop. So is there a possible escape? of course! Everything would be fine, if we just return the literal, we were matching against. Observe:

val reduce : Expression => Expression = ( expr :Expression ) => simplify( expr ) match { case lit @ Literal(_) => lit ... }

Wow, that was easy again. If we don’t rely on the given functions argument (that is *expr*) but instead stay *local *and only refer to those elements we’re matching against (that is *lit*) we’re free to transform the ingoing value in every which way we want while not compromising pattern matching!

With our adapted function at hand , let’s see if we can save some reduction steps:

val expr = Mult( Sub(Literal(6), Mult(Sub( Literal(5), Literal(3)), Literal(3))), Add(Literal(3), Mult(Literal(5), Literal(8)))) for( e <- resolve( expr ) ) println( format( e ) ) // will print ... // ( ( 6 - ( ( 5 - 3 ) * 3 ) ) * ( 3 + ( 5 * 8 ) ) ) // ( ( 6 - ( 2 * 3 ) ) * ( 3 + ( 5 * 8 ) ) ) // ( ( 6 - 6 ) * ( 3 + ( 5 * 8 ) ) ) // ( 0 * ( 3 + ( 5 * 8 ) ) ) // 0

Well, it seems that we in fact saved some reduction steps! Praise to simplification!

While we have seen, that it’s relatively easy to extend functionality by more or less adding some new functions, let’s see how easy it is to extensd our language itself. Say we wanna add another binary operation, like a modulo operation. First we need to extend our algebraic datatype:

sealed abstract case class Expression ... case class Mod( x :Expression, y :Expression ) extends Expression

Now this was the easy part! What about our functions which are build upon our language blocks? For example, let’s take a closer look at our function *eval*. Since we declared our datatype as *sealed*, the compiler has the chance to detect all possible value constructors and see if we’ve matched against all possible cases. In this situation, the compiler complains that our *match is not exhaustive! missing combination Mod*! So let’s give what he deserves:

val eval : Expression => Int = _ match { ... case Mod( leftExpr, rightExpr ) => eval( leftExpr ) % eval( rightExpr ) }

It turns out, that possibly *every* function, which is based on our language needs to be adapted! So we can’t stop with *eval*, but also need to consider *reduce*, *simplify *(if we detect some patterns for simplifying expressions, based on modulo) , *format *and so on. This may become really ugly! For example let’s take a look at a rather worst case scenario: let’s focus on function *reduce*! There, we might add a whole bulk of new case expressions for every new operation:

val reduce : Expression => Expression = ( expr :Expression ) => simplify( expr ) match { case lit @ Literal( _ ) => lit case Add( Literal(_), Literal(_) ) => Literal( eval(expr) ) case Add( left @ Literal(_), rightExpr ) => Add( left, reduce( rightExpr ) ) case Add( leftExpr, right @ Literal(_) ) => Add( reduce( leftExpr ), right ) case Add( leftExpr, rightExpr ) => Add( reduce( leftExpr ), rightExpr ) // case Sub ... cases omitted // case Mult ... cases omitted case Mod( Literal(_), Literal(_) ) => Literal( eval(expr) ) case Mod( left @ Literal(_), rightExpr ) => Mod( left, reduce( rightExpr ) ) case Mod( leftExpr, right @ Literal(_) ) => Mod( reduce( leftExpr ), right ) case Mod( leftExpr, rightExpr ) => Mod( reduce( leftExpr ), rightExpr ) }

Oh my god! Such functions gets bigger and bigger with every new binary operation we’re going to add to our expression language! If we take a closer look to those case expressions for *Add *and those case Expressions for *Mod *(as also to those for *Sub *and *Mult*) we can clearly see some similarities: in fact we could abstract away from the concrete binary operation and concentrate on the reduction of its operands in a rather *polymorph* way.

Unfortunately we need to match against those different value constructors! Well, do we really need to? It turns out, that Scala provides the idea of a so called Extractor, which gives some kind of independence when it comes to pattern matching. You can think of an Extractor as a way to *deconstruct *a given value in an arbitrary way, not determined by the structure of your datatype. This is all done by a simple method *unapply* which takes a value of any type and returns an Option, containing a tuple for the single parts which gets revealed by the process of deconstruction. On the other side, we’re allowed to simply return None as a way to show that we can’t deconstruct a given value – in this case, there won’t be a successful match! Sounds confusing? All gets better with a simple example. Just watch:

object BinaryOp{ def unapply( x :Any ): Option[ Tuple2[Expression,Expression] ] = { x match{ case Add( l, r ) => Some( ( l, r ) ) case Sub( l, r ) => Some( ( l, r ) ) case Mult( l, r ) => Some( ( l, r ) ) case Mod( l, r ) => Some( ( l, r ) ) case _ => None } } }

Our first Exctractor! As said, it’s simply an object with a single method *unapply*, taking any value and resulting in an Option of an arbitrary tuple. In our case, we try to match the given value against all known binary operations. If we get a match, we simply return the left and right operand of the given operator. Otherwise we just return None, showing that the given value can’t be deconstructed into the operations operands. With our new Extractor at hand, we might happily try to give a more concise, *polymorph* implementation for our function *reduce*:

val reduce : Expression => Expression = ( expr : Expression ) => simplify( expr ) match { case lit @ Literal( _ ) => lit case BinaryOp( left @ Literal(_), right @ Literal(_) ) => Literal( eval( ??? ) ) case BinaryOp( left @ Literal(_), rightExpr ) => ???( left, reduce( rightExpr ) ) ... }

Uhm, what started so promising turns out to be useless, since we also need to refer to (or to know at least) the concrete operation on the right side of our case expressions! So this is a dead end? Hm, what prevents us to return the operation as a whole within our Extractor, too? Nothing? Then let’s extend it:

object BinaryOp{ def unapply( x: Any ): Option[ Tuple3[Expression,Expression,Expression] ] = { x match{ case add @ Add( l, r ) => Some( ( add, l, r ) ) case sub @ Sub( l, r ) => Some( ( sub, l, r ) ) case mult @ Mult( l, r ) => Some( ( mult, l, r ) ) case mod @ Mod( l, r ) => Some( ( mod, l, r ) ) case _ => None } } }

Aahhh, now we’re able to also refer to the operation as a whole! But wait a minute. This is just not enough. Sometimes, we need to construct a new operator value on the right side of a case expression which will carry some reduced argument (like at line 9 of our new implementation for *reduce*). But since we’re able to refer to the old operator, we can think of a function, which just constructs a new operation based on a given one and some operands. You might think of it as a kind of a *factory function*:

val construct : (Expression, Expression, Expression ) => Expression = ( op :Expression, fst :Expression, snd :Expression ) => op match { case a :Add => Add( fst, snd ) case s :Sub => Sub( fst, snd ) case m :Mult => Mult( fst, snd ) case mo :Mod => Mod( fst, snd ) }

There you go! We just leveraged another mechanism for doing pattern matching in Scala. This time we just matched the given operation expression against its *type*. Since Scala is also an object oriented language, everything is an object (during runtime) in Scala. And while every object belongs to a type, so values of our datatype, too.

Now that we’ve got all ingredients to write some new functions in a more *polymorphic *way, let’s see how to do with our function under focus:

val reduce : Expression => Expression = ( expr : Expression ) => simplify( expr ) match { case lit @ Literal( _ ) => lit case BinaryOp( binOp, left @ Literal(_), right @ Literal(_) ) => Literal( eval( binOp ) ) case BinaryOp( binOp, left @ Literal(_), rightExpr ) => construct( binOp, left, reduce( rightExpr ) ) case BinaryOp( binOp, leftExpr, right @ Literal(_) ) => construct( binOp, reduce( leftExpr ), right ) case BinaryOp( binOp, leftExpr, rightExpr ) => construct( binOp, reduce( leftExpr ), rightExpr ) }

That’s all! Our function shrinked to only 5 cases. We never need to touch it again when adding some new binary operations. Of course we need to extend *eval *and *construct *with every new operation, but that’s all left to do. All other functions based on operations of our little expression language might stay stable, as long as they operate on a more abstract level (that is not need to act upon a concrete operation)! Take a look at this example, were i added another operation *Pow *(for power) and only extended our Extractor *BinOp *plus functions *eval *and *build*:

val expr = Mult( Add(Literal(6),Mult(Sub(Literal(5),Mod(Literal(5),Add(Literal(2),Literal(1)))),Literal(3))), Add(Literal(3),Mult(Pow(Sub(Literal(10),Literal(6)),Literal(5)),Literal(8)))) for( e <- resolve( expr ) ) println( format( e ) ) // will print ... // ( ( 6 + ( ( 5 - ( 5 % ( 2 + 1 ) ) ) * 3 ) ) * ( 3 + ( ( ( 10 - 6 ) ^ 5 ) * 8 ) ) ) // ( ( 6 + ( ( 5 - ( 5 % 3 ) ) * 3 ) ) * ( 3 + ( ( ( 10 - 6 ) ^ 5 ) * 8 ) ) ) // ( ( 6 + ( ( 5 - 2 ) * 3 ) ) * ( 3 + ( ( ( 10 - 6 ) ^ 5 ) * 8 ) ) ) // ( ( 6 + ( 3 * 3 ) ) * ( 3 + ( ( ( 10 - 6 ) ^ 5 ) * 8 ) ) ) // ( ( 6 + 9 ) * ( 3 + ( ( ( 10 - 6 ) ^ 5 ) * 8 ) ) ) // ( 15 * ( 3 + ( ( ( 10 - 6 ) ^ 5 ) * 8 ) ) ) // ( 15 * ( 3 + ( ( 4 ^ 5 ) * 8 ) ) ) // ( 15 * ( 3 + ( 1024 * 8 ) ) ) // ( 15 * ( 3 + 8192 ) ) // ( 15 * 8195 ) // 122925

Now that we extended our operations, is it also possible to extend the atoms within our language? Until now, we can only express some integer literals, making the whole expression kind of static.

What about introducing a variable as another atom? It could look like this:

sealed abstract class Expression ... case class Var( x :String ) extends Expression

Hurray! We’re just added the possibility to also note some variable parts within our expressions. We simply state a variable and give’em a name:

val expr = Mult( Add( Literal( 6 ), Mult( Sub( Var( "x" ), Literal( 3 ) ), Literal( 3 ) ) ), Add( Literal( 3 ), Mult( Literal( 5 ), Var( "y" ) ) ) )

Wow, that looks really good! But ask yourself what the result of e.g. *Mult( Literal( 5 ), Var( “y” ) )* may be? Well, in order to resolve such an expression, we need to extend our model in a more fundamental way: along with the expression, we also need an *environment*, which delivers a concrete integer value for every variable. Let’s first define what we understand under an *environment *and how we could deliver a certain value from of a given environment (for a given variable name):

type Environment = List[ ( String, Int ) ] val lookup : ( String, Environment ) => Int = ( Key :String, env :Environment ) => env match { case Nil => 0 case ( Key, i ) :: _ => i case _ :: xs => lookup( Key, xs ) }

Wowowow! Now that needs a little bit of explanation, don’t you think? First we just give a *description *of what we understand of an environment. It’s just a type alias for a list of pairs, where each pair consist of a String value (which might be interpreted as our variable name) and an integer value (which might be consisdered as the value to substitude for a given variable). We also could have used another data structure called *Map*, but we just wanna restrict ourself to some core data structures here!

Next is our function *lookup*, which takes a String (let’s say a variable name for which we’re interested in the related integer value) and an environment and results into an integer value. So far, we’ve cheated a little bit: in case there is an empty environment (that is, we can’t substitude a variable name), we simply return zero (we’ll use an Option for such cases in the near future, so don’t be worried). The second case expression tries to match the first (head) pair of the environments list against the given Key. If we have a match, we can deliver the assigned integer value. Did you note the first letter of our given key is in upper case? That’s because Scala interprets a name solely in lower cases within a pattern as a variable name (to bind the deconstructed, revealed part of the given pattern). That’s not what we want here! We wanna match against a concrete value – that’s the *Key*, given as the functions first argument.

Since the introduction of variables is such a fundamental extension (also forcing the introducing of an environment to substitute variables by an integer value), we also need to adapt our functions. For evaluating an arbitrary expression, we now also need a certain environment in order to resolve some variables within it:

val eval : (Expression, Environment) => Int = (exp :Expression, env: Environment) => simplify ( exp ) match { case lit @ Literal( x ) => lit case Var( x ) => lookup( x, env ) case Add( leftExpr, rightExpr ) => eval( leftExpr, env ) + eval( rightExpr, env ) case Mult( leftExpr, rightExpr ) => eval( leftExpr, env ) * eval( rightExpr, env ) case Sub( leftExpr, rightExpr ) => eval( leftExpr, env ) - eval( rightExpr, env ) case Mod( leftExpr, rightExpr ) => eval( leftExpr, env ) % eval( rightExpr, env ) }

But that’s not enough! Let’s get back to our worst case function *reduce*. Similarly to our binary operations, we also might want do handle atoms in a more *polymorphic *way (that is to act on literals and variables in the same way without differentiating between them). Wait a minute. Didn’t we discovered a way to pattern match on a datatype without relying on their real structure? Yeah, extractors to the rescue, again!

object Atom{ def unapply( x: Any ): Option[Expression] = { x match{ case literal @ Literal(_) => Some( literal ) case variable @ Var(_) => Some( variable ) case _ => None } } }

Aaahhh, we only have a match if there’s a literal or a variable. Only in this two cases, we return an expression, which is just the found literal or atom. In all other cases we’ll return None, so there will be no match in an arbitrary case expression. Now we can adapt *reduce *like so:

val reduce : ( Expression, Environment) => Expression = ( exp : Expression, env :Environment ) => simplify( exp ) match { case Atom( variable @ Var(_) ) => Literal( eval( variable, env ) ) case Atom( a ) => a case BinaryOp( binOp, Atom(variable @ Var(_)), rightExpr ) => construct( binOp, reduce( variable,env ), rightExpr ) case BinaryOp( binOp, leftExpr, Atom(variable @ Var(_)) ) => construct( binOp, leftExpr, reduce( variable, env ) ) case BinaryOp( binOp, Atom(_), Atom(_) ) => Literal( eval( binOp, env ) ) case BinaryOp( binOp, left @ Atom(_), rightExpr ) => construct( binOp, left, reduce( rightExpr, env ) ) case BinaryOp( binOp, leftExpr, right @ Atom(_) ) => construct( binOp, reduce( leftExpr, env ), right ) case BinaryOp( binOp, leftExpr, rightExpr ) => construct( binOp, reduce( leftExpr, env ), rightExpr ) }

Ok, let’s inspect that function. We see that it’s possible to use pattern binding even within a pattern declared by extractors. Take a look at lines 5, 7 and 8 for example: there we wanna be sure that the atom *really is* a variable so we can transform it into an equivalent integer literal just by evaluating the variable to it’s value. There are other cases (e.g. line 9, 10 and 11) where we’re not interested in the concrete form of that atom. There, we only wanna be sure that the operands are just arbitrary atoms, so we don’t need to reduce them any more! There also, you might have seen, that we’re allowed to nest some patterns using multiple extractors: we simply used the *BinaryOp *pattern to extract the operator and its operands while matching against an arbitrary operator. Now within the extracted parts (so within the *BinaryOp *pattern) we additionally match the extracted operands against another extractor pattern *Atom*.

Now it’s time to try our extended language. We could have a single expression featuring some variables and provide multiple environments for assigning variables in some diffeent ways:

val expr = Mult( Add( Literal( 6 ), Mult( Sub( Var( "x" ), Literal( 3 ) ), Literal( 3 ) ) ), Add( Literal( 3 ), Mult( Literal( 5 ), Var( "y" ) ) ) ) for( exp <- resolve( expr, ( "y", 8 ) :: ( "x", 1) :: Nil ) ) println( format( exp ) ) // will print // ( ( 6 + ( ( x - 3 ) * 3 ) ) * ( 3 + ( 5 * y ) ) ) // ( ( 6 + ( ( 1 - 3 ) * 3 ) ) * ( 3 + ( 5 * y ) ) ) // ( ( 6 + ( -2 * 3 ) ) * ( 3 + ( 5 * y ) ) ) // ( ( 6 + -6 ) * ( 3 + ( 5 * y ) ) ) // ( 0 * ( 3 + ( 5 * y ) ) ) // 0 ... for( exp <- resolve( expr1_2, ( "y", 42 ) :: ( "x", 17 ) :: Nil ) ){ println( format( exp ) ) } // will print // ( ( 6 + ( ( x - 3 ) * 3 ) ) * ( 3 + ( 5 * y ) ) ) // ( ( 6 + ( ( 17 - 3 ) * 3 ) ) * ( 3 + ( 5 * y ) ) ) // ( ( 6 + ( 14 * 3 ) ) * ( 3 + ( 5 * y ) ) ) // ( ( 6 + 42 ) * ( 3 + ( 5 * y ) ) ) // ( 48 * ( 3 + ( 5 * y ) ) ) // ( 48 * ( 3 + ( 5 * 42 ) ) ) // ( 48 * ( 3 + 210 ) ) // ( 48 * 213 ) // 10224

Works like a charm! We *only *needed to touch almost every function …

Whew! What a journey! We’re at the end of our extended example. Most of the given data and functionality are based on two concepts: algebraic datatypes and pattern matching. We almost saw every possible way to do pattern matching in Scala: we pattern matched against the natural structure of some case classes (which we leveraged as a kind of description for some value constructors of an algebraic datatype) and deconstructed their nested components, using variable binding, wildcards (remember the underscore) or some concrete values. We pattern matched against some *artificial *patterns, provided by some custom extractors. We matched against types and used variables to bind whole or part of some patterns.

We saw that pattern matching is a more easy task when adding some new functionality while the number of value constructors for our datatype remains stable. This way you might wanna compare the whole construct to the visitor pattern. There also, you may have a number of (non subtype-polymorphic) types where you need to define a certain functionality upon a composite structure for some nested values of those types. The visitor will also kind of *deconstruct *the given nested structure while visiting each node. You can see each *visit *method as a kind of case expression which gets called if the visitor hits a value of the right kind.

Like with the visitor pattern, it’s more easy to add new visitors (providing another functionality), but it’s extremely inconvenient if you add some new types. This would mean that you need to *visit *and adapt each existing visitor implementation, adding another *visit *method to handle the new type!

The same is true for algebraic datatypes and pattern matching. If your datatype appears to be very fragile, then it may be the wrong choice, since you also need to potentially update all your functions based on that datatype. You might soften that pain by introducing some custom extractors to kind of abstract over some of your value constructors! If your datatype remains more stable on the other side, pattern matching might be an elegant way to add some new functionality over time. Only it provides some more options for using different patterns and pattern semantics at your own neeed (while a visitor might only match against a certain type). I hope you’ve seen some of its flexibility within the last two episodes …

]]>In this episode we’ll going to recap and employ everything we’ve learned so far about algebraic datatypes and pattern matching for implementing a more extensive example. We’ll put all those little pieces together which we’ve discovered so far and see how they work in cooperation for building a little language which allows us to write, pretty print, step-wise reduce and evaluate arbitrary arithmetic expressions (considering addition, subtraction and multiplication on integer values). And as the cherry on top, we’ll discover some new flavour of algebraic datatypes and pattern matching.

It may be a good start to first give some thoughts on how we wanna represent algebraic expressions. Just consider a language of expressions build up from basic values (integer literals) and some operations on them (e.g. addition or multiplication of some integer values). For example, the following are all arithmetic expressions:

17

17 + 23

109 * ( 8 + 15 )

An expression in its simplest form might be an integer literal. That’s a legal expression for sure! And how could we represent such an entity within our little language? What about an algebraic datatype *Expression*? Right, mate! Good idea! Let’s write it down:

sealed abstract case class Expression case class Literal( x :Int ) extends Expression

Ok, so far we have a simple and neat product type, since we could express a whole bunch of different integer literals, just using that single value constructor:

val expr1 = Literal( 1 ) val expr2 = Literal( 17 ) ... val exprN = Literal( 532 )

Well, if you think that’s boring, you’re again right! So far, our Expressions are a bit too simple, right? How do you feel about adding some operations which will take some integer literals and act on them? The addition of two integer literals surely pose an Expression in itself. So let’s add it as another value constructor to our datatype, extending our expression language:

sealed abstract case class Expression case class Literal( x :Int ) extends Expression case class Add( a :Literal, b :Literal ) extends Expression

Aaahh, now things start to become more interesting. Our new value constructor also features some components, that is two integer literals which act as the operands for our operation *Add*.

val sum1 = Add( Literal( 17 ), Literal( 4 ) ) val sum2 = Add( Literal( 123 ), Literal( 321 )

In a sense, we’ve just created a recursive datatype (ok, indirectly), since those two components are also Expressions! Um, wait a minute! What was that? Those two components are also expressions? Yep, we just declared literals as being legal Expressions in its simplest form! But is there actually any reason why we restrict addition to act on integer literals directly? If we would allow arbitrary Expressions as operands, we could express nested Expressions within our language like this:

val sum3 = Add( Literal( 21 ), Add( Literal( 17 ), Literal( 4 ) ) ) val sum4 = Add( Add( Literal( 19 ), Literal( 2 ) ), Literal( 12 ) )

In fact, there’s nothing to be said against nested operations (unless you want to restrict yourself to ordinary, basic expressions). From this point of view, we could build arbitrary nested expressions in a recursive way. This recursice nature of building expressions is directly reflected within our value constructors! Observe:

sealed abstract case class Expression case class Literal( x :Int ) extends Expression case class Add( x :Expression, y :Expression ) extends Expression case class Mult( x :Expression, y :Expression ) extends Expression case class Sub( x :Expression, y :Expression ) extends Expression

See the recurive structure? We now defined an algebraic datatype with a recursive structure, allowing us to build arbitrary nested arithmetic expressions. Since there are several operations all acting on an arbitrary expression, we could mix them in every which way.

val expr1 = Mult( Literal( 6 ), Add( Literal( 3 ), Literal( 4 ) ) ) val expr2 = Sub(Mult(Literal(21), Add(Literal(103), Literal(42))), Add(Literal(17), Mult(Literal(29), Literal(7)))) val expr3 = Mult(Sub(Literal(6), Mult(Sub( Literal(5), Literal(3)), Literal(3))), Add(Literal(3), Mult(Literal(5), Literal(8))))

Ah, ok! We’re now able to construct arbitrary expressions featuring any level of nesting, so we could come up with some rather complex expressions. Hm, is there anything annoying?

At least, we might got some problems when trying to read a more complex expression. It’s rather difficult to detect the correct nesting structure, resulting from the fact that operations are expressed in postfix notation within our little language. For that to change, let’s write a little function which takes an arbitrary expression and results into a string which represents the given expression in infix notation (which our brain is trained to scan and recognize).

Given the recursive nature of our expressions, we can mirror that fact directly within our function: we’ll pattern match against every possible value constructor for our *Expression *type, formatting them into their related infix format and than filling the gaps for every sub-expression (that are the operands for any given operation) by just formatting them recursively. Just watch:

val format : Expression => String = _ match { case Literal( x ) => x.toString case Add( leftExpr, rightExpr ) => "( " + format( leftExpr ) + " + " + format( rightExpr ) + " )" case Mult( leftExpr, rightExpr ) => "( " + format( leftExpr ) + " * " + format( rightExpr ) + " )" case Sub( leftExpr, rightExpr ) => "( " + format( leftExpr ) + " - " + format( rightExpr ) + " )" }

That’s all? Aye, mate! That’s all! We’ve just looked at every basic expression type and give an appropriate format. By binding the components for the value constructors of any given operation, we referred to them at the right side of a case expression being able to format them recursively before inserting them into their right place within the string representation for the current operation. This way we’re now able to pretty print any given expression, like the ones above:

println( format( expr1 ) ) // ( 6 * ( 3 + 4 ) ) println( format( expr2 ) ) // ( ( 21 * ( 103 + 42 ) ) - ( 17 + ( 29 * 7 ) ) ) println( format( expr3 ) ) // ( ( 6 - ( ( 5 - 3 ) * 3 ) ) * ( 3 + ( 5 * 8 ) ) )

Ok, now we got a weapon for printing any given expression in infix notation, no matter how complex (read deeply nested) they may be.

What about evaluating a given expression? Finally, we might wanna resolve a complex expression down to a single integer value by evaluating all operations within that expression. Is this any harder as formatting a nested expression? Surely not! It turns out that we can rely on the very same recursive nature of our datatype! So while evaluating a single operation, we just evaluate the value for every operand recursively, again.

val eval : Expression => Int = _ match { case Literal( x ) => x case Add( leftExpr, rightExpr ) => eval( leftExpr ) + eval( rightExpr ) case Mult( leftExpr, rightExpr ) => eval( leftExpr ) * eval( rightExpr ) case Sub( leftExpr, rightExpr ) => eval( leftExpr ) - eval( rightExpr ) }

See the structural similarity to our function *format*, which’s again reflecting the structural similarity to our recursive datatype? Anyhow, now we can just apply any expression to our *eval *function and receive the final, resolved integer value, to which the expression evaluates:

eval( expr1 ) // 42 eval( expr2 ) // 2825 eval( expr3 ) // 0

Wow, our last expression evaluated to zero! Did you see that coming? Well, it would be nice if we had a function which could reduce a given expression step-wise, so that we could follow the single resolvement steps until we finally receive a single integer literal.

For this to realize, we need to find a plan which *expression patterns* we’re able to reduce in which way. Surely, a given integer literal can’t be reduced any further. What’s about the addition of two literals? Well, we only could reduce it to a single integer literal, illustrating the result of that basic addition. As soon as their’s at least one more complex (nested) operand, we first need to reduce that operand solely, before reducing the whole operation in a next step. I think you got the idea: we just need to act on every operation in exactly the same way:

val reduce : Expression => Expression = ( expr :Expression ) => expr match { case Literal(_) => expr case Add( Literal(_), Literal(_) ) => Literal( eval( expr ) ) case Add( left @ Literal(_), rightExpr ) => Add( left, reduce( rightExpr ) ) case Add( leftExpr, right @ Literal(_) ) => Add( reduce( leftExpr ), right ) case Add( leftExpr, rightExpr ) => Add( reduce( leftExpr ), rightExpr ) case Sub( Literal(_), Literal(_) ) => Literal( eval( expr ) ) case Sub( left @ Literal(_), rightExpr ) => Sub( left, reduce( rightExpr ) ) case Sub( leftExpr, right @ Literal(_) ) => Sub( reduce( leftExpr ), right ) case Sub( leftExpr, rightExpr ) => Sub( reduce( leftExpr ), rightExpr ) case Mult( Literal(_), Literal(_) ) => Literal( eval( expr ) ) case Mult( left @ Literal(_), rightExpr ) => Mult( left, reduce( rightExpr ) ) case Mult( leftExpr, right @ Literal(_) ) => Mult( reduce( leftExpr ), right ) case Mult( leftExpr, rightExpr ) => Mult( reduce( leftExpr ), rightExpr ) }

Wowowow, hold on! What’s going on here? Everything looks familiar for the first case expression: there, we simply match the given expression against a single literal. We’re not interested in the given integer value for that literal (therefore the underscore), since we only return the given expression back in case of a match. Same goes for the first case expression matching against *Add*: since both operands mark some simple integer literals, we’ll return a new literal which represents the sum (by addition) of those two basic operands.

No need to get scared of the next case expression. There we wanna match against *Add *while the first operand being a simple literal and the second one a nested expression (we know that the second operand can’t be a literal – in that case there would’ve been a match on the first case for *Add*, right?). If we got a match – hence a literal for the first and a nested expression for the second operand – we’ll return a *new (!) Add *expression, were the second operand is going to be reduced and the first operand just remains the same. Now we got a dilemma: we needed to match the first operand against a literal pattern while also refering to it as a whole on the right side for building a new *Add *expression! But specifying a literal pattern prevents us to declare a variable binding for the first operand. And the other way round, if we simply declare a variable binding for the first operand, how can we be sure to match against a literal pattern simultaneously?

That’s the moment our new constsuct – the @-annotation – is waiting for! It’s just a way to bind a variable to a pattern! So in our case, we just match the first operand against a literal pattern and bind that whole pattern (that is the first operand, in case you’ve forgot it) to a variable named *left*. So if there’s a match, we have a convenient way to refer to the first operand on the right side while it’s guaranteed to be a simple literal.

Now it’s time to see our new function in action. Let’s take a rather complex expression and reduce it step by step:

val expr1 = Mult(Sub(Literal(6), Mult(Sub( Literal(5), Literal(3)), Literal(3))), Add(Literal(3), Mult(Literal(5), Literal(8)))) val expr2 = reduce( expr1 ) val expr3 = reduce( expr2 ) val expr4 = reduce( expr3 ) val expr5 = reduce( expr4 ) val expr6 = reduce( expr5 ) val expr7 = reduce( expr6 ) println( format( expr1 ) ) // ( ( 6 - ( ( 5 - 3 ) * 3 ) ) * ( 3 + ( 5 * 8 ) ) ) println( format( expr2 ) ) // ( ( 6 - ( 2 * 3 ) ) * ( 3 + ( 5 * 8 ) ) ) println( format( expr3 ) ) // ( ( 6 - 6 ) * ( 3 + ( 5 * 8 ) ) ) println( format( expr4 ) ) // ( 0 * ( 3 + ( 5 * 8 ) ) ) println( format( expr5 ) ) // ( 0 * ( 3 + 40 ) ) println( format( expr6 ) ) // ( 0 * 43 ) println( format( expr7 ) ) // 0

There you go. Now we’ve received a better understanding on how the whole expression’s evaluating to zero. We’ve kind of *debugged *the resolvement process, watching every intermediate step. Too bad, we need two know the number of steps in advance! So why not write a function which takes an expression and results into a list of expressions which represent the intermediate expressions after each reduction step until we reach a single literal:

val stepResolve : ( Expression,List[Expression] ) => List[Expression] = ( expr :Expression, steps :List[Expression] ) => expr match { case Literal(_) => expr :: steps case _ => stepResolve( reduce( expr ), expr :: steps ) }

Experts that we are, we can easily see what’s going on: the function just takes an expression and a list of expressions and then just acts on the given expression. If it’s a simple literal (the base case) then we can’t reduce the expression any further. We just prepend the expression to the list of expressions and be done. Otherwise we’re also prepending the expression but need to reduce it at least one more time. For our conveniance, we could come up with another function which just take a single expression and then starts the recursive resolvement steps just by providing an empty list at the start:

val resolve = ( expr :Expression ) => stepResolve( expr, Nil ).reverse

So if you apply the above expression *expr1 *to *resolve*, you gonna receive all intermediate expressions, starting with the given expression down to the final integer literal:

for( expr <- resolve( expr1 ) ) println( format( expr ) ) // will print ... // ( ( 6 - ( ( 5 - 3 ) * 3 ) ) * ( 3 + ( 5 * 8 ) ) ) // ( ( 6 - ( 2 * 3 ) ) * ( 3 + ( 5 * 8 ) ) ) // ( ( 6 - 6 ) * ( 3 + ( 5 * 8 ) ) ) // ( 0 * ( 3 + ( 5 * 8 ) ) ) // ( 0 * ( 3 + 40 ) ) // ( 0 * 43 ) // 0

In this episode we saw algebraic datatypes and pattern matching in practice. We used both to implement a little language for building representations of arbitrary nested arithmetic expressions and operate on them. We recognized *Expression *as a recursive datatype, since operational expressions like *Add *or *Mult *may take some other Expressions as their operands, which is directly reflected by their corresponding value constructors.

In addition to that, most of our functions also reflected the recursice nature of such an expression in a similar way: they were matching against those different value constructors to handle each expression type individually while operating recursively on the operands for any given operation. There we discovered @-annotations which gives us a way to match against a pattern and bind that pattern to a variable for further reference.

We’re not at the end of our road, considering arithmetic expressions. As you’ve seen while debugging through the intermediate expressions during the single resolvement steps, we did some more needless reduction steps. Since the first operand of a multiplication was already zero, we still did some reduction steps on the right operand yet. We’ll see in the next episode how we could get rid of those unnecessary steps by applying some trivial simplifications to our expressions. In addition to that, we’ll see how to reduce the number of case expression within our function *reduce*. In both cases, we’re going to discover some yet unknown forms of pattern matching and will encounter a way for kind of creating your own patterns, leveraging so called extractors. Hope to see you then …

This 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 one question left is how to use pattern matching and therein refer to the single components of a given value constructor for a product type.

So let’s start right away with a little warm-up and revisit our well known product type *Shape*. To make things a bit more interesting, let’s add *Triangle *(considered right-angled for simplicity sake) as another value constructor. Here it comes:

slealed abstract class Shape case class Circle( radius : Double ) extends Shape case class Rectangle( width : Double, height : Double ) extends Shape case class Triangle( base : Double, height : Double ) extends Shape

Ok, ok, nothing new so far. Now, let’s define a new function which returns the area for any given value of a Shape. Ring, Ring – is there a way of applying pattern matching? Of course! We could give a separate case expression for every individual Shape. So let’s match against the different value constructors, like we did before with sum types! Uhm, err, but what about the fields? No matter – as we said, let’s simply match against the value constructors. As soon as they offer some fields, we only need to *mimic* those within our pattern: if we wanna refer to them afterwards, we can simply bind them by providing a free variable name on the right position within our value constructor pattern. Observe:

import sala.Math.{Pi,pow} val area : Shape => Double = _ match { case Circle( radius ) => Pi * ( pow( radius, 2.0 ) ) case Rectangle( width, height ) => width * height case Triangle( base, height ) => height * base / 2 }

Ah, ok now things gettin’ clearer, right? We simply applied some variable names for every single field within our individual value constructors, se we refer to them afterwards on the right side of each case expression for calculating the right area. See that variable *radius *within the first case expression for matching against circles. This one is a free variable name and only accidentally named after the same name used within the original value constructor. You could use whatever (free) variable name you want, as long as they start with a lower case (that’s the sign for Scala to bind the fields value from the actual Shape instance to that variable).

Of course you’re not forced to always bind your fields to a variable. Say we wanna add some optimization and directly return the height of a Rectangle, if the width is 1 (and vice verca). There, we could simply add another case expression just *before *our common case for Rectangles (otherwise we would always match against the common case):

... case Rectangle( 1, height ) => height case Rectangle( width, 1 ) => width case Rectangle( width, height => width * height ...

See that we’re also allowed to match single fields of a certain value constructor against a constant value. And what about our friend, the underscore? It’s of course valid syntax to place them at the position of arbitrary fields. Now guess its meaning – again, we apply the underscore if we simply don’t care about the fields value. If we wanna give an own case expression for the more or less unlikely case of a Triangle with a base of zero, we wouldn’t be interested about the value of its height at all. Check it out:

... case Triangle( 0, _ ) | Triangle( _, 0 ) => 0 case Triangle( base, height ) => height * base * 2 ...

Nothing to be scared! We just said that if the first or second field is of value 0, then we dont care about the companion field (by placing an underscore at its position) because the whole case expression evaluates to zero anyway.

Let’s just concentrate on rectangles for the rest of this episode and create some more functions to play with them. Say we wanna use them to build a little brick world where you can topple or stack them. For a first glance, let’s write a function which takes a rectangle and returns another rectangle where width and height is just switched. Experts that we are now, easy as it can be:

val switch : Rectangle => Rectangle = _ match { case Rectangle( w, h ) => Rectangle( h, w ) }

A tiny little Function. It does nothing more then using pattern matching to kind of *unwrap *the components of that product types value constructor. Now you see why pattern matching is sometimes named as *deconstruction*: a value constructor (like *Rectangle*) constructs a new value from some given values for its individual components (that is the fields for *width *and *height*) while pattern matching deconstructs that value again and kind of unveils the individual components.

Now imagine we wanna stack two rectangles. The result might be another, new *Shape *called *Stack *(i know, it’s no real Shape, but think it’s for the sake of easy continuation for this episode). So let’s just add it:

... case class Stack( top :Rectangle, bottom :Rectangle ) extends Shape ... val myStack = Stack( Rectangle( 5, 10 ), Rectangle( 7, 12 ) )

Ok, so with this new Shape on board, we could build some new stacks simply by taking two rectangles and use our new value constructor. Let’s say we want to make our stacks a little more robust by trying to pile them in a more controlled way: whenever two sides of a rectangle are of the same length, we use those sides to stack them. Means that we may switch a given rectangle if the length of its height corresponds with the length of the companions width and vice verca!

So far so good! But how can we pattern match under regard of some conditions? Of course we could do some kind of case analysis on the right side of an case expression which may lead to nested pattern matching. You may try it and judge for yourself if such functions remain well structured and readable. Fortunately pattern matching offers something called *Guards*, which is nothing more (but also nothing less) as a kind of Predicate which also need to be fulfilled in order to have a valid match. In Scala, a guard is simply a boolean expression, preceded by keyword *if*. Just watch:

val stack : ( Rectangle, Rectangle ) => Stack = ( r1 : Rectangle, r2 : Rectangle ) => ( r1, r2 ) match { case( Rectangle( w1,_ ), Rectangle( w2,_ ) ) if w1 == w2 => Stack( r1, r2 ) case( Rectangle( w1,_ ), Rectangle( _,h2 ) ) if w1 == h2 => stack( r1, switch( r2 ) ) case( Rectangle( _,h1 ), Rectangle( w2,_ ) ) if h1 == w2 => stack( switch( r1 ), r2 ) case _ => Stack( r1, r2 ) }

As you can see, we just added a guard to our pattern. As soon as the basic pattern matches, the guard is evaluated. If the guard results to *true*, we have a final match, If the guard results to *false*, we haven’t a match and pattern matching will continue with the next case expression.

This time, we just saw that pattern matching on product types is not more complicated than we already saw with sum types. The only additional feature is to provide some meaningful expressions for a product types components (that are the fields of a given value constructor.)

As we saw, we could simply put a new variable at the position of a field, which binds the fields current value to that variable (so we can use it at the right side of the case expression). This way we can *deconstruct *a value of a given product type back into its individual parts. If we’re not interested in some of those parts we simply use the almighty underscore (again) at those positions.

Another way of pattern match was to just apply constant values for some or all components of a product type. This way we could match against some individual cases were we’re just fixing some components. We used that in order to fish for some special cases which needed some special treatment (e.g. for the sake of performance).

Finally, we saw a first simple use case for guards. As we’ll see, this is a very powerful mechanism to incorporate some conditions into our patterns. With guards we can not only match against a static pattern, but also put some additional *dynamic *relations to a pattern, which can’t be directly expressed by only looking at a types fields. We will make some more use of guards in the next episode, where we’ll discover some recursive defined datatypes and tryin’ to pattern match against. In addition to that, we’ll see some yet undiscovered techniques offered by Scalas pattern matching mechanism, which will even inrease its range of application. Stay tuned …

In the last episode we were introducing ourself to the idea of Pattern matching – a powerful mechanism for operating on algebraic datatypes by examining different occurrences for a certain type separately, each within an individual case expression. So far, we only matched single values of some sum types by their given value constructors. In this episode we’re going to see how to match against a combination of sum type values.

As threatened in the last episode, imagine we need some tri-state logic for implementing a simple probabilistic model. In this model, we wanna be able to resolve some propositions to be either *true *or *false *or ‘*maybe true or false*‘ (we don’t know yet). Don’t you think this calls for an own datatype? There might be three different values, say *True*, *False *and *Maybe*. Let’s give *Maybe *some special honor: because it looks some kind of exceptional in relation to those well known others, we might name our new datatype *Moolean*. So let’s not lose any further word and first define an appropriate datatype:

sealed abstract class Moolean case object True extends Moolean case object False extends Moolean case object Maybe extends Moolean

So far, this is all boring. What we have here is a simple, pure sum type, featuring three value constructors. Now things get more interesting, if we want to write some methods which operate on them. What about some pure moolean functions, which solely combine or transform some given moolean values. For a warm-up, we could implement a function *not*, which kind of *inverts *a given moolean value:

val not : Moolean => Moolean = ( mool :Moolean ) => mool match { case True => False case False => True case Maybe => Maybe }

Ahhh, it all seems familiar for *True *and *False*: we just behave like their *Boolean *counterpart. Inversing *Maybe *results into *Maybe *in our modell. Think like ‘*Maybe true*‘ gets inverted into ‘*Maybe false*‘ and also the other way round. Either way, it remains a *Maybe*. Now this is busines as usual. We just give a separate case expression for every possible value constructor, catching all possible cases for our given value *mool*.

Whats about combining two moolean values? Let’s say we wanna implement an own function *equals *which takes two moolean values and decides if they both are of the same value constructor. Let’s pretend there isn’t such a comparison for free in Scalas case classes, so we need to implement it on our own. Now, putting ourself in that difficult position, we now have to answer the question how to match against two moolean values simultaneously, since we need to match against both values within our case expressions in order to decide equality. After a short while you may get to the solution to simply express both values as a simple (ad hoc) pair and simply match against that instance of *Tuple2 *(which is a product type, by the way…). Observe:

val equal : ( Moolean, Moolean ) => Moolean = ( a :Moolean, b :Moolean ) => ( a, b ) match { case ( True, True ) => True case ( False, False ) => True case ( Maybe, Maybe ) => True case _ => False }

Ok, seems we can always put those individual values into a tuple and then match against that tuple! See how we could easily absorb all cases where both values aren’t of the same value constructor? Instead of factoring out all possible combinations, we just gathered them within our *otherwise *case.

Combining more than one value now gives rise for another nice application of the underscore: you can use’em not only as the all and final otherwise case, but also for merging only some different cases into one. Sounds funny? All i say is to use the underscore for some values within your tuple combination, where you don’t care about some values at all. For this to make clear, let’s say we wanna have a function *and*, which combines two moolean values in a conjunctive way. And the rules are as follows:

- as soon as any of the two values is
*False*, the whole expression evaluates to*False* - as soon as any of the two values is
*Maybe*, the whole expression evaluates to*Maybe* - in all other cases, the whole expression evaluates to
*True*

Note, that the order of evaluation is important. So rule 1 need to be evaluated before rule 2. And because rule 2 is going to be evaluated before rule 3, the only case for rule 3 is to match against two values of *True*. Fortunately, pattern matching plays into our hands, since the case expressions will be evaluated from top to bottom. See that ‘*any of the two values*‘ within our rules? As soon as there is one of both values matched, we really don’t care about the other one. This can be expressed like so:

val and : ( Moolean, Moolean ) => Moolean = ( a :Moolean, b :Moolean ) => ( a, b ) match { case ( False, _ ) => False case ( _, False ) => False case ( Maybe, _ ) => Maybe case ( _, Maybe ) => Maybe case _ => True }

Aaah, see the first case expression for example? There, we don’t care if the second value might be *True*, *False *or *Maybe *at all. As soon as the first value matches *False*, the whole expression evaluates to *False*. So in this case, we *merged *three cases into one. You may see the first two cases as somewhat related (just as the third and fourth case as well). They are somewhat the same, we only match against different positions within our tuple. Well, if this disturbs your eyes, or your feelings of elegance at all, you may bring them together into one single case expression, using disjunction:

val or : ( Moolean, Moolean ) => Moolean = ( a :Moolean, b: Moolean ) => ( a, b ) match { case ( True, _ ) | ( _, True ) => True case ( Maybe, _ ) | ( _, Maybe ) => Maybe case _ => False }

Condensing case expressions by disjunction makes your function even more concise. For the first case expression, we just catched all cases now, where the first *or *the second value’s matching *True*.

If you come from Javaland, you surely have heard of the Ternary-Operator. It goes something like this:

int absoluteOfA = a > 0 ? a : -1 * a String yesNo = (true && (false || true ) ? "yes" : "no" Order order = selection.equals( "sell" ) ? new SellOrder() : new BuyOrder()

The ternary-Operator can be seen as an espression, which evaluates to one of two values of a certain type. The value is selected by a boolean expression, which preludes the whole *ternary-expression* (before the question mark). If the boolean expression evaluates to true, the whole expression evaluates to the first value (or expression) after the question mark, otherwise to the next expression (after the colon).

Because this episode would be to short otherwise, let’s see how to craft a Quarternary-Operator which evalueates to an arbitrary value of an arbitrary type , depending on a single moolean value. In this case, we not only need to state two values which gets selected depending if the moolean value (or expression which evaluates to a moolean value) is *True *or *False*. In addition to that, we need to give a third value which gets selected if the moolean expression evaluates to *Maybe*. Well, if you can’t imagine, here’s a little preview on how we would like our Quaternary-Operator to work:

val shouldBeTrue :String = True ? "TRUE" | "FALSE" | "MAYBE" val shouldBeZero :Int = Maybe ? 1 | -1 | 0 val shouldBePupil : Person = False ? new Teacher | new Pupil | new Padawan

Please note, that the following solution will only take values for the three cases. We’ll see shortly (when looking at lazy evaluation) how to enhance this version for also working with expressions which evaluate to a certain value, only if selected by the preluding moolean value. For our Quarternary-Operator to work in the above drafted way, we need to leverage Scalas feature of implicit type conversion (which i’m just going to use here without any further explanation) while still relying on pure datatypes (without featuring any methods). We’re catching any moolean value by an implicit conversion, which starts a series of Quaternary-Fragments. Such a fragment will lead to the next fragment, until the whole expression is constructed. In this case, the expression can be evaluated (by pattern matching), resulting in the value which is given for the current moolean value. Just watch:

implicit def startQuarternary( mool : Moolean ) = new QuarternaryTrueReceiver( mool ) class QuarternaryTrueReceiver[+A]( mool : Moolean ){ def ?[A]( trueValue :A ) = new QuarternaryFalseReceive( mool, trueValue ) } class QuarternaryFalseReceiver[+A]( mool : Moolean, trueValue :A ){ def |[B >: A]( falseValue :B ) = new QuarternaryMaybeReceiver( mool, trueValue, falseValue ) } class QuarternaryMaybeReceiver[+A]( mool :Moolean, trueValue :A, falseValue :A ){ def |[B >: A]( maybeValue :B ) = mool match { case True => trueValue case False => falseValue case Maybe => maybeValue } }

See what’s going on? Whenever we try to call a method *?* on a moolean value, implicit type conversion kicks in an calls our method *startQuarternary*. This method simply starts the chain of producing our fragments in form of separate classes which just collect the individual parts of the whole quarternary-expression. In the last Fragment *QuarternaryMaybeReceiver*, we’ve collected all necessary parts, so that we can pattern match against the inducing moolean expression and pick one of the given values to return.

In this episode, we saw how to pattern match against a combination of values – in our case two values of type Moolean. Of course, those values needn’t to be of the same type. You might pattern match against every combination of values of arbitrary algebraic datatypes. All is fine, as long as you put them into an appropriate tuple and than match against that tuple.

Further on, we saw how to kind of *merge *more than one case into one case expression. This we could achieve by – once again – applying the underscore (as a kind of placeholder) to those positions within the tuple, we’re not care about the concrete value. Another way of consolidating more than one case was to bring them together under one case expression in a disjunctive way.

Finally we crafted our own Quarternary-Operator. As you’ve seen, you’re kind of able to write your own *control structures* by need. Our algebraic datatype remained untouched. Instead we used implicit type conversion to start a chain for collecting the different parts of the whole expression.

Still, we only saw how pattern matching can help to structure your functions in a well-arranged way for sum types, yet. By cleverly leveraging the evaluation order of case expressions and merging different cases into one case expression we might gain very concise functions. What’s still open is operating on product types (well, we already have seen one example in this episode, which kind of sneaked in!). There, we may also need to pattern match against some values which are composed within other datatypes. That will be the topic of the next episode. Looking forward to see you again …