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 sahiptirleftright ve aynı tipte ve alt ağaçlara içerir.
heightherhangi 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 heightparametresi α'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 heightjenerik 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.valuebu 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.valueEtkin 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 |
=====================+=====================================