2010-04-28 20 views
10

Próbuję zdefiniować typ strukturalny definiujący kolekcję, która ma metodę "dodaj" (na przykład kolekcja java). Korzystanie z tego, chciałbym zdefiniować kilka funkcja wyższego rzędu, które działają na pewnej kolekcjiUżywanie typów strukturalnych Scala z typami abstrakcyjnymi

object GenericTypes { 
    type GenericCollection[T] = { def add(value: T): java.lang.Boolean} 
} 

import GenericTypes._ 
trait HigherOrderFunctions[T, CollectionType[X] <: GenericCollection[X]] { 
    def map[V](fn: (T) => V): CollectionType[V] 
    .... 
} 

class RichJList[T](list: List[T]) extends HigherOrderFunctions[T, java.util.List] 

To nie skompilować z powodu następującego błędu

error: Parameter type in structural refinement may not refer to abstract type defined outside that same refinement 

próbowałem usunięcie parametru na GenericCollection i umieszczenie go na metodzie:

object GenericTypes { 
    type GenericCollection = { def add[T](value: T): java.lang.Boolean} 
} 
import GenericTypes._ 
trait HigherOrderFunctions[T, CollectionType[X] <: GenericCollection] 

class RichJList[T](list: List[T]) extends HigherOrderFunctions[T, java.util.List] 

ale dostaję kolejny błąd:

error: type arguments [T,java.util.List] do not conform to trait HigherOrderFunctions's type parameter bounds [T,CollectionType[X] <: org.scala_tools.javautils.j2s.GenericTypes.GenericCollection] 

Czy ktoś może mi doradzić jak używać typowania strukturalnego przy pomocy parametrów pisanych abstrakcyjnie w Scali? Albo jak osiągnąć to, co chcę osiągnąć? Dzięki wielkie!

Odpowiedz

4

Jak widać w ticket 1906 nie można użyć typu abstrakcyjnego zdefiniowanego poza typem konstrukcji z powodu braku informacji o typie w czasie wykonywania.

ta jest zawarta w Scala Language Reference (3.2.7 Compound Types):

Within a method declaration in a structural refinement, the type of 
any value parameter may only refer to type parameters or abstract types that are 
contained inside the refinement. 

Zwykłym sposobem na dodanie nowych metod typu jest niejawna konwersja typu.

trait HigherOrderFunctions[T, CC[_]] { 
    def zap[V](fn:() => V): CC[V] 
} 

class RichJList[T](list: java.util.List[T]) extends HigherOrderFunctions[T, java.util.List]{ 
    def zap[V](fn:() => V): java.util.List[V] = { 
     val l = new java.util.ArrayList[V] 
     l add fn() 
     l 
    } 
} 
implicit def list2RichList[T](l : java.util.List[T]) = new RichJList(l) 
new java.util.ArrayList[AnyRef]() zap (() => 2) 

Jeśli kompilator widzi, że rodzaj brakowało ZAP metodę będzie przekonwertować go do typu, który ma zap sposób niejawny z metody konwersji (tutaj list2RichList) w zakresie.

scala> new java.util.ArrayList[AnyRef]() zap (() => 2) 
res0: java.util.List[Int] = [2] 
Powiązane problemy