Scala Goodness: Structural Typing

Structural typing in Scala is the way to describe types by their structure, not by their name as with other typing. Structural typing reduces coupling and the need for inheritance. In Java you would mainly use interfaces instead of structural typing.

I go with the same examples as in "Scala Goodness: Compound types" so it's easier to compare both solutions.

class Dog {
   def call() = println("Comes to you")
}
class Cat {
   def call() = println("Doesn't bother")
}

def call(c:{ def call():Unit }) = c.call();

c:{ def call():Unit } describes a type which has a call method that returns nothing - like void in Java. The method does take all objects of types that satisfies this constraint. We can now use call on both classes:

scala> call(new Dog)
Comes to you

scala> call(new Cat)
Doesn't bother

You can also give your structural type a name with type aliasing:

type Callable = { def call():Unit }

def call(c:Callable) = c.call();

With the same classes from above we get:

scala> call(new Cat)
Doesn't bother

scala> call(new Dog)
Comes to you

Both ways work with more than one method:

def callAndFeed(a:{ def call():Unit; def feed():Unit }) {
  a.call();
  a.feed();
}

class Dog {
  def call() = println("Comes to you")
  def feed() = println("Eats")
}

Calling with a new dog results in:

scala> callAndFeed(new Dog)
Comes to you
Eats

Structural typing is very useful if you are not able to modify classes to make them implement a trait or interface or if you want to reduce coupling and increase reuse. How does this relate to interfaces? The benefit of interfaces instead of structural typing is how they describe the roles of a class.

class Dog extends Feedable with Callable

instead of

class Dog {
   def call() = println("Comes to you")
   def feed() = println("Eats")
}

Scala glory!

See also: