2012-10-29 5 views

答えて

22

TypeSynonymInstancesは完全に安全です。部分的に適用されるタイプの同義語のような潜在的に派手なものは禁止されているので、それはすなわち、インスタンス頭部に

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

を型シノニムの右側を入力するのとまったく同じ効果を

と同じされています
instance Bar ([a], [a]) 

ただし、両方のインスタンスにはネストされた型コンストラクタと繰り返し型変数が含まれているため、両方のインスタンスにはFlexibleInstancesが必要です。一般に、これはタイプ同義語を拡張した後のケースであることが多い。

私は彼らがデフォルトでは禁止されている理由が考えられます。

しかし、FlexibleInstancesも完全に安全な拡張です。それが行うことができます最悪の事態はあなたがそのような、私はそれが言語を簡単にするためにだと推測できるFlexibleInstancesはデフォルトでは使用できない理由については

instance Xyzzy String 
instance Xyzzy [a] 

として重複インスタンスを定義しようとした場合、コンパイル時にエラーが発生しています。インスタンスヘッドの標準ルールは、インスタンスの定義がオーバーラップできる唯一の方法は、インスタンスヘッド内の型コンストラクタが同一で​​、重複をチェックするFlexibleInstancesが少し難しいことを保証することです。私はそれを理解したよう

14

は、それは一種の単相性のようなものです制限 - そこは何もそれを退治について間違っはませんが、それはあなたが期待していない可能性があります行動にあなたを開きます。単相性制限は何も害を及ぼさないのと同じように、すべての型はまだ有効です。これは完全に安全でなければなりません。型の同義語には制限があり、単純な名前の短縮よりも好奇心をそそることはできません。(、それらを部分的に適用することはできないので、タイプレベルのラムダは得られません)、その定義の右側でいつでも置き換えることができます。したがって、これらの定義の右辺はインスタンス・ヘッドとしてチェックされることができます(または展開するためにさらにタイプ・シノニムを含んでいます)ので、安全でないことは起こりません。

一方、monomorphismの制限を無効にすると、潜在的に奇妙なパフォーマンス特性が現れます。タイプ同義語インスタンスを有効にすると、奇妙なタイプのクラスエラーが発生する可能性があります。それでは、-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がデフォルトでオンになっていない理由の一部です)。-XOverlappingInstancesをオンにすると、-XFlexibleInstancesをオンにするよりもa much dodgier ideaになります。

5

これまで許可されていましたが、初心者にはハスケルの驚きを少なくするため、禁止されました。

関連する問題