2016-07-23 22 views
5

Bir tür öğesinin bir tür parametresine ayıklandığı Aux şablonunun (şekilsiz ve başka bir yerde kullanıldığı gibi) biraz bir fikrim var ve bunun bir argüman olduğunu aynı argüman listesindeki argümanların olabileceğini biliyorum. Birbirine bağlı - ama genel olarak ne için kullanıldığı ve hangi problemleri çözdüğünün net değil. Örneğin, şu anda bir beyaz kutu makrosu tarafından döndürülen daha spesifik bir türün nasıl korunacağını ve nasıl çalışacağını anlamaya çalışıyorum - bu Aux için bir örnek notu mu?Aux düzeni Scala'da ne yapar?

Basit bir açıklama var mı?

+0

Bazı tartışmalar için cevabım [burada] (http://stackoverflow.com/a/34548518/334519) bakın. –

cevap

5

Basitçe söylemek gerekirse, bu model iki genel tür parametresi arasında bir ilişki kurabilmenizi sağlar.

davası sınıflar için Size genel HList temsil verir şekilsiz LabelledGeneric tipi sınıfına bir göz atalım:

trait LabelledGeneric[T] { 
    type Repr 
} 

T yani LabelledGeneric[MyCaseClass] size MyCaseClass ait hList temsilini verecek girdi türüdür. Repr, çıktı tipidir, yani T'a karşılık gelen HList tipi.

Generic örneğini alan ve çıkış türünün başka bir parametresine ihtiyaç duyan bir yöntem yazalım. Örneğin biz Scala burada gen veya keys erişmesine izin vermez, çünkü bu işe yaramazsa Bunun dışında bir etiketlenmiş jenerik

def fieldNames[T](implicit gen: LabelledGeneric[T], keys: Keys[gen.Repr]): keys.Repr … 

ait alan adlarını toplamak için Keys kullanabilirsiniz. Ya beton tipine veya tip değişkenine sahip olabiliriz. Aux devreye giriyor

Ve bu: Bu bize bir tip değişken içine "lift" gen.Repr yapalım:

object Generic { 
    type Aux[T, Repr0] = Generic[T] { type Repr = Repr0 } 
} 

olarak, Aux tip bir tür değişkene Repr bize bir yol verir görebilirsiniz, bu yüzden nihayet foo tanımlayabiliriz: Eğer Prolog aşina değilseniz

def foo[T, Repr, K](
    implicit gen: LabelledGeneric.Aux[T, Repr], 
    keys: Keys.Aux[Repr, K] 
): K … 

Eğer kanıtlayan bir yüklem olarak Aux okuyabilir iki tip değişken arasındaki ilişki. Yukarıdaki örnekte "LabelledGeneric, Repr'un T etiketli genel temsili olduğunu kanıtlar ve Keys.Aux, K'nin Repr'nin tüm anahtarlarının bir listesi olduğunu kanıtlar" şeklinde okuyabilirsiniz.