I am experimenting with type variables and structural types as part of learning Scala's 'cake' pattern.
Below is a toy API that illustrates my question:
When methods defined in structurual type 'B' are a superset of those in structurual type 'A', why can't I pass an instance of B to a method that wants an 'A'?
... Toy API ....
object Tester extends App {
trait SomeApi {
type Organism <: {
def die(): Unit;
}
type Dog <: {
def die(): Unit;
def bark(): Unit;
}
def dieQuietlyDoesntCompile(entity: Organism): Unit = {
entity.die()
}
def dieQuietly(entity: { def die(): Unit }): Unit = {
entity.die()
}
def processDog(dog: Dog): Unit = {
println("start dog process on : " + dog)
dieQuietly(dog)
}
}
}
The structural types in my API start off with what you might call a 'base type' (Organism in the example above), plus, I have other types in the API which extend the base type. In the case of the Toy API, Dog has all the methods of Organism, plus one more: 'bark()'.
I want to write some helper methods that operate on the base types as is illustrated by the processDog() method .... which takes a 'Dog' instance, but which also wants to call out to 'dieQuietly' which handles the more generic type 'Organism'.
The way I have done things above works, however it is really clunky because I have to fully repeat all the methods of the base structural type. Not so bad in this toy case (since I only have one method: die()), but really awkward as the number of methods in these structural types increases.
Therefore, I would rather passs the dog instance to a method written like 'dieQuietlyDoesntCompile()'.
But as that functions name indicates, if i pass it a Dog instance, it fails to compile with the error:
type mismatch; found : dog.type (with underlying type SomeApi.this.Dog) required: SomeApi.this.Organism
Can anyone suggest a more convenient way to accomplish my goal...? Or am I stuck repeating the methods in the base type ? (an approach which doesn't seem very DRY to me). Thanks in advance for your help ! /chris