2012-10-29 57 views

回答

22

TypeSynonymInstances是完全安全的。因爲任何潛在的花式像部分應用類型同義詞不允許,它具有完全一樣在實例頭打字類型同義詞的右手側,即

type Foo a = ([a], [a]) 
instance Bar (Foo a) 

相同的效果是一樣的

instance Bar ([a], [a]) 

但是,請注意,兩個實例都需要FlexibleInstances,因爲它們包含嵌套類型構造函數以及重複類型變量。一般來說,擴展類型同義詞之後通常會出現這種情況。

我想可能是他們被默認禁止的原因。

然而,FlexibleInstances也是一個非常安全的擴展。它能做的最糟糕的是會導致編譯時錯誤,如果你嘗試定義重疊的情況下,如

instance Xyzzy String 
instance Xyzzy [a] 

至於爲什麼FlexibleInstances是默認不可用,我只能猜測,這是簡化的語言。實例頭的標準規則確保實例定義可以重疊的唯一方式是如果實例頭中的類型構造函數是相同的,而檢查重疊的稍微困難一些。

14

據我瞭解,它有點像單態限制 - 沒有什麼錯誤關於擺脫它,但它打開你的行爲,你可能不希望。就像單形態限制不會傷害任何東西 - 所有類型都是有效的 - 這也應該是完全安全的:無論如何都會限制類型同義詞,從而阻止它們做簡單的名稱縮寫(,例如,you不能部分應用它們,所以我們不會獲得類型級別的lambda表達式),因此您可以隨時將它們替換爲定義的右側。因此,由於可以將這些定義的右側作爲實例頭部進行檢查(或者包含進一步擴展的類型同義詞),因此不應該發生任何不安全事件。另一方面,正如禁用單態限制打開您可能會出現的奇怪性能特徵一樣,啓用類型同義詞實例也會打開您可能存在的奇怪類型類錯誤。因此,讓我們能夠-XTypeSynonymInstances,並嘗試用一種代名詞寫一個實例:

Prelude> :set -XTypeSynonymInstances 
Prelude> instance Num String where (+) = (++) 

<interactive>:3:10: 
    Illegal instance declaration for `Num String' 
     (All instance types must be of the form (T a1 ... an) 
     where a1 ... an are *distinct type variables*, 
     and each type variable appears at most once in the instance head. 
     Use -XFlexibleInstances if you want to disable this.) 
    In the instance declaration for `Num String' 

String看起來像一個普通的舊類型,所以這可能是在第一個令人驚訝的;但它確實是[Char],所以根據Haskell 2010嚴格的規則,這個實例是無效的。如果我們通過-XFlexibleInstances轉彎轉放寬這些規則(順便說一下,implies -XTypeSynonymInstances),這個例子現在的工作:

Prelude> :set -XFlexibleInstances 
Prelude> instance Num String where (+) = (++) 
... errors about undefined methods ... 
Prelude> "a" + "b" 
"ab" 

但事情變得醜陋快:

Prelude> instance Eq String where 
Prelude> "a" == "b" 

<interactive>:8:5: 
    Overlapping instances for Eq [Char] 
     arising from a use of `==' 
    Matching instances: 
     instance Eq a => Eq [a] -- Defined in `GHC.Classes' 
     instance Eq String -- Defined at <interactive>:7:10 
    In the expression: "a" == "b" 
    In an equation for `it': it = "a" == "b" 

再次,即使String樣子一個獨特的類型,我們已經有一個[a]的實例,所以這個與它重疊。 (實際上,這可能是默認情況下爲什麼-XFlexibleInstances未啓用的一部分。)並且開啓-XOverlappingInstancesa much dodgier idea比開啓-XFlexibleInstances

5

它曾經被允許,但爲了讓Haskell減少對初學者的驚喜,它被禁止。

相關問題