ملاحظة مضحكة حول الأنواع الهيكلية (العودية) في سكالا
-
30-09-2019 - |
سؤال
كنت بحاجة إلى بعض النوع الهيكلي المتكرر في جزء من الكود باستخدام السمات والنوع الهيكلي كقيد معلمة النوع. لقد نجحت بشكل جيد ، لكن في وقت لاحق تعلمت أن سكالا لا تدعم الأنواع الهيكلية العودية.
لذلك هل يمكن لأحد أن يشرح لي لماذا يعمل هذا بشكل جيد:
scala> trait Test[M[A] <: { def map[B](f: A => B) : M[B] } ] {}
defined trait Test
وهذا ليس:
scala> def test[M[A] <: { def map[B](f: A => B) : M[B] } ] = null
<console>:5: error: illegal cyclic reference involving type M
def test[M[A] <: { def map[B](f: A => B) : M[B] } ] = null
المحلول
أعتقد أن هذا خلل في المترجم. يعرض الرمز التالي نفس سلوك الرمز الأولي الخاص بك:
trait Test[M[A] <: { def map: M[A] } ] {}
def test[M[A] <: { def map: M[A] } ] = null
ينتج عنه خطأ في وقت الترجمة: "مرجع دوري غير قانوني".
والرمز التالي لا (أي أنه يجمع بشكل جيد):
type S[M] = { def map: M }
trait Test[M[A] <: S[M[A]] ] {}
def test[M[A] <: S[M[A]] ] = null
الفرق الوحيد هو أن الكتابة الهيكلية يتم تطبيقها عبر نوع الاسم المستعار هنا.
نصائح أخرى
يلقي مقتطف الكود الأول أيضًا خطأ في Scala 2.7.7final:
scala> trait Test[M[A] <: { def map[B](f: A => B) : M[B] } ] {}
<console>:4: error: illegal cyclic reference involving type M
trait Test[M[A] <: { def map[B](f: A => B) : M[B] } ] {}
^
ما هو إصدار Scala الذي تستخدمه؟
لا تنتمي إلى StackOverflow