Использование Scala Construal Types с абстрактными типами

StackOverflow https://stackoverflow.com/questions/2726364

  •  02-10-2019
  •  | 
  •  

Вопрос

Я пытаюсь определить структурный тип, определяющий любую коллекцию, которая имеет метод «Добавить» (например, коллекция 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. Вы не можете использовать абстрактный тип, определенный вне структурный тип из-за отсутствующего типа информации во время выполнения.

Это указано в Ссылка на скалью (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]
Лицензировано под: CC-BY-SA с атрибуция
Не связан с StackOverflow
scroll top