SBT-Eclipse Integration

Yay, we finally have got a really good Eclipse plugin for Scala. Thanks to all the contributors for their great work (as a former Eclipse committer I know that it was hard work). But as lots of Scala projects use SBT as their build tool, a new need is arising, the need for an integration of SBT and Eclipse. For the last one and a half years or so I have been using SBT and IntelliJ IDEA, because the Scala plugin for IDEA is awesome and, most important, there is a really good SBT-IDEA integration. It is provided by the sbt-idea project which I take as an inspiring example for what I would like to achieve for SBT-Eclipse integration.

Therefore I started the sbteclipse project which aims at providing the same features as sbt-idea, i.e. the ability to create Eclipse project files (.project and .classpath) from an SBT project. As SBT will soon be on version 0.9 which differs a great lot from version 0.7 from a plugin developer’s perspective, I decided to develop sbteclipse as a plugin for SBT 0.9.

While there is still a very long way to go, I just released the very first version 0.1 of sbteclipse to the Typesafe repository which means that you can use it easily. Right now it will only create a single project with its source- and class-directories. Libraries and multi-module projects are not yet supported. And of course you will have to build SBT 0.9 on your own, because there are no binaries yet.

If you are interested, please take a look at the “Usage” section of the sbteclipse README. I would be glad to get your feedback, of course. Have fun!

SBT-Eclipse Integration

Applicatives are generalized functors

In my previous blog post about categories and functors I already threatened you with the possibility of a follow-up. Well, here we go. Actually I won’t talk about category theory this time, but about an important abstraction from the world of advanced (at least in my understanding) functional programming which turns out to be a close relative to the now well understood functor.

Functors

Just in case you don’t remember exactly what a functor looks like, here comes the definition:

trait GenericFunctor[->>[_, _], ->>>[_, _], F[_]] {

  def fmap[A, B](f: A ->> B): F[A] ->>> F[B]
}

trait Functor[F[_]] extends GenericFunctor[Function, Function, F] {

  final def fmap[A, B](as: F[A])(f: A => B): F[B] =
    fmap(f)(as)
}

For the sake of simplicity we will stick to the more specific Functor definition throughout the rest of this post. Such a functor is an endofunctor, because its source and target are the same (the category of Scala types and Scala functions). Maybe you remember that such a functor can be regarded as a provider of a computational context: The function f: A => B you give to fmap is lifted into the functor’s context which means that it is executed (maybe once, maybe several times or maybe even not at all) under the control of the functor.

As an example let’s look at how the OptionFunctor defined in the previous blog post is working: If we give fmap a Some the given function will be invoked, if we give it a None it won’t be invoked.

scala> fmap(Option(1)) { x => println("I was invoked!"); x + 1 }
I was invoked!
res0: Option[Int] = Some(2)

scala> fmap(None: Option[Int]) { x => println("I was invoked!"); x + 1 }
res1: Option[Int] = None

So far, so good. Using functors we can lift functions of arity-1 into a computational context.

Applicatives

But what if we have a function of higher arity? Can we still use a functor to lift a function of, let’s say, arity-2?

Let’s look at what happens if we call fmap to partially apply an arity-2 function to its first argument within the computational context of an Option:

scala> val f = (x: Int) => (y: Int) => x + y + 10
f: (Int) => (Int) => Int = <function1>

scala> fmap(Option(1))(f)
res0: Option[(Int) => Int] = Some()

What we get back is an Option[Int => Int], i.e. the “rest” of the partially applied function wrapped in an Option. Now we have a problem, because we cannot give this lifted function to another call of fmap.

scala> fmap(Option(2))(fmap(Option(1))(f))
:13: error: type mismatch;
 found   : Option[(Int) => Int]
 required: (Int) => ?
       fmap(Option(2))(fmap(Option(1))(f))

Of course we cannot, because fmap expects a pure function, not a lifted one. And that’s the moment when applicatives enter the stage. The idea is simple and follows intutively from what we have just seen: Instead of fmap taking a pure function, an Applicative defines the method apply taking a lifted function. And it defines the method pure to lift pure functions. Using these it is perfectly possible to partially apply an arity-n function to all of its arguments within a computational context. Before we look at our example from this new perspective, let’s code up our new abstraction:

trait Applicative[F[_]] extends Functor[F] {

  def pure[A](a: A): F[A]

  def apply[A, B](f: F[A => B]): F[A] => F[B]

  final def apply[A, B](fa: F[A])(f: F[A => B]): F[B] =
    apply(f)(fa)

  override def fmap[A, B](f: A => B): F[A] => F[B] =
    apply(pure(f))
}

As you can see, there is a strong relation between functors and applicatives: Each applicative is a functor and by one of the laws for applicatives the following has to hold true: fmap = apply ο pure. Well, this law is pretty intuitive, because it makes sure we can use an applicative as a functor, i.e. for a pure arity-1 function, and it will behave as expected.

In order to be able to work with applicatives we need some scaffolding and for our Option example we need an implementation of Applicative:

object Applicative {

  def pure[A, F[_]](a: A)(implicit applicative: Applicative[F]): F[A] =
    applicative pure a

  def apply[A, B, F[_]](fa: F[A])(f: F[A => B])(implicit applicative: Applicative[F]): F[B] =
    applicative.apply(fa)(f)

  implicit object OptionApplicative extends Applicative[Option] {

    override def pure[A](a: A): Option[A] =
      Option(a)

    override def apply[A, B](f: Option[A => B]): Option[A] => Option[B] =
      o => for { a <- o; p <- f } yield p(a)
    }
}

Now let’s look at our example from above with an arity-2 function. Using a functor we got stuck, but using an applicative we can make it all the way through the two arguments:

scala> apply(Option(1))(apply(Option(2))(pure(f)))
res0: Option[Int] = Some(13)

Ain’t that nice? You might answer, that this code looks cumbersome and is not necessary at all. Regarding the first argument please read on. Regarding the second: Yes, of course we don’t need an applicative for Option, because it already offers flatMap which does the job. But with this type class approach we can deal with any class, e.g. with Either from the Scala standard library or with classes from our own projects.

Conclusion

You have seen the basic principle of applicatives: We can apply functions of arbitrary arity (well, greater or even one) to its arguments within a computational context. As functors provide exactly this for arity-1, applicatives are generalized functors.

Thanks to Scala’s flexibility we can of course do much better than above. Using a little pimp my library and some operators we can get something that’s elegant and useful. Luckily the scalaz folks have already done this, so I will just show two ways of expressing the above example using this awesome library:

scala> Option(1) <*> (Option(2) <*> Option(f))
res0: Option[Int] = Some(13)

scala> (Option(1) <**> Option(2)) { _ + _ + 10 }
res1: Option[Int] = Some(13)

Now this is really nice, isn’t it? Especially the second one looks very concise and intuitive. And as I stated above we can use it for types that don’t bring helpful methods like flatMap. Let’s conclude with another example using Either which is a perfect candidate to be used for results that might fail with well defined errors:

scala> (1.right[String] <**> 2.right[String]) { _ + _ + 10 }     
res0: Either[String,Int] = Right(13)

scala> (1.right[String] <**> "Error".left[Int]) { _ + _ + 10 }
res1: Either[String,Int] = Left(Error)

If you are interested in the code examples shown above, you can find these here: https://github.com/weiglewilczek/fun

Applicatives are generalized functors

Introduction to Category Theory in Scala

If you are a former Java developer and have become a Scala fanboy like me, you will probably sooner or later encounter terms like monad, functor or other mysteries from the realm of category theory which make you feel like a little dummkopf (screamingly funny for a German like me, according to www.dict.cc this seems to be a proper English verb). If you already feel comfortable with these, don’t waste your time and move along. But if not, I would like to invite you to a little sightseeing trip that reflects my efforts to get to know this secret realm somewhere in between abstract mathematics and computer science.

This blog post is meant to be an introduction. Depending on the effect on my health (while writing I’m often afraid that my head might explode), my future spare time (understanding comes very slowly, if at all) and your feedback, I am going to write a follow-up. But for now let’s get started.

What’s a category?

Obviously this should be the first question when talking about category theory, although in my opinion the concept of a category is not too useful for programming. Here comes a comprehensive answer:

A category is made up from objects and maps (aka morphisms or arrows) between these objects. Maps can be composed in an associative fashion and for each object there is an identity map which is neutral with regard to composition.

Objects can be anything, but let’s look at a simple case: The category of finite sets. The diagram below depicts two such finite sets as well as a map from the one called source (aka domain) to the other called target (aka codomain).

A little more formally, we can call the domain A and the codomain B and write the map like this:

f: A → B

Now what’s composition? Let’s look at the next diagram, where I added another finite set and another map. Please don’t worry that in this strange world eating habits are different from what you might know 😉

Let’s call the new set C and the new map g: B → C. Obviously we can get from A to C by first following f and then g. Therefore we get a new map from composing f and g:

g ο f: A → C

Now that we know composition, we have to talk about associativity and identity. Let’s add another map h: C → D. Then the associativity law requires the following to hold true:

(h ο g) ο f = h ο (g ο f)

Associativity should become clear pretty fast from thinking of addition or multiplication of numbers. Therefore let’s move along towards the identity laws. These require that for each object X of the category there is an identity map 1X: X → X which satisfies the following rules:

  • f ο 1A = f
  • 1B ο f = f

The following diagram depicts an identity map in our example category of finite sets. Obviously for identity maps the domain and codomain are the same object.

OK, that’s it. That’s categories. Objects, maps, composition, associativity and identity. If you would like to dive a little deeper into the theory, I recommend Wikipedia or “Conceptual Mathematics” by Lawvere and Schanuel. I will move along and look at categories from a Scala point of view.

Categories in Scala

Note: In the following I will borrow a lot of ideas and even some (slightly modified) code from the scalaz project. This Scala library, together with the Apocalisp blog, provides an incredibly valuable source of information and inspiration about advanced functional programming in Scala.

Now that we have investigated the category of finite sets, let’s implement another one in Scala. Therefore we consider the category made up from Scala types as objects and Scala functions as maps. We still have to prove that this is a category, but first let’s code it up:

object Category {
  def id[A]: A => A = a => a
  def compose[A, B, C](g: B => C, f: A => B): A => C =
    g compose f // This is Function.compose, not a recursive call!
}

OK, it looks like we have all the ingredients we need: Types are objects, functions with one argument (trait Function) are maps, id returns the identity function for each A and compose composes two functions.

It looks obvious, that the associativity and identity laws are satisfied, but better let’s check using a simple unit test written using the awesome specs and ScalaCheck frameworks:

class CategorySpec extends Specification with ScalaCheck {
  import Category._

  "A Category" should {

    val f = (i: Int) => i.toString
    val g = (s: String) => s.length
    val h = (i: Int) => i * i

    "satisfy associativity" in {
      Prop forAll { (i: Int) =>
        compose(h, compose(g, f))(i) == compose(compose(h, g), f)(i)
      } must pass
    }

    "satisfy identity" in {
      Prop forAll { (i: Int) =>
        compose(f, id[Int])(i) mustEqual compose(id[String], f)(i)
      } must pass
    }
  }
}

OK, so now we know that Category indeed adheres to the category laws. But that’s not the end of our story! Let’s move along to a more general category in Scala: While sticking to the Scala types as objects we will use the type constructor ->> for the maps.

trait GenericCategory[->>[_, _]] {
  def id[A]: A ->> A
  def compose[A, B, C](g: B ->> C, f: A ->> B): A ->> C
}

Please note, that A ->> B is just another way to write ->>[A, B], which nicely reflects the fact that we are talking about maps here.

Of course our Category is an implementation of this GenericCategory:

object Category extends GenericCategory[Function] {
  def id[A]: A => A = a => a
  def compose[A, B, C](g: B => C, f: A => B): A => C =
    g compose f // This is Function.compose, not a recursive call!
}

If you are interested in further types of categories, don’t hesitate to take a look at scalaz: You can find numerous categories there, e.g. a category of partial functions or a monoid category. I will keep it that way and move along to another important concept in category theory.

Functors

Now that we know categories and how to represent certain ones in Scala, let’s look at another important concept of category theory, which is also very important for functional programming. Consider two categories C1 and C2; then a functor F is a structure-preserving mapping between these categories.

OK, but what does that mean? A mapping between categories simply means that

  • every object A ∈ C1 is mapped to to an object F(A) ∈ C2 and
  • every map A → B between two objects A, B ∈ C1 is mapped to a map F(A) → F(B) between two objects F(A), F(B) ∈ C2.

In order to preserve the category structure this mapping must preserve the identity maps and the compositions. More formally:

  • F(1A) = 1F(A) ∀ A ∈ C1
  • F(g ο f) = F(g) ο F(f) ∀ f: A → B, g: B → C where A, B, C ∈ C1

Before thinking about the “meaning” of a functor, let’s code it up in Scala using our GenericCategory (of Scala types and arbitrary maps between these) as foundation:

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

Again, ->> and ->>> as well as F are type constructors. Looking at the ingredients, we find all that we need: Types A and B are mapped to types F[A] and F[B] and maps A ->> B are mapped to maps F[A] ->>> F[B].

Now let’s move along from arbitrary maps to Scala functions, i.e. choose our Category as source and target of the functor. This results in a so called endofunctor (same source and target) and looks like the following:

trait Functor[F[_]] extends GenericFunctor[Function, Function, F] {
  final def fmap[A, B](as: F[A])(f: A => B): F[B] =
    fmap(f)(as)
}

Please note, that the new fmap method is just for convenience and delegates to the inherited one. Using the higher kinded type for the first parameter list makes it possible to infer the type of A for the function in the second parameter list.

In order to code up some examples, we have to specify the type constructor F. Let’s start with good old List:

object ListFunctor extends Functor[List] {
  def fmap[A, B](f: A => B): List[A] => List[B] = as => as map f
}

This one let’s us map a function over a List, which means that this functor looks like a container that allows us to apply a function to all of its elements. This is a very intuitive way to think about functors. And it makes clear, that functors are a very important concept for functional programming, because if you look at the collections of the Scala library, you will see, that all of them provide this “mapping a function over the elements”.

OK, let’s see how we can use that. Therefore we add a Functor object, move our ListFunctor into that and make it implicit and add a generic fmap method:

object Functor {

  def fmap[A, B, F[_]](as: F[A])(f: A => B)(implicit functor: Functor[F]): F[B] =
    functor.fmap(as)(f)

  implicit object ListFunctor extends Functor[List] {
    def fmap[A, B](f: A => B): List[A] => List[B] =
      as => as map f
  }
}

Welcome type classes! The new generic fmap method takes an additional and implicit parameter of type Functor parameterized with a higher kinded type. When we call this method with an instance of this higher kinded type and a function but no functor, the compiler will look for a matching implicit value. Let’s see it in action:

scala> import com.weiglewilczek.cats.Functor._
import com.weiglewilczek.cats.Functor._

scala> fmap(List(1, 2, 3))(x => x + 1)        
res0: List[Int] = List(2, 3, 4)

While we could have reached the same result by simply calling map on the List instance, we now have something more general: A fmap method that works for any type for which we provide a functor.

We still have to verify that our ListFunctionFunctor satisfies the functor laws. Hence we write another unit test:

class ListFunctorTest extends Specification with ScalaCheck {
  import Functor.ListFunctor._

  "A ListFunctor" should {

    "preserve identity" in {
      val stringID = (s: String) => s
      val stringListID = (ss: List[String]) => ss
      Prop forAll { (ss: List[String]) =>
        fmap(stringID)(ss) == stringListID(ss)
      } must pass
    }

    "preserve composition" in {
      val f = (i: Int) => i.toString
      val g = (s: String) => s.length
      Prop forAll { (is: List[Int]) =>
        fmap(g compose f)(is) == (fmap(g) compose fmap(f))(is)
      } must pass
    }
  }
}

Fine! Now let’s look at another example. Why not use Option as type constructor for the Functor trait?

implicit object OptionFunctor extends Functor[Option] {
  def fmap[A, B](f: A => B): Option[A] => Option[B] =
    o => o map f
}

This one let’s us map a function over an Option, which can be thought of as applying the function in the context of the Option. If it is None, the function won’t be applied, if it is Some, it will be applied. This “computational context” is another way of looking at functors which sometimes is called “lifting” of functions: The function is lifted from its normal context to the functor’s context.

Let’s code up another example that makes this interpretation even more obvious. Now we use Function0 as type constructor for the Functor trait:

implicit object Function0Functor extends Functor[Function0] {
  def fmap[A, B](f: A => B): Function0[A] => Function0[B] =
    a => () => f(a())
}

Let’s see this one in action:

scala> val f = (s: String) => s.length
f: (String) => Int = <function1>

scala> val lifted = fmap(() => "abc")(f)
lifted: () => Int = <function0>

scala> lifted()
res1: Int = 3

As you can see, the function f is lifted into the context of the given Function0, i.e. it works on the output of that.

Conclusion

In this blog post we looked at two basic objects from category theory: Categories and functors. Of course there are others, some of them heavily used (e.g. monads), but I will keep it like that for now. Hopefully I could show you that category theory offers some interesting and valuable concepts that can be applied to and expressed in Scala. As I consider myself still a rookie in category theory, I’d be happy to get your feedback.

If you are interested in the code examples shown above, you can find these here: https://github.com/weiglewilczek/fun

Introduction to Category Theory in Scala