Biraz karışıklığa yol açarak bu karışıklığın bir kısmını başlatmak için telafi edeyim. İnsanları daha aşina olma eğiliminde olduğundan, benzetmeyi bunu açıklamak için değer seviyesinden kullanmayı seviyorum.
Tür yapıcısı, bir türü "oluşturmak" için tür bağımsız değişkenlerine uygulayabileceğiniz türdür.
Değer yapıcısı, bir değeri "oluşturmak" için değer bağımsız değişkenlerine uygulayabileceğiniz bir değerdir.
Değer yapıcılara genellikle "işlevler" veya "yöntemler" denir. Bu "yapıcıların" aynı zamanda "polimorfik" olduğu söylenir (çünkü bunlar "şekil" şeklinde "şeyler" oluşturmak için kullanılabilirler) veya "soyutlamalar" (çünkü farklı polimorfik örneklemeler arasında neyin değiştiğinin üzerinde soyutlandıkları için) kullanılabilir.
Soyutlama / polimorfizm bağlamında, birinci dereceden soyutlamanın "tek kullanımı" anlamına gelir: bir kez bir tür üzerinde soyutlanırsınız, ancak bu türün kendisi hiçbir şey üzerinde soyut olamaz. Java 5 jenerikleri birinci derecedir.
Yukarıdaki soyutlamaların birinci dereceden yorumu şu şekildedir:
Tür yapıcısı, uygun bir türü "oluşturmak" için uygun tür argümanlarına uygulayabileceğiniz bir türdür.
Değer yapıcı, uygun bir değeri "oluşturmak" için uygun değer bağımsız değişkenlerine uygulayabileceğiniz bir değerdir.
Dahil herhangi bir soyutlama vurgulamak için (sanırım bu "sıfır-sıra" diyebiliriz, ama bu herhangi bir yerde kullanılan görmedim), değer 1
veya türü gibi String
, biz genellikle bir şey "uygun" bir değer veya tip olduğunu söylüyorlar.
Uygun bir değer, argümanları beklememesi anlamında "hemen kullanılabilir" (bunlar üzerinde soyutlama yapmaz). Bunları kolayca yazdırabileceğiniz / inceleyebileceğiniz değerler olarak düşünün (bir işlevi seri hale getirmek hile yapıyor!).
Uygun bir tür, değerleri sınıflandıran bir türdür (değer yapıcılar dahil), tür yapıcılar herhangi bir değeri sınıflandırmaz (uygun bir tür elde etmek için önce doğru tür bağımsız değişkenlerine uygulanması gerekir). Bir türü başlatmak için, uygun bir tür olması gerekir (ancak yeterli değildir). (Soyut bir sınıf veya erişiminiz olmayan bir sınıf olabilir.)
"Yüksek mertebe" basitçe polimorfizm / soyutlamanın tekrarlanan kullanımı anlamına gelen jenerik bir terimdir. Polimorfik tipler ve değerler için aynı anlama gelir. Somut olarak, daha üst düzey bir soyutlama, bir şeyin üzerine soyutlanan bir şeyden soyutlanır. Tipler için, "daha üst düzey" terimi daha genel "daha üst düzey" in özel amaçlı bir sürümüdür.
Böylece, karakterizasyonumuzun üst düzey versiyonu şöyle olur:
Tür yapıcısı, uygun bir türü (kurucu) "oluşturmak" için tür argümanlarına (uygun türler veya tür yapıcıları) uygulayabileceğiniz bir türdür.
Değer yapıcısı, uygun bir değeri (yapıcı) "oluşturmak" için değer bağımsız değişkenlerine (uygun değerler veya değer yapıcıları) uygulayabileceğiniz bir değerdir.
Böylece, "üst düzey" basitçe "X üzerinden soyutlama" derken, gerçekten demek istediğiniz anlamına gelir! Bu X
soyutlanan, kendi "soyutlama haklarını" kaybetmez: istediği her şeyi soyutlayabilir. (Bu arada, burada "soyut" fiilini kullanıyorum: bir değerin veya türün tanımı için gerekli olmayan bir şeyi dışarıda bırakmak, böylece soyutlamanın kullanıcısı tarafından bir argüman olarak değiştirilebilir / sağlanabilir .)
Aşağıda, uygun, birinci dereceden ve daha yüksek seviyeli değerler ve türlerden bazı örnekler (Lutz'un sorularını e-posta ile esinlenerek) görebilirsiniz:
proper first-order higher-order
values 10 (x: Int) => x (f: (Int => Int)) => f(10)
types (classes) String List Functor
types String ({type λ[x] = x})#λ ({type λ[F[x]] = F[String]})#λ
Kullanılan sınıflar şu şekilde tanımlanmıştır:
class String
class List[T]
class Functor[F[_]]
Sınıfları tanımlayarak dolaylı yoldan kaçınmak için, bir şekilde doğrudan Scala'da ifade edilemeyen anonim tip işlevlerini ifade etmeniz gerekir, ancak çok fazla sözdizimsel yükü olmayan yapısal türleri kullanabilirsiniz ( #λ
-style, https://stackoverflow.com adresinden kaynaklanmaktadır. / users / 160378 / retronym afaik) ile ilişkili olan kısmını dışarı aktarmak suretiyle yedek oluşturmanız gerekir :
Scala'nın anonim tür işlevlerini destekleyen bazı varsayımsal gelecekteki sürümlerinde, bu son satırı örneklerden kısaltabilirsiniz:
types (informally) String [x] => x [F[x]] => F[String]) // I repeat, this is not valid Scala, and might never be
(Kişisel bir notta, "daha yüksek türler" hakkında konuştuğum için pişman oldum, sonuçta sadece türler! Kesinlikle netleştirmeniz gerektiğinde, "type constructor parametresi", "type constructor member" gibi şeyleri söylemenizi öneririm. veya "tür oluşturucu takma adı" nı seçerek yalnızca uygun türlerden bahsetmediğinizi vurgulayın.)
ps: Konuları daha da karmaşıklaştırmak için, "polimorfik" farklı bir şekilde belirsizdir, çünkü polimorfik tip bazen Forall T, T => T
polimorfik değerleri sınıflandırdığından (Scala'da bu değer, yapısal tip olarak yazılmıştır {def apply[T](x: T): T = x}
)