باستخدام أنواع Scala الهيكلية مع أنواع مجردة

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