簡體   English   中英

是否存在Haskell無法驗證的類型簽名?

[英]Are there type signatures which Haskell can't verify?

本文確定系統F中的類型推斷(在本文中稱為“可打字性”)是不可判定的。 我在其他地方從未聽過的是該論文的第二個結果,即F中的“類型檢查”也是不可判定的。 這里的“類型檢查”問題意味着:給定一個術語t ,輸入T和輸入環境A ,判斷A ⊢ t : T可推導? 這個問題是不可判定的(並且它相當於可打字性的問題)對我來說是令人驚訝的,因為它似乎直覺上應該是一個更容易回答的問題。

但無論如何,鑒於Haskell基於System F(或F-omega,偶數),關於類型檢查的結果似乎表明存在Haskell項t和類型T ,因此編譯器將無法決定t :: T是否有效。 如果是這樣的話,我很好奇這樣的術語和類型是什么......如果不是這樣的話,我有什么誤解?

據推測,理解這篇論文會得到一個建設性的答案,但我有點超出我的深度:)

通過適當地豐富語法,可以使類型檢查成為可判定的。 例如,在論文中,我們將lambdas寫為\\x -> e ; 要鍵入檢查,你必須猜測 x的類型。 但是,使用適當豐富的語法,可以將其寫為\\x :: t -> e ,它將猜測工作從流程中取出。 同樣,在論文中,它們允許類型級lambda是隱含的; 也就是說,如果e :: t ,那么e :: forall a. t e :: forall a. t 做類型檢查,你必須在猜測多少forall的增加,以及何時消除它們。 和以前一樣,您可以通過添加語法使其更具確定性:我們添加兩個新的表達式/\\a. e /\\a. ee [t]以及兩個新的輸入規則,如果e :: t ,那么/\\a. e :: forall a. t /\\a. e :: forall a. t /\\a. e :: forall a. t ,如果e :: forall a. t e :: forall a. t ,然后e [t'] :: t [t' / a] (其中t [t' / a]中的括號是替換括號)。 然后語法告訴我們何時以及添加多少個foralls,以及何時消除它們。

所以問題是:我們可以從Haskell轉到充分注釋的System F術語嗎? 答案是肯定的,這要歸功於Haskell類型系統的一些關鍵限制。 最關鍵的是所有類型都排名第一*。 沒有太多細節,“排名”與你必須在->構造函數的左邊找到一個forall

Int -> Bool -- rank 0?
forall a. (a -> a) -- rank 1
(forall a. a -> a) -> (forall a. a -> a) -- rank 2

特別是,這有點限制了多態性。 我們不能用一級類型輸入這樣的東西:

foo :: (forall a. a -> a) -> (String, Bool) -- a rank-2 type
foo polymorphicId = (polymorphicId "hey", polymorphicId True)

下一個最關鍵的限制是類型變量只能被單形類型替換。 (這包括其他類型變量,如a ,但不是像forall a. a這樣的多態類型。)這確保了部分類型替換保留了一等級。

事實證明,如果你做出這兩個限制,那么不僅類型推斷是可判定的,而且你也得到最小的類型。

如果我們從Haskell轉向GHC,那么我們不僅可以討論什么是可打字的,而且可以討論推理算法的外觀。 特別是在GHC中,有一些擴展可以放寬上述兩個限制; GHC如何在該環境中進行推理? 嗯,答案是它根本就沒有嘗試過。 如果您想使用這些功能編寫術語,那么您必須在第一段中添加我們所討論的鍵入注釋:您必須明確注釋引入和消除forall的位置。 那么,我們可以寫一個GHC的類型檢查器拒絕的術語嗎? 是的,這很簡單:只需使用未注釋的二級(或更高級)類型或不可預測性。 例如,以下內容不進行類型檢查,即使它具有顯式類型注釋並且可以使用rank-two類型:

{-# LANGUAGE Rank2Types #-}
foo :: (String, Bool)
foo = (\f -> (f "hey", f True)) id

*實際上,限制為二級足以使其可判定,但是一級類型的算法可以更有效。 排名三種類型已經給程序員足夠的繩索使推理問題變得不可判定。 我不確定這些事實是否在委員會選擇將Haskell限制為一級類型時已知。

以下是Scala中SKI演算的類型級實現的示例: http//michid.wordpress.com/2010/01/29/scala-type-level-encoding-of-the-ski-calculus/

最后一個示例顯示了無界迭代。 如果你在Haskell中做同樣的事情(我很確定你可以),你有一個“不可表達的表達式”的例子。

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM