2013-04-07 9 views
5

Say mam to:Ograniczenie klasę z niejawnego dowodów

trait Animal { 
    type Species 
    } 

mogę dość łatwo napisać funkcję, która trwa tylko dwa zwierzęta tego samego gatunku

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

ale chcę utworzyć klasa z tym samym rodzajem ograniczenia:

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

, ale nie zostanie skompilowany. Próbowałem kilka kombinacji próbują wykorzystać cechy z trwałych identyfikatorów i ograniczeń, a co nie, ale bez względu na to, co robię - Wydaje mi się zawsze skończyć z problemami

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 
    } 

    } 

Dzięki.

Odpowiedz

4

można wyrazić poprzez ograniczenie argumentu typu na Bed.apply zamiast poprzez ograniczenie równości typu

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 
    } 
} 

To może być trochę terser przy pomocy typu alias,

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 
    } 
} 

Przykładowa sesja 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] 
Powiązane problemy