Cogs and Levers A blog full of technical stuff

Functors in Scala

Scala’s type is very rich; even where constructs aren’t well defined you can easily piece together anything that you need. In today’s article, I’ll take you through some different functor types as well as a small primer on variance.

Variance

Type variance is what we use to describe sub-class relationships in a class hierarchy. In scala we use the following notations to denote variances:

  Description Notation
covariant C[T'] is a subclass of C[T] [+T]
contravariant C[T] is a subclass of C[T'] [-T]
invariant C[T] and C[T'] are not related [T]

Functors

Covariant functors are what provide map or fmap:

trait Functor[F[_]] {
  def fmap[A, B](f: A => B): F[A] => F[B]
}

Contravariant functors provide contramap:

trait Contravariant[F[_]] {
  def contramap[A, B](f: B => A): F[A] => F[B]
}

Exponential functors are what provide xmap:

trait Exponential[F[_]] {
  def xmap[A, B](f: (A => B, B => A)): F[A] => F[B]
}

Applicative functors are what provide apply and <*>:

trait Applicative[F[_]] {
  def apply[A, B](f: F[A => B]): F[A] => F[B]
}

Monads provide bind, flatMap or =<<:

trait Monad[F[_]] {
  def flatMap[A, B](f: A => F[B]): F[A] => F[B]
}

Comonads provide extend, coflatMap and <<=:

trait Comonad[F[_]] {
  def coflatMap[A, B](f: F[A] => B): F[A] => F[B]
}

Unit testing private members in Java

Sometimes, you need to be able to look at the private members of your classes in order to test that something has gone to plan. Unit testing is one scenario where this makes sense.

import java.lang.reflect.Field;

. . .

private static byte[] getAddressSpace(Memory m) {
    try {
        Field field = Memory.class.getDeclaredField("addressSpace");
        field.setAccessible(true);
        return (byte[]) field.get(m);
    } catch (Exception e) {
        fail(e.getMessage());
    }

    return null;
}

By using the getDeclaredField method, passing the name of the field; the reflection framework will send back the definition. This field gets executed through the use of the get method, passing in the object instance.

To finish the picture here, we can also get access on methods that are private as well:

Method method = targetClass.getDeclaredMethod(methodName, argClasses);
method.setAccessible(true);
return method.invoke(targetObject, argObjects);

Done.

Streams in Java 8

The functional programming paradigm has certainly seen a lot of attention of late, where some of the features that can be exploited from it have properties that assist in scale programming.

In today’s post, I’ll walk through Java 8 streams which allow you to treat collection data structures in a functional way.

What is a stream?

A stream prepares a collection of elements in such a way that you can operate on it functionally. The higher-order functions that you’d commonly see in a functional arrangement are:

An example

To start with, we need to define some test data. We’re going to work with artists and songs:

/** Song.java */
public class Song {
  public String name;
  public int year;
  public int sales;

  public Song(String name, int year, int sales) {
    this.name = name;
    this.year = year;
    this.sales = sales;
  }

  public String getName() {
    return name;
  }

  public int getYear() {
    return year;
  }

  public int getSales() {
    return sales;
  }
}

/* Artist.java */
public class Artist {
  private String name;
  private int age;
  private List<Song> songs;

  public Artist(String name, int age, List<Song> songs) {
    this.name = name;
    this.age = age;
  }

  public String getName() {
    return name;
  }

  public int getAge() {
    return age;
  }

  public List<Song> getSongs() {
    return songs;
  }
}

Now that we have a basic structure of artists and songs, we can define some test data to work with.

Don’t judge me.

Artist rickAstley = new Artist(
  "Rick Astley",
  50,
  Arrays.asList(
    new Song(
      "Never Gonna Give You Up",
      1987,
      500000
    )
  )
);

Artist bonJovi = new Artist(
  "Jon Bon Jovi",
  54,
  Arrays.asList(
    new Song(
      "Livin' on a Prayer",
      1986,
      3400000
    ),
    new Song(
      "Wanted Dead or Alive",
      1987,
      4000000
    )
  )
);

List<Artist> artists = Arrays.asList(bonJovi, rickAstley);

Ok, now that the boilerplate is out of the way; we can start the fun stuff.

Map

map is a function that allows you to apply a function to each element of a list; transforming and returning it. We can grab just the artist’s names with the following:

artists.stream()
  .map(Artist::getName)
  .collect(toList())

toList comes out of the java.util.stream.Collectors class. So you can import static:

import static java.util.stream.Collectors.toList;

Mapping deeper

flatMap allows you to perform the map process on arrays of arrays. Each artist has an array of songs, so we can flat map (at the artist level) to emit a flat list of songs:

artists.stream()
  .flatMap(a -> a.getSongs().stream())
  .map(Song::getName)
  .collect(toList())

Filter

We only want artists over the age of 52.

artists.stream()
  .filter(a -> a.getAge() > 52)
  .map(Artist::getName)
  .collect(toList())

Reduce

We can aggregate all of the sales figures into a single value:

artists.stream()
  .flatMap(a -> a.getSongs().stream())
  .mapToInt(Song::getSales)
  .sum()

Ok, so this has been a whirlwind tour of the Java 8 functional interface.

Implicit values in Scala

Scala has the concept of implicit parameters which allows the developer to implicitly apply a value that has been previously defined. According to the documentation

A method with implicit parameters can be applied to arguments just like a normal method. In this case the implicit label has no effect. However, if such a method misses arguments for its implicit parameters, such arguments will be automatically provided.

An example

We’ll create a Person class that expects a first and last name. There’s also a manager field to be supplied:

case class Person(firstName: String, lastName: String)
                 (implicit manager: Person = null)

Immediately, you can see that the manager parameter has been decorated with the implicit keyword. What this says is:

  • First, any Person that can be accessed (at the point of construction) that has been declared implicit.
  • Second, any Person also declared implicit in companion modules.

For demonstration purposes, a showHierarchy function has been created to show management:

def showHierarchy() = {

  print(s"$firstName $lastName is ")

  if (manager == null) {
    println("not managed by anybody")
  } else {
    val managerFirstName = manager.firstName
    val managerLastName = manager.lastName

    println(s"managed by $managerFirstName $managerLastName")
  }
}

When the Person has a manager, you’ll see their name; otherwise this function will show that they are “not managed by anybody”.

Using the class

With all of this definition, we now take a look at usage. Note that the manager parameter has a default value of null. So, any invocation where an implicit can not be supplied still doesn’t need to be specified as it’s been defaulted.

val sam = Person("Sam", "Brown")
val joe = Person("Joe", "Smith")

sam.showHierarchy()
joe.showHierarchy()

This program shows the following output:

Sam Brown is not managed by anybody
Joe Smith is not managed by anybody

Makes sense. sam wasn’t declared as implicit and as such, wouldn’t be offered in the construction of joe. So, we modify the construction of sam and add the keyword:

implicit val sam = Person("Sam", "Brown")

This has an immediate impact on the output of the program:

Sam Brown is not managed by anybody
Joe Smith is managed by Sam Brown

As you can see, sam has now been implicitly offered to the construction of joe and as such, the manager parameter gets filled (in the construction of joe).

Handy.

Create a DSL using implicits in Scala

Scala provides some simple options to get up and running the development of domain specific languages. In today’s post, I’ll take you through the usage of the implicit keyword that easily allows for this to happen.

End goal

For the purposes of today, I want to create a language that defines simple, directional instructions. “Move left”, “move forward”, etc. The end goal, I want a language that looks like this:

var jump = 5.0 units up
var shuffle = -2.0 units left
var fall = -6000.0 units down

Implicit conversion

The implicit conversion will allow us to get this process started. It’ll provide the ability for us to take that literal, double value (at the start of each of those statements), and convert them into a class instance that we can do more interesting things with.

implicit def convertDoubleToDirectionUtil(amount: Double) = new DirectionUtil(amount)

Ok, so we don’t know what a DirectionUtil class is just yet. That’s coming. Right now, it’s important to focus on this function which is an implicit conversion; allows us to express a double-value like normal and have Scala treat it as a DirectionUtil instance.

Implicit classes

The implicit class allows us to offer a class up to an implicit conversion when it’s in scope.

The definition of our DirectionUtil class here, allows us the units definition function.

implicit class DirectionUtil(val amount: Double) {

  def units(dir: String) = {
    dir match {
      case "forward" => scale((0.0, 0.0, 1.0), amount)
      case "backward" => scale((0.0, 0.0, -1.0), amount)
      case "left" => scale((-1.0, 0.0, 0.0), amount)
      case "right" => scale((1.0, 0.0, 0.0), amount)
      case "up" => scale((0.0, -1.0, 0.0), amount)
      case "down" => scale((0.0, 1.0, 0.0), amount)
      case _ => (0.0, 0.0, 0.0)
    }
  }

}

Really simply, this is just a vector-scaling function. Takes in a tuple, and adjusts it by a magnitude depending on the direction passed in.

Wrapping it all up

To finish up, we’ll put this class and implicit conversion into one neat singleton:

object DirectionUtil {
  val forward = "forward"
  val backward = "backward"
  val left = "left"
  val right = "right"
  val up = "up"
  val down = "down"

  def scale(vec: (Double, Double, Double), mag: Double) = {
    val (x, y, z) = vec
    (x * mag, y * mag, z * mag)
  }

  implicit def convertDoubleToDirectionUtil(amount: Double) = new DirectionUtil(amount)

  implicit class DirectionUtil(val amount: Double) {

    def units(dir: String) = {
      dir match {
        case "forward" => scale((0.0, 0.0, 1.0), amount)
        case "backward" => scale((0.0, 0.0, -1.0), amount)
        case "left" => scale((-1.0, 0.0, 0.0), amount)
        case "right" => scale((1.0, 0.0, 0.0), amount)
        case "up" => scale((0.0, -1.0, 0.0), amount)
        case "down" => scale((0.0, 1.0, 0.0), amount)
        case _ => (0.0, 0.0, 0.0)
      }
    }

  }
}

Now that we have this defined, we can start writing code that looks like this:

object Main extends App {
  import DirectionUtil._

  val jump = 5.0 units up
  println(jump)
}

. . which, as expected gives us an output like this:

(0.0,-5.0,0.0)

In closing

This is a really simple example, but you can see immediately how it can be applied to much more complex scenarios; and how you can be a lot more expressive in your scala source code.