Structural Sub Typing in Scala
Structural typing is compile time checked duck-typing. It allows us to specify the characteristics of a required type instead of an actual concrete type. Let’s create a new SBT project ScalaTyping. In this post we are going to discuss how Scala supports structural sub-typing. Let’s create a simple Scala SBT project.
Let’s introduce three types A, B and C. They are defined as singletons. They don’t share a common inheritence hierarchy. But they have one thing in common, all of them have printThis method defined.
These types have structural similarity which might or might not be semantically similar. What if we just need to use printThis method from objects of these types. Structure typing allows us to introduce code which is based on certain code structures. Scala’s structural typing allows us to introduce such behavior. In the following code, we are creating a List of objects which follow a certain structure. They must have printThis method available with the specified signature. Since A, B, and C fulfill this criteria, we can add their objects to the collection.
Let’s compile and run the code now. We can notice that the code compiles successfully. The correct methods of A, B and C are being called and messages are being printed after being formatted as specified in the individual methods.
This is only possible because of support of structural typing by scala. Otherwise, in a nominal typing system, in order to use these types in this fashion, they must inherit from a common super type with the required signatures. This makes it difficult when we are using these types from a third-party library supporting no extensions.
Structural Typing with Implicit Conversions
Now let’s introduce one more important aspect to this discussion by taking this one step further. How can we still use this when we want to use a type which doesn’t have such structural similarity. Here we have another type D, which is not structurally similar to the other types. This can be an example of a type which we might have from some other library. This is possible that the type is structurally not similar but semantically very similar. It has other methods which can be mapped to the required definition of our structured type.
The type has a method printOnce, which is very similar to our structural requirement for the collection. We just want the method to be used instead of printThis. But if we add D to the same collection, the scala compiler doesn’t seem very happy. This is simply checking the structural type similarity, which D doesn’t clearly have.
We can get around this with using implicit conversion discussed in the previous post. Here we are introducing the implicit conversion between a type with printThis to a type with printOnce. We are also specifying what should be done when printThis is called, it would just call printThis method passing through the arguments passed.
After introducing the above implicit conversion, just make sure that you have your import statement right. When we run the code now, it correctly uses printOnce method following the implicit conversion. Compiler is also happy because of introduction of this implicit conversion.