2012-10-03 1 views
4

J'ai deux objets, chacun avec des types définis localement, et je veux déterminer si les types sont les mêmes. Par exemple, je voudrais ce code pour compiler:Comparer les types dans Scala

trait Bar { 
    type MyType 
} 

object Bar { 
    def compareTypes(left: Bar, right: Bar): Boolean = (left.MyType == right.MyType) 
} 

Cependant, la compilation échoue avec « valeur MyType est pas membre de Bar ».

Que se passe-t-il? Y a-t-il un moyen de faire cela?

Répondre

9

Vous pouvez le faire, mais il faut un peu de machines supplémentaires:

trait Bar { 
    type MyType 
} 

object Bar { 
    def compareTypes[L <: Bar, R <: Bar](left: L, right: R)(
    implicit ev: L#MyType =:= R#MyType = null 
) = ev != null 
} 

Maintenant, si nous avons les éléments suivants:

val intBar1 = new Bar { type MyType = Int } 
val intBar2 = new Bar { type MyType = Int } 
val strBar1 = new Bar { type MyType = String } 

Il fonctionne comme prévu:

scala> Bar.compareTypes(intBar1, strBar1) 
res0: Boolean = false 

scala> Bar.compareTypes(intBar1, intBar2) 
res1: Boolean = true 

L'astuce consiste à demander des preuves implicites que L#MyType et R#MyType sont les mêmes, et de fournir une valeur par défaut (null) si ce n'est pas le cas. Ensuite, vous pouvez simplement vérifier si vous obtenez la valeur par défaut ou non.

+0

Merci, ça marche! – emchristiansen

+0

Si l'on omet la valeur par défaut de null, ce serait un contrôle complet de la compilation, ce que je préférerais dans ce cas car tous les types sont connus au moment de la compilation. – sschaef

+0

@sschaef, Je ne pense pas que tous les types sont connus au moment de la compilation. Par exemple, dans la barre suivante, MyType n'est pas déterminé avant l'exécution: "barre de valeurs: Barre = if (/ * flip coin * /) intBar1 else strBar1" – emchristiansen