2014-04-09 12 views
7

Say mam następujący kod:Structural wpisując w Scala: użyj abstrakcyjny typ w wyrafinowania

class Bar { def bar(b:Bar):Boolean = true } 
def func(b:Bar) = b.bar(b)  

Powyższy działa dobrze. Klasa Bar jest zdefiniowana w 3rd biblioteki strona istnieje kilka podobnych klas, z których każda metoda bar np

class Foo { def bar(f:Foo):Boolean = false } 

Zamiast pisać func dla każdej takiej klasie, chcę definiować func stosując ogólny typ B tak długo, jak ma to prawidłową sygnaturę w postaci bar.

Próbowałem następujących ale daje mi błąd:

def func[B <: {def bar(a:B):Boolean}](b:B) = b.bar(b) // gives error 

Błąd pojawia się:

<console>:16: error: Parameter type in structural refinement may not refer to 
an abstract type defined outside that refinement 
def func[B <: {def bar(a:B):Boolean}](b:B) = b.bar(b) 
        ^

Jednak jeśli mam następujące prace definicji metody, ale wywołanie daje błąd:

def func[B <: {def bar(a:Any):Boolean}](b:B) = b.bar(b) 

func(new Bar) 

<console>:10: error: type mismatch; 
found : Bar 
required: B 
      func(new Bar) 
      ^

Czy istnieje sposób, aby zrobić to, co chcę, bez zmiany kodu Bar?

Odpowiedz

2

Jest to znany problem z typem abstrakcyjnym zdefiniowanym poza typem strukturalnym dla parametru metody. Po drugie, twoje podejście nie działa, ponieważ sygnatury metod nie są równe (wygląda na to, że przeciążanie metody).

Proponuję zastosować obejście. funkcjonalne podejście definicji sposobu, ponieważ Function1 [-T1 + R], znany jest typ:

class Bar { def bar : Bar => Boolean = _ => true } 
class Foo { def bar : Foo => Boolean = _ => false } 

def func[T <: { def bar : T => Boolean } ](b: T): Boolean = b.bar(b) 

func(new Bar) 
func(new Foo) 

przeciw & Za typu funkcjonalne VS typu metoda definicja here