I've ran into this problem a while ago and it took a bit of thinking before I came to a solution.
Say you have an enumeration:
object BasicAnimal extends Enumeration{val Cat, Dog = Value}
and a function:
def noise(animal:BasicAnimal) = println("It's an animal!")
Say you want to extend the enumeration to include other animals as well:
object FourLeggedAnimal extends BasicAnimal{val Dragon = Value}
So then Cat, Dog and Dragon would all be FourLeggedAnimal, yet only Dog and Cat will be BasicAnimal. Sadly, this wouldn't work as BasicAnimal is an object, not a class or a trait. So what's a guy to do? Try this for a size:
abstract class BasicAnimalAbstract extends Enumeration{ type BasicAnimal = Value val Cat, Dog = Value } abstract class FourLeggedAnimalAbstract extends BasicAnimalAbstract{ type FourLeggedAnimal = Value val Dragon = Value } object BasicAnimal extends BasicAnimalAbstract{} object FourLeggedAnimal extends FourLeggedAnimalAbstract{} def f(animal: FourLeggedAnimal) = println("It's an animal!")
Then you get: scala> f(Dragon) It's an animal! scala> f(Cat) It's an animal! So it would seem that this is the solution. Sadly, this is only a partial solution. One of the issues is that
BasicAnimal.Cat != FourLeggedAnimal.Cat.
Moreover, not even casting would work!
FourLeggedAnimal.Cat.asInstanceOf[BasicAnimal] != BasicAnimal.Cat
So this only works to a certain extent. If you're desperate, you can do this in order to get equality
between elements of BasicAnimal and FourLeggedAnimal:
def findCorrespondent(animal: FourLeggedAnimal){
BasicAnimal.withName(animal.toString)
}
Not ideal, but works.
No comments:
Post a Comment