background preloader

Type Classes

Facebook Twitter

Scala Implicits : Type Classes Here I Come. I was having some discussion on type classes in Scala with Daniel on Twitter the other day when I suddenly discovered one of my unfinished posts on the same topic. Not that there's anything new that you will get to know from this rant. But these are some of my thoughts on the value that type class based thinking adds to your design space. I started this post when I published my thoughts on orthogonality in design some time back. Let's start with the GOF Adapter pattern .. the object adapter that uses the highly recommended composition technique to bind abstractions. The example is also the same which I used for discussing orthogonality in design .. case class Address(no: Int, street: String, city: String, state: String, zip: String) And we want to adapt this to the interface of a LabelMaker .. i.e. we would want to use Address as a LabelMaker ..

As a client our point of focus has shifted to the adapter class AddressLabelMaker, which wraps our original abstraction, the Address instance. Refactoring into Scala Type Classes. A couple of weeks back I wrote about type class implementation in Scala using implicits. Type classes allow you to model orthogonal concerns of an abstraction without hardwiring it within the abstraction itself. This takes the bloat away from the core abstraction implementation into separate independent class structures. Very recently I refactored Akka actor serialization and gained some real insights into the benefits of using type classes. This post is a field report of the same. Inheritance and traits looked good .. .. but only initially. With Type Classes .. We took the serialization stuff out of the core Actor abstraction into a separate type class. Next we define a separate module that publishes APIs to serialize actors that use these type class implementations ..

A sample actor with encapsulated state. Import ActorSerialization. This refactoring has made the core actor implementation much cleaner moving away the concerns of serialization to a separate abstraction. Type Class pattern example. I was pleasantly suprised by the popularity of my last article, but some people expressed the wish to see a more practical example, outside Scala library. It is always difficult to use practical examples in blog articles, as they often require a lot of context to be properly understood and introduce a lot of unnecessary complexity. So I'm going to compromise here. The example below discuss a common task in many systems, but which I'm going to present in a very simplistic manner.

Specifically, how to format stuff for output. There is much discussion about the proper place to handle output formatting. On one hand, for instance, we have the toString method available on every Java object. It is not uncommon to have serializer, toXML, or similar stuff either. So let's try to solve this problem using the type class pattern. 1.import scala.xml.NodeSeq 3.abstract class FormatterXML[T] { 4. def format(input: T): NodeSeq 1.case class Person(name: String, age: Int); object Person { 04. 05. 06. 05. 11. Monkey Patching, Duck Typing and Type Classes. Implicit tricks -- the Type Class pattern. Some people have been recently discovering the Scala equivalent of Haskell's Type Classes. I was a bit suprised because I thought everyone with enough Scala experience already knew about them, but, apparently, I was wrong. A type class is basically a way to classify types based on the methods they offer.

It offers an alternative to inheritance, in that you can group many different classes (types) that share a common set of methods, just like a superclass can be used to group its subclasses. While Scala does not support type classes directly, the same patterns that hold true for Haskell can be simulated by using implicits in Scala. It will feature proeminently in Scala 2.8, where examples can be found with Numeric, Ordering and even, I think, CanBuildFrom. So, let me give a simple example of the kind of usage this can be put to.

The problem put to me was restricting the options of a type parameter T without resorting to inheritance. First, my abstract class: 1.abstract class Acceptable[T]