2009-09-25 58 views
19

排名較高的類型看起來很有趣。從Haskell wikibook談到這個例子:你在Haskell中發現了哪些更高級的類型?

foo :: (forall a. a -> a) -> (Char,Bool) 
foo f = (f 'c', f True) 

現在我們可以不用編譯爆炸評估foo id。這個例子在本書中被我在其他幾個地方看到的現實世界的例子很快地追蹤到:ST monad和runST。這很酷。

但是我還沒有遇到這樣的情況,我通過編寫自己的函數來解決一個問題,使用更高級的參數。你有嗎?你在野外有什麼樣的等級2或等級-n多態性的例子?

回答

7

看看Darcs source中的功能,如withRepoLock

Darcs支持多種存儲格式,並且支持通過類型類型表示。因此,您可以編寫通用於存儲庫格式的代碼。實際讀取磁盤存儲庫時,您需要通過一些常用代碼來分派該代碼,以找出存儲庫所在的格式並選擇正確的類型實例。

3

這可能是您遇到問題,排名較高的類型有用,但未能實現。例如在Darcs的例子中,他們可以很容易地實現它,沒有更高的排名類型。相反,調用者必須確保它們符合某些函數的前提條件,例如爲存儲庫格式選擇正確的函數實例。

排名較高的類型的優點是它將責任從程序員轉移到編譯器。使用傳統方法,如果Darcs開發人員對存儲庫類型犯了錯誤,則結果可能是運行時錯誤或數據損壞。對於排名較高的類型,開發人員在編譯時會收到類型錯誤。

8

Weirich和Washburnn的「盒子去香蕉」! (paper,slides

這是一個非常原始的,可能稍有不準確的解釋:給定一個歸納類型,BGB讓你表示這種類型的函數空間是「積極的」 - 它們從不在他們的論點中區分歧視。它們至多包括他們的參數作爲其他值的一部分(通常是相同類型的)。

Weirich + Washburn使用它得到一個可能的adequate HOAS代表lambda演算-XRankNTypes Haskell(有人證明它足夠嗎?)。

我用它here(警告:亂碼)把一個

(forall g . GArrow g => g() x -> g() y) 

(forall g . GArrow g => g x y) 

這工作,因爲秩爲2的多態類型不能「考察」結構它的論點 - 它所能做的就是將這個論點「粘貼」到更大的結構中。一些欺騙讓我找出粘貼發生的地方,然後我將粘貼點(如果有的話)返回到GArrow的輸入。

你不能這樣做Control.Arrow類,因爲整個Haskell函數空間通過arr「泄漏」到它。