Örüntü eşlemede yöntemin tür çıkarımı ve sınıf türü parametreleri arasındaki fark


9

Type parametresi, bir çevreleme sınıfının aksine bir çevreleme yönteminden geldiğinde desen eşleştirme neden farklı çalışıyor? Örneğin,

trait Base[T]
case class Derived(v: Int) extends Base[Int]

class Test[A] {
  def method(arg: Base[A]) = {
    arg match {
      case Derived(_) => 42
    }
  }
}

hata veriyor

constructor cannot be instantiated to expected type;
 found   : A$A87.this.Derived
 required: A$A87.this.Base[A]
      case Derived(_) => 42
           ^

Ayöntem türü parametresi ne zaman başarıyla derlenir

class Test {
  def method[A](arg: Base[A]) = {
    arg match {
      case Derived(_) => 42
    }
  }
}

Soru, Daniel'in benzer soruya cevap vermeye çalıştığım analizine dayanıyor .

Yanıtlar:


4

% 100 tam cevabım yok, ama sizin için yeterli olabilecek bir işaretçim var.

Scala derleyicisi GADT'lerle (Genelleştirilmiş Cebirsel Veri Türleri) çok özel bir şekilde ilgilenir. Bazı davalar özel işlemlerle çözülürken, bazı davalar çözülmez. Dotty deliklerin çoğunu doldurmaya çalışıyor ve zaten birçok ilgili sorunu çözdü , ancak hala birkaç açık olan da var.

Scala 2 derleyicisindeki özel GADT kullanımının tipik örneği kullanım durumunuzla çok ilgilidir. Şuna bir bakarsak:

def method[A](arg: Base[A]) = {
  arg match {
    case Derived(_) => 42
  }
}

ve dönüş türünü açıkça beyan ederiz A:

def method[A](arg: Base[A]): A 

iyi derlenecek. IDE'niz şikayet edebilir, ancak derleyici buna izin verecektir. Yöntem, bir döndürdüğünü söylüyor A, ancak desen eşleştirme durumu Intteorik olarak derlenmemesi gereken bir Bununla birlikte, derleyicide GADT'lerin özel kullanımı iyi olduğunu söylüyor, çünkü bu belirli desen eşleştirme dalının A"olarak" sabitlendiği Int( Derivedhangisi ile eşleştiğimiz için Base[Int]).

GADT için genel tip parametresi (bizim durumumuzda A) bir yerde bildirilmelidir. Ve işte ilginç kısım - özel derleyici işlemesi, yalnızca kapatma yönteminin type parametresi olarak bildirildiğinde çalışır . Eğer bir tür üyeden ya da çevreleyen özellik / sınıfın tür parametresinden geliyorsa, kendinize tanık olduğunuz gibi derlenmez.

Bu yüzden% 100 tam bir cevap olmadığını söyledim - bunu doğru şekilde belgeleyen somut bir yere (resmi şartname gibi) işaret edemem. Scala GADTs taşınması ile ilgili kaynaklar bir inmesi çiftin arasında blogposts arada harika, ama bundan daha isterseniz derleyici koduna kendiniz içine kazmak zorunda kalacaktır. Bunu tam olarak yapmaya çalıştım ve bu yönteme geldiğini düşünüyorum , ama gerçekten daha derine inmek istiyorsanız, Scala derleyici kod tabanıyla daha deneyimli birine ping atmak isteyebilirsiniz.

Sitemizi kullandığınızda şunları okuyup anladığınızı kabul etmiş olursunuz: Çerez Politikası ve Gizlilik Politikası.
Licensed under cc by-sa 3.0 with attribution required.