Structural Types is a neat feature of Scala that not many developers know or use. This article will provide a brief introduction on what they are and how to use them.
What are Structural Types?
Types can be really powerful in Scala: they can define classes, abstract classes, objects, traits, functions…and a lot more!
What if we don’t really care what our instance is as long as it has a particular structure?
This problem is also called Duck Typing. The duck test by Mr Riley asserts that
When I see a bird that walks like a duck and swims like a duck and quacks like a duck, I call that bird a duck.
A Structural Type allows you to specify a desired set of properties and to define a type for them: the compiler will guarantee that the given type is compatible with the defined structure and reflection is used at runtime on the instance to call the method. It is important to mention that the use of reflection is quite expensive, so you should probably be careful when using it if performance is a big concern.
How to use them
Let’s simplify the duck test and let’s see how the problem can be easily solved using structural types.
For the sake of this tutorial we consider a duck any entity that can quack.
This requirement can be translated in the following structural type:
scala> type Duck = { def quack(): String } defined type alias Duck
Every time we will use the type Duck the compiler will guarantee that the instance associated to it is compatible with the given structure:
scala> class Bird { def quack() = "quack"} defined class Bird scala> val d1: Duck = new Bird d1: Duck = Bird@541a9917 // it works! scala> class Bro { def quack() = "YOOOO QUAAAACKKK" } defined class Bro scala> val d2: Duck = new Bro d2: Duck = Bro@7db1592b // it works! scala> class Person defined class Person scala> val d3: Duck = new Person <console>:9: error: type mismatch; found : Person required: Duck (which expands to) AnyRef{def quack(): String} val d3: Duck = new Person // it doesn't work because Person doesn't quack
Summary
In this article we have described how Scala implements Static Duck Typing and how it can be used to validate instances on their structure rather than type.