2016-11-19 28 views
0

Haskellで数値表現用のカスタムデータ型を作成しましたが、今度はEqインスタンスを実装したいと思っています。だから私はすでに行われていますHaskellでカスタムデータ型のEqのインスタンスを作成する

instance (Eq Sign) => Eq (Numeral) where 
(==) Num(x,_)== Num(y,_) = x==y 

しかし、私はこのエラーを取得する:

data Digit = Zero | One | Two 
type Digits = [Digit] 
data Sign = Pos | Neg -- Pos fuer Positive, Neg fuer Negative 
newtype Numeral = Num (Sign,Digits) 

instance Eq Sign where 
(==) Pos Pos = True 
(==) Neg Neg = True 
(==) _ _ = False 

instance Eq Digit where 
(==) Zero Zero = True 
(==) One One = True 
(==) Two Two = True 
(==) _ _ = False 

は、今私は私のカスタムタイプ数字でログインをチェックアウトしたいので、私はこれを試したパターンで解析エラー:( ==)

+0

いずれか '(==)(NUM(X、_))(NUM(Y、_))= X == y'または'民(X、_)==民(y、_)= x == y'である。 – jpath

+0

またなぜ 'Numt'に' newtype'を使用しますか?なぜ、 'data Numeral = Num Sign Digits'? – jpath

+0

最初に入力したケースを入力すると、あいまいなオカレンス '==' が表示されますが、それ以前に複数回宣言されています(前のケースでは推測しています)、2番目のケースもうまく機能しない –

答えて

3

ほとんど私はすでに多くの肉付け形式のコメントで書いたものを置く:

はあなたのコードを持ついくつかの問題があります。

  1. instance宣言の下にコードをインデントする必要があります。そのようにして、インスタンス宣言にどのようなコードが属するかをコンパイラに伝えます。
  2. 具体的なタイプ(Eq Sign =>)でタイプクラス制約を要求しています。これは標準のHaskellでは不可能であり、コンパイラの指示に従い、FlexibleInstancesの言語拡張を有効にしても意味をなさないでしょう。

    instance (Eq Sign) => Eq (Numeral) where 
    

    タイプの制約はタイプ変数にのみ使用されます。たとえば:

    double :: Num a => a -> a 
    double x = x + x 
    

    は、ここでは、機能doubleだけNumを実装するすべてのタイプのために働くことを言います。一方、は、既にわかっているので、IntにはNumインスタンスがあり、冗長です。 Eq Signと同じです。

    このような制約は、インスタンスを記述する型に別の多型を含む場合にのみ意味があります。 Foxの例instance Ord a => Ord [a]。ここではリストの要素のOrdインスタンスを使用して、辞書順にリストを並べ替えます。

  3. は、インフィックスまたはプレフィックス形式で定義できますが、両方では定義できません。したがって(==) (Num (x,_)) (Num (y,_)) = x == yまたはNum (x,_) == Num (y,_) = x == yのいずれかです。

  4. タプルを新しく入力すると、製品タイプを作成するのがむしろ奇妙です。より複雑な基底型に既に存在する機能を使用する場合は、通常、Newtypeが使用されます。しかし、ここではそうではありません、あなたはちょうどDigitsSignの正常な製品がほしいです。

  5. 数値のSignのみを比較しています。技術的には有効なEqインスタンスですが、先頭のゼロを切り捨てた数字の数字を比較したいとも思います。下のコードでは、単純にしておくために、ゼロを切り捨てませんでした。

data Digit = Zero | One | Two 
type Digits = [Digit] 
data Sign = Pos | Neg 
data Numeral = Num Sign Digits 

instance Eq Sign where 
    (==) Pos Pos = True 
    (==) Neg Neg = True 
    (==) _ _ = False 

instance Eq Digit where 
    (==) Zero Zero = True 
    (==) One One = True 
    (==) Two Two = True 
    (==) _ _ = False 

instance Eq Numeral where 
    Num s1 x1 == Num s2 x2 = s1 == s2 && x1 == x2 
+0

非常によく説明されています。私はチュートリアルのどこかで、たとえばEq a => Eq customTypeを見てきました。 Signsを現在のインスタンスと比較するインスタンスを含むと理解しました。私はSignsを単に比較したことを知っています。私はDigitを比較するためにEqの別のインスタンスを作成したかったのです。私はあなたが最初に書いたことを試したが、うまくいかなかったと思う。今度はもう一度試してみましたが、 "あいまいな出現=="と言いました。とにかく、よく説明されています。 –

+0

申し訳ありませんコードをコピーすると動作します。 –

+0

@ペガサスホーンありがとう。私はインスタンス宣言の型制約について2の最後に短い段落を追加しました。 – jpath

関連する問題