13.11.2013

Using Functors or How to use implicit conversions inside containers

Since I work with Scala in my current project, using implicit conversions is quite nice to do the usual mapping stuff 'behind the scenes', for example to map between the external representation of a time value (in thrift) and the internal one using Joda DateTime

Using this just requires it to bring it in scope, e.g. with an import:

Some weeks ago a colleague asked me why the Scala compiler is so stupid not to apply a implicit conversion in the following case:

But how should the compiler now how to convert an Option[JodaDateTime] to Option[ThriftDateTime]? Yes, there is a map() method in Option, but this is just some kind of usual convention, and it would be really dangerous if the scala compiler would automatically use a method map() if present.

At this time I just suggested to explicitly map or use an implicit conversion on Option:
But this is really cumbersome and you have to do it also for lists or any other container type, even if they all have a common map method with the same semantic.

Functors

It turns out that there is a functional class which describes the above situation, they are called functors.
A functor is simply a trait which specifies to supply a map() method with adheres to the functor laws.

The above functor definition is directly taken from Scalaz 7.
Using it for an implicit "container" conversion of our two classes means:


With that the conversions work in all "containers" for which scalaz defines functors:

..and if you want you can write your own functors for your classes.