Я пытаюсь определить структурный тип, определяющий любой набор, который имеет "добавить" метод (например, набор Java). Используя это, я хочу определить несколько функций высшего порядка, которые воздействуют на определенный набор
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]
Это не компилирует со следующей ошибкой
error: Parameter type in structural refinement may not refer to abstract type defined outside that same refinement
Я пытался удалить параметр на GenericCollection и поместить его в метод:
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]
но я получаю другую ошибку:
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]
Кто-либо может дать мне некоторый совет относительно того, как использовать структурный ввод с введенными параметрами краткого обзора в Scala? Или как достигнуть того, что я надеюсь выполнять? Большое спасибо!
Как видно из билета 1906 , вы не можете использовать абстрактный тип, определенный вне структурного типа, из-за отсутствует информация о типе во время выполнения.
Об этом говорится в Справочнике по языку Scala (3.2.7 Составные типы) :
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.
Обычный способ добавления новых методов к типу - неявное преобразование типа.
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)
Если компилятор видит, что тип пропустил метод zap, он преобразует его в тип, имеющий в области видимости метод zap с методом неявного преобразования (здесь list2RichList).
scala> new java.util.ArrayList[AnyRef]() zap (() => 2)
res0: java.util.List[Int] = [2]