Varolan türleri evrensel tiplerle birlikte açıklamanın mantıklı olduğunu düşünüyorum, çünkü iki kavram birbirini tamamlayıcı niteliktedir, yani biri diğerinin "zıttı" dır.
Varoluşçu türlerle ilgili her ayrıntıya cevap veremiyorum (tam bir tanım vermek, tüm olası kullanımları listelemek, soyut veri türleriyle ilişkilerini vb.) Çünkü bunun için yeterince bilgili değilim. Ben sadece (Java kullanarak) bu HaskellWiki makalenin varoluşçu türlerin temel etkisi olarak belirttiklerini göstereceğim:
Varoluşçu tipleri edilebilir kullanılan birkaç farklı amaçlar için. Ancak yaptıkları şey sağdaki tip değişkenini 'gizlemek'. Normalde, sağda görünen herhangi bir tür değişkeni de solda görünmelidir […]
Örnek kurulum:
Aşağıdaki sözde kod, düzeltmek için yeterince kolay olsa da, oldukça geçerli bir Java değildir. Aslında, bu cevapta yapacağım şey tam olarak bu!
class Tree<α>
{
α value;
Tree<α> left;
Tree<α> right;
}
int height(Tree<α> t)
{
return (t != null) ? 1 + max( height(t.left), height(t.right) )
: 0;
}
Bunu kısaca açıklayayım. Tanımlıyoruz…
Tree<α>
ikili ağaçtaki bir düğümü temsil eden özyinelemeli tip . Her düğüm avalue
tipinde bir a depolar ve isteğe bağlı referanslara sahiptirleft
right
ve aynı tipte ve alt ağaçlara içerir.
height
herhangi bir yaprak düğümünden kök düğüme en uzak mesafeyi döndüren bir işlevt
.
Şimdi yukarıdaki sahte kodu height
uygun Java sözdizimine çevirelim! (Kısaca nesne yönelimi ve erişilebilirlik değiştiricileri gibi kısacası çıkarmaya devam edeceğim.) İki olası çözüm göstereceğim.
1. Evrensel tip çözüm:
En belirgin düzeltme, imza height
parametresi α'yı imzasına sokarak genel bir yöntem oluşturmaktır :
<α> int height(Tree<α> t)
{
return (t != null) ? 1 + max( height(t.left), height(t.right) )
: 0;
}
Bu, isterseniz değişkenleri bildirmenize ve bu işlevin içinde α türünde ifadeler oluşturmanıza olanak tanır . Fakat...
2. Varoluşçu tip çözüm:
Metodumuzun vücuduna bakarsanız, α ! Bu türden hiçbir ifade veya bu türle bildirilen herhangi bir değişken yok ... Öyleyse, neden height
jenerik yapmamız gerekiyor ? Neden α'yı unutamıyoruz ? Sonuç olarak şunları yapabiliriz:
int height(Tree<?> t)
{
return (t != null) ? 1 + max( height(t.left), height(t.right) )
: 0;
}
Bu cevabın en başında yazdığım gibi, varoluşsal ve evrensel tipler tamamlayıcı / ikili niteliktedir. Bu nedenle, evrensel tip çözüm height
daha genel hale getirilecekse , varoluşçu tiplerin zıt etkiye sahip olmasını beklemeliyiz: daha az genel hale getirmek , yani type parametresini gizlemek / kaldırmak α .
Sonuç olarak, artık t.value
bu yöntemin türüne başvuramaz veya bu türden herhangi bir ifadeyi değiştiremezsiniz, çünkü herhangi bir tanımlayıcı bağlı değildir. ( ?
Joker karakter , bir türü "yakalayan" bir tanımlayıcı değil, özel bir işarettir.) t.value
Etkin bir şekilde opak hale gelmiştir; belki de onunla yapabileceğiniz tek şey onu yazmaktır Object
.
Özet:
===========================================================
| universally existentially
| quantified type quantified type
---------------------+-------------------------------------
calling method |
needs to know | yes no
the type argument |
---------------------+-------------------------------------
called method |
can use / refer to | yes no
the type argument |
=====================+=====================================