2016-11-19 4 views
1

this質問では、タグなしの共用体はサブタイプの形式として記述されています。タグなしの共用体は型クラスを許可するのと同じですか?

タイプクラスもサブタイプの一種です。

概念的には同等ですか?どういたしまして、これらをHaskellでどのように実装するのですか?

+4

私は、すべての値が正確に_one_型であるため、伝統的に定義されるように、Haskellにはサブタイプがないと主張します。型抜きは、ユーザー定義のポリモーフィズムを可能にするために、型の言語を拡張する単なる方法です。つまり、 'x'の値は' C a => a'型であり、 'C'は' a'の規則に従わなければなりません。それでも 'x'はちょうど1つの型を持っています。これはOOPyのサブタイプと対比されます。ここで、値 'x'は複数の型を持ちます:基本型、および基本型からサブクラスを持つ型。 – hao

+1

もう一つのより賢明な議論:サブタイプ化は、Haskellコンパイラが持っているDHMスタイルのプリンシパル型の型推論を禁止しますが、typeclassesはそうしません。 – hao

+3

@ haoformayorの点について詳しく述べる:サブタイプとアドホック多型を混同しないでください。サブタイプは、アドホック多型の1つの風味であり、タイプクラスはむしろ異なるものです。 –

答えて

4

タイプクラスもサブタイプの一種です。

これらはありません。説明のために、のは、私はその質問に示唆したTypeScript examplesに戻ってみましょう:私たちは組合型を持つ値を持っている場合は

は、我々は唯一の労働組合のすべてのタイプに共通しているメンバー にアクセスすることができます。ここで

interface Bird { 
    fly(); 
    layEggs(); 
} 

interface Fish { 
    swim(); 
    layEggs(); 
} 

function getSmallPet(): Fish | Bird { 
    // ... 
} 

let pet = getSmallPet(); 
pet.layEggs(); // okay 
pet.swim(); // errors 

getSmallPetの戻り値の型はFishBirdが、メンバーFishBirdの両方に共通のメンバーとして持っている両方のスーパータイプでもありません。 Fishでもあり、aであり、従ってBirdである。型クラスで何が起こる

はかなり異なっている:

foo :: Num a => a -> a 
foo x = (x * x) + x 

ながら(3 :: Integer)(7.7 :: Double)も持っていることをNumに対応するスーパータイプがあるという意味ではありません両方foo (3 :: Integer)foo (7.7 :: Double)仕事、。むしろ、Num a => a -> aは、aの選択は、Numのインスタンスを持つ必要があります(Numはタイプではないことを強調しておく価値があります)。(*)(+)の適切な実装が選択されたタイプに適しています。 OOPメソッドとは異なり、(*)(+)は特定のタイプに属していないため、IntegerDoubleの両方で使用するためにスーパータイプを導入する必要はありません。

+0

この回答は多くの助けになります、ありがとうございます。それにもかかわらず、「ペット」の例は型クラスを介して実装することもできるので、2つの概念が少なくとも関連していると感じています。 「型クラスの制約は、タグなしの共用体ほど強力ですか? (これはおそらくフォローアップの質問として適していますが)。 – ThreeFx

+3

@ThreeFxこの場合、同じ目標を達成するための2つの異なる方法があると言えます。ところで、TypeScriptの例で、 'fish'と' Bird'が拡張する 'layEggs'メソッドを持つ' Oviparous'インターフェースを持っていれば、タグなしのアスペクトは議論には必須ではないことに注意してください基本的な違いは同じままです。関連性のある、多少接線的な質問:[*パラメトリック多型対アドホック多型*](http://stackoverflow.com/q/6730126/2751851)。 – duplode

関連する問題