Frage

Ich versuche, eine Strukturtyp definieren, jede Sammlung zu definieren, die eine „add“ Verfahren (zum Beispiel eine Java-Sammlung) hat. Mit dieser, ich möchte ein paar Funktionen höherer Ordnung definieren, die auf einer bestimmten Sammlung arbeiten

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]

Dies lässt sich nicht kompilieren mit dem folgenden Fehler

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

Ich habe versucht, den Parameter auf GenericCollection entfernen und auf die Methode setzen:

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]

, aber ich bekomme einen anderen Fehler:

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]

geben kann jemand mir einige Ratschläge, wie mit abstrakten typisierte Parameter in Scala Struktur Typisierung zu bedienen? Oder wie zu erreichen, was ich bin auf der Suche zu erreichen? Vielen Dank!

War es hilfreich?

Lösung

Wie können Sie in Ticket 1906 nicht verwenden können, abstrakter Typ außerhalb des Strukturtypen definiert durch Typinformationen zur Laufzeit fehlt.

Dies ist in der Scala Sprachreferenz angegeben wird (3.2.7 Verbindungstypen) :

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.

Der üblicher Weg, neue Methoden zu einer Art hinzuzufügen, ist durch implizite Typumwandlung.

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)

Wenn der Compiler sieht, dass die Art die zap Methode verpassten sie es auf eine Art konvertieren, die die zap-Methode mit einer impliziten Konvertierungsmethode (hier list2RichList) in ihrem Umfang hat.

scala> new java.util.ArrayList[AnyRef]() zap (() => 2)
res0: java.util.List[Int] = [2]
Lizenziert unter: CC-BY-SA mit Zuschreibung
Nicht verbunden mit StackOverflow
scroll top