1

私が持っている場合:

data Container a = Node a | End a | Container a

Container a 要素のリストを見て、リスト差分を実行できる関数を書きたい場合、この抽象データ型が同等であることをコンパイラに明示的に伝えるにはどうすればよいでしょうか?

私はそれが次のようになると思いました:

compare::Eq (Container a) => Container a -> Container a -> Bool
compare a b
           | a == b = True
           | a /= b = False

しかし、「==」の使用に起因する (Eq (Container a)) を推測できなかったため、Eq ステートメントが正しくないと不平を言っています。

編集私の抽象データ型で (Eq) を導出することが、これを許可する唯一の方法です。誰か確認してくれませんか?

派生を含めた後のEDIT2(Eq):

test:: [Container a] -> Container a -> Bool
test list element = elem element list

「(Eq a) のインスタンスなし」

4

2 に答える 2

6

このようなインスタンスをコンパイラに通知する最も簡単な方法は、節を使用するderivingことです。この場合、

data Container a = Node a | End a | Container a deriving (Eq)

Eqインスタンスを手動で指定することもできます。たとえば、次の例では、 a に等しいかどうかContainerをテストできる要素が含まれている場合、Containerも等しいかどうかをテストできます。

instance Eq a => Eq (Container a) where
    (Node a)      == (Node b)      = a == b
    (End a)       == (End b)       = a == b
    (Container a) == (Container b) = a == b
    _             == _             = False

これは与えられたものと同じ定義なderivingので、そのような定義を打ち出す必要はありませんが、より複雑な定義が必要な場合Eqは、そのようなことをしなければなりません。

コンテナのインスタンスを作成したら、次のEqように記述できます。

compare :: Eq a => Container a -> Container a -> Bool
compare a b | a == b = True
            | a /= b = False

(この関数についての 2 つのこと: と同じであり、ガードの最後の代替手段として(==)使用する必要があるため、実際にはまったく無意味です。)otherwise

これらは基本的に 2 つのオプションのみです。基本的に2つの組み合わせである3番目の方法がありますが、GHC拡張機能を使用しStandaloneDerivingます。

deriving instance Eq a => Eq (Container a)
于 2012-09-08T13:43:30.193 に答える