8

olarak uygulanamıyor. Başlığı another question üzerinden kırdığımda, alakalı görünen farklı bilmecelere rastladım.Temsil tipi, üye türü

error: overriding type Peer in trait Fenced with bounds >: Nothing <: Sys[this.Peer]; 
type Peer has incompatible type 
     def makeFence[S <: Sys[S]] = new Fenced { type Peer = S#Peer } 
                ^

Neden: hata şöyledir Nerede

trait Sys[S <: Sys[S]] { 
    type Peer <: Sys[Peer] 
} 

trait Fenced { 
    type Peer <: Sys[Peer] 
} 

def makeFence[S <: Sys[S]] = new Fenced { type Peer = S#Peer } 

: Bu onlardan biri mi? gerçekten gösterim türü karakteriyle Ben sorunları çözmez, Rex'in cevabı Fenced nesne yapılandırılmasını mümkün kılarken


(ayrıca önemli değildi, Sys kendinden tip _:S => eklemeye çalıştık) Bir tür projeksiyon kullanırken kaybolmak (S#Peer). Daha zor kısıtlamalar getiren başka bir senaryo ile geldim; Hala neden aradığınızı kısıtlamaları tamamen emin değilim

trait Test[S <: Sys[S]] { 
    def make[T <: Sys[T]](): Unit 

    make[S#Peer]() 
} 

error: type arguments [S#Peer] do not conform to method make's type 
     parameter bounds [T <: Sys[T]] 
       make[S#Peer]() 
       ^
+0

Temel problemin “A [B <: Sys [B]]' ye (iyi) karşı olduğunu, A özelliği (A tipi B <: Sys [B]} '(yani her şey). Ama ben gerçekten tip üyelerle çalışmam gerekiyor, benim durumumda tip parametrelerini tanıyamıyorum. –

+0

Neyi başarmaya çalışıyorsunuz? 'S # Peer',' S''den Peer'' dir, fakat 'Fenced'' akranın _its_' Peer'' S'' olmasını ister, bu da (yüzey seviyesi) uyumsuzluğu üretir. Mantıksal olarak uyumsuz olup olmadığı sanırım türleri basit takma adlar veya sahiplik beyanları olarak görüp görmediğinize bağlıdır. Ne yazık ki, Scala bu konuda tamamen tutarlı değil. Sadece "Çitli" bir "Sys" olan bir türü var mı? –

+0

@RexKerr - niyet açık değilse üzgünüm. Bağlantılı sorular tüm bağlamı verir. Temel olarak, ihtiyacım olan şey (bence), birbirinden atıfta bulunulan iki bağlantılı sistemi, dış sistemden geçmeme izin veren bir şekilde tanımlamaktır; S <: Sys [S] ve sadece dış sistemin tip üyelerini kullanarak diğer akran sistemini tam olarak yerleştirebilme. Buradaki tip projeksiyonlarının sınırlarını zorluyorum. Bu soru, dış sistemin bir tüketici içindeki akran türünü yeniden diriltmenin mümkün olmadığını söyleyerek bunu açıklamaya çalışır. –

cevap

3

, ama burada bir ihtimal: Bu çekirdek sorunu olduğunu düşünüyorum (ve gerektirir)

trait Sys[S <: Sys[S]] { 
    type Peer <: Sys[Peer] 
} 

trait Fenced { 
    type MySys <: Sys[MySys] 
    type Peer = MySys#Peer 
} 

def makeFence[S <: Sys[S]] = new Fenced{ type MySys = S } 

Bu verir Peer ve Fenced içinde orijinal dış türüne erişim. Fenced'un bunu yapıp yapamayacağını veya dış tipler arasında soyut olup olmamasından emin değilim.

+0

Çok ilginç bir yaklaşım, type parametresini type üyesine taşıyor. Evet, her iki tipte de çitle çevrili bir problem yok. Bunu tüm sonuçlara kadar oynamak zorundayım, ama en azından bu benim için yeni bir düşünce, teşekkürler!Fenced' '' in Peer' tip eleman için Sistemi [eş] 'kısıtlama: bu' Eş

+0

Bu yalnızca Sys' 'bir değişmez 'S'ye ile çalışır. Sys [f: değil –

+0

geçerli bir çözüm değil, ama genel olarak bir 'val f = makeFence [X]' Bu yaklaşımla, bu olmayacak durumda olduğunu 'f.Peer

3

Sys 'tür parametre kovaryantı yapabilir misiniz? Örneğin, bu derler: Artık

trait Sys[+S <: Sys[S]] { type Peer <: Sys[Peer] } 
trait Fenced { type Peer <: Sys[Peer] } 

def makeFence[S <: Sys[S]] = new Fenced { type Peer = S#Peer } 

eğer (sadece REPL copy-paste kolaylık bir nesne sarılmış) şu var:

object Example { 
    case class SysX(i: Int) extends Sys[SysX] { type Peer = SysY } 
    case class SysY(j: Int) extends Sys[SysY] { type Peer = SysX } 
} 

import Example._ 

Ben beklediğiniz gibi çalışır:

scala> val fenceX = makeFence[SysX] 
fenceX: java.lang.Object with Fenced{type Peer = Example.SysX#Peer} = ... 

scala> val y: fenceX.Peer = SysY(1) 
y: fenceX.Peer = SysY(1) 

scala> val y: fenceX.Peer = SysX(1) 
<console>:15: error: type mismatch; 
found : Example.SysX 
required: fenceX.Peer 
     val y: fenceX.Peer = SysX(1) 

Hangi (bence) istediğin nedir?

+0

Üzgünüz Travis, ama 'S'ye değişmez :-( –

+0

@Travis Merhaba Travis kalmalıdır. Ben tam anlamıyorum ama öğrenmeye çalışıyorum. Eğer onun ko- çalışır neden lütfen açıklayabilir varyant ve değişmez ise çalışmıyor? – Jatin