2017-09-20 11 views
3

デフォルトの実装が提供されているため、以下ではインスタンス宣言が必要な理由について不明な点があります。インスタンス宣言

module Example where 

class Eq a => EQ a where 
    eq :: a -> a -> Bool 
    eq = (==) 

-- why is this instance declaration needed? 
instance EQ Int where 
    eq = (==) 

f :: Int -> Int -> Bool 
f = eq 

インスタンスの宣言を省略すると、エラーが発生します。私はHaskellのレポートのどこかで説明されていると確信していますが、それを見つけるのにしばらく時間がかかります。

+3

'class'インスタンスが' instance'を自動的に構築しないためです。 –

+0

@ WillemVanOnsemに感謝します。私は、 'instance'宣言に' where'節を書く必要がないことを認識したはずです。 'instance EQ Int'を書くだけで十分であり、' Int'に 'eq'のデフォルト実装を装備しています。 –

答えて

2

私はあなたがクラスの定義だと思っていますが、多分Java/C#/で何がclassなのでしょうか?

あなたが書く場合:あなただけの型クラスを定義

class Eq a => EQ a where 
    eq :: a -> a -> Bool 
    eq = (==) 

:型クラスに機能を追加し、制約を記述する方法を。あなたはであり、ではなく、Eq aがすべてEQ aであると書いてあります。EQ aを実装するには、Eq aも実装する必要があります(少し奇妙です)。

さらに、あなたはデフォルト実装提供していますeq = (==)を、それはあなたが、実装を指定しないインスタンスのための唯一のデフォルトの実装です。書き込むことによって

instance EQ Int where 
    eq = (==) 

あなたは今IntEQであることを定義しています。あなたは、インスタンスのために書き込むことにより、例えば、より有用なものにすることができます。

instance Eq a => EQ a 

は今、あなたはよりEq aが成立するために、すべてのタイプaを書かれている、またEQのタイプのインスタンスです。しかし、あなたが書いた場合、すぐにEQの全公布を定義しているので、の定義ではaEQのインスタンスに制限されているので、今度は、Haskellユニバース全体でeq(==)に等しいことを意味します。

あなたはおそらく言いたい:

{-# LANGUAGE FlexibleInstances #-} 
{-# LANGUAGE UndecidableInstances #-} 

class EQ a where 
    eq :: a -> a -> Bool 

instance Eq a => EQ a where 
    eq = (==) 

は今、あなたは型クラスEQを定義し、Eq aあるすべてのタイプaのために、我々は(==)eqを設定し、それはあなたのように、他のタイプの上にEQを定義することができますよく、のインスタンスではないdata Fooのように。ここで2つの拡張をオンにしなければならないことを覚えておいてください。これらはコンパイラ特有のものであり、標準Haskellの一部ではありません。

+0

単純型変数に適用される型コンストラクタが型に含まれていないため、最後の 'instance'は許されません。 Haskell 2010レポートの46ページを参照してください。それが 'instance Eq a => EQ [a]'で始まっていれば許されます。 –

+0

@MarcvanDongen:あなたは、Haskell 2010が許可していないということは間違いありません。しかしghcはそれを許します。GHCはHaskellのスーパーセットです。 –

+0

ありがとうございます。あなたの答えにこれを反映させ、これを説明してください。あなたがするなら、私は答えを受け入れるでしょう。 –

関連する問題