2013-04-07 4 views
5

Dire que j'ai ceci:Contraindre une classe avec des preuves implicites

trait Animal { 
    type Species 
    } 

Je peux assez facilement écrire une fonction qui ne prend que deux animaux de la même espèce

def breed(a: Animal, b: Animal)(implicit evidence: a.Species =:= b.Species) = ??? 

mais je veux créer un class avec le même type de contrainte:

class Bed(a: Animal, b: Animal)(implicit evidence: a.Species =:= b.Species) 

mais il ne sera pas compilé. J'ai essayé quelques combinaisons d'essayer d'utiliser des caractères avec des identificateurs stables et les contraintes et ce pas, mais peu importe ce que je fais - je semble toujours se retrouver avec des problèmes

trait Bed { 
    type T 
    def a: Animal { type Species = T } 
    def b: Animal { type Species = T } 
    } 

    object Bed { 

    def apply(a1: Animal, b1: Animal)(implicit ev: a1.Species =:= b1.Species) = new Bed { 
     type T = b1.Species 
     def a = a1 // this line won't compile, as the compiler can't see the two species are equal ? 
     def b = b1 
    } 

    } 

Merci.

Répondre

4

Vous pouvez exprimer la contrainte par un argument de type sur Bed.apply plutôt que par une contrainte d'égalité de type,

object Bed { 
    def apply[T1](
    a1: Animal { type Species = T1 }, 
    b1: Animal { type Species = T1 }) = new Bed { 
    type T = T1 
    def a = a1 
    def b = b1 
    } 
} 

Cela peut être un peu laconique à l'aide d'un alias de type,

type AnimalAux[S] = Animal { type Species = S } 

object Bed { 
    def apply[T1](a1: AnimalAux[T1], b1: AnimalAux[T1]) = 
    new Bed { 
     type T = T1 
     def a = a1 
     def b = b1 
    } 
} 

des échantillons REPL,

scala> trait Dog 
defined trait Dog 

scala> val tigger = new Animal { type Species = Dog } 
tigger: Animal{type Species = Dog} = [email protected] 

scala> val zebedee = new Animal { type Species = Dog } 
zebedee: Animal{type Species = Dog} = [email protected] 

scala> Bed(tigger, zebedee) 
res0: Bed{type T = Dog} = [email protected] 

scala> val b = Bed(tigger, zebedee) 
b: Bed{type T = Dog} = [email protected] 
Questions connexes