3 回答

TA貢獻(xiàn)1780條經(jīng)驗(yàn) 獲得超1個贊
存在類型的值,例如,?x. F(x) 是包含某種類型 x和該類型的值的一對F(x)。而like多態(tài)類型的值?x. F(x)是一個具有某種類型并產(chǎn)生 type值的函數(shù)。在這兩種情況下,類型都會關(guān)閉某個類型構(gòu)造器。xF(x)F
請注意,此視圖混合了類型和值。存在證明是一種類型和一種價值。通用證明是按類型(或從類型到值的映射)索引的整個值系列。
因此,您指定的兩種類型之間的區(qū)別如下:
T = ?X { X a; int f(X); }
這意味著:類型的值T包含一個稱為的類型X,一個值a:X和一個函數(shù)f:X->int。類型值的生產(chǎn)者T可以選擇任何類型,X消費(fèi)者對此一無所知X。除了調(diào)用它的一個示例,a并且可以通過將其int賦予來將其轉(zhuǎn)換為一個值f。換句話說,類型的值T知道如何產(chǎn)生int某種方式。好吧,我們可以消除中間類型,X而只是說:
T = int
普遍量化的數(shù)字有些不同。
T = ?X { X a; int f(X); }
這意味著:類型的值T可以給出任何類型的X,它會產(chǎn)生一個值a:X,和功能f:X->int 不管是什么X是。換句話說:類型值的使用者T可以為選擇任何類型X。類型值的產(chǎn)生者T一無所知X,但是它必須能夠a為任何選擇產(chǎn)生一個值X,并能夠?qū)⑦@樣的值轉(zhuǎn)化為一個值int。
顯然,實(shí)現(xiàn)這種類型是不可能的,因?yàn)闆]有程序可以產(chǎn)生每種可以想象的類型的值。除非您允許荒謬之類的話null。
由于一個存在性參數(shù)是一對,因此可以通過currying將一個存在性參數(shù)轉(zhuǎn)換為通用參數(shù)。
(?b. F(b)) -> Int
是相同的:
?b. (F(b) -> Int)
前者是2級生存者。這導(dǎo)致以下有用的屬性:
等級的每個存在量化類型都是等級n+1普遍量化類型n。
有一種標(biāo)準(zhǔn)的算法可以將存在物轉(zhuǎn)換為通用物,稱為Skolemization。

TA貢獻(xiàn)2012條經(jīng)驗(yàn) 獲得超12個贊
我認(rèn)為將存在性類型與通用類型一起解釋是有意義的,因?yàn)檫@兩個概念是互補(bǔ)的,即一個概念與另一個概念“相對”。
我無法回答有關(guān)存在性類型的每一個細(xì)節(jié)(例如給出確切的定義,列出所有可能的用途,它們與抽象數(shù)據(jù)類型的關(guān)系等),因?yàn)槲覍Υ藳]有足夠的了解。我將僅演示(使用Java)HaskellWiki文章聲明存在類型的主要作用:
存在類型可以用于多種不同目的。但是他們要做的是在右側(cè)“隱藏”一個類型變量。通常,出現(xiàn)在右側(cè)的任何類型變量也必須出現(xiàn)在左側(cè)[…]
設(shè)置示例:
以下偽代碼不是完全有效的Java,即使很容易修復(fù)它也是如此。實(shí)際上,這正是我要在此答案中執(zhí)行的操作!
class Tree<α>
{
α value;
Tree<α> left;
Tree<α> right;
}
int height(Tree<α> t)
{
return (t != null) ? 1 + max( height(t.left), height(t.right) )
: 0;
}
讓我為您簡要說明一下。我們正在定義...
Tree<α>表示二叉樹中的節(jié)點(diǎn)的遞歸類型。每個節(jié)點(diǎn)存儲value某種類型的α,并引用相同類型的可選樹left和right子樹。
該函數(shù)height返回從任何葉節(jié)點(diǎn)到根節(jié)點(diǎn)的最遠(yuǎn)距離t。
現(xiàn)在,讓我們將上面的偽代碼height轉(zhuǎn)換為正確的Java語法?。楹啙嵠鹨姡覍⒗^續(xù)省略一些樣板,例如面向?qū)ο蠛涂稍L問性修飾符。)我將展示兩種可能的解決方案。
1.通用型解決方案:
最明顯的解決方法是height通過將類型參數(shù)α引入其簽名來簡單地實(shí)現(xiàn)泛型:
<α> int height(Tree<α> t)
{
return (t != null) ? 1 + max( height(t.left), height(t.right) )
: 0;
}
如果需要,這將允許您聲明變量并在該函數(shù)內(nèi)創(chuàng)建類型為α的表達(dá)式。但...
2.現(xiàn)有類型解決方案:
如果查看我們方法的主體,您會注意到我們實(shí)際上并沒有訪問或使用α類型的任何東西!沒有那種類型的表達(dá)式,也沒有用那種類型聲明的變量……那么,為什么我們必須使height泛型成為根本呢?為什么我們不能簡單地忘記α?事實(shí)證明,我們可以:
int height(Tree<?> t)
{
return (t != null) ? 1 + max( height(t.left), height(t.right) )
: 0;
}
正如我在回答之初所寫的那樣,存在和通用類型本質(zhì)上是互補(bǔ)/雙重的。因此,如果通用類型的解決方案要使通用性height 更高,那么我們應(yīng)該期望存在性類型具有相反的效果:使其不通用,即通過隱藏/刪除類型參數(shù)α。
結(jié)果,您將無法再引用t.value此方法的類型,也不能操作該類型的任何表達(dá)式,因?yàn)闆]有標(biāo)識符綁定到該方法。(?通配符是一個特殊的令牌,而不是“捕獲”類型的標(biāo)識符。)t.value實(shí)際上已經(jīng)變得不透明了;也許您唯一仍能做的就是將其類型轉(zhuǎn)換為Object。
摘要:
===========================================================
| 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 |
- 3 回答
- 0 關(guān)注
- 591 瀏覽
添加回答
舉報