对不起,我的英语很差。标题可能无法解释我的意思。
在数据树中,Tree
定义如下:
-- | Multi-way trees, also known as /rose trees/.
data Tree a = Node {
rootLabel :: a, -- ^ label value
subForest :: Forest a -- ^ zero or more child trees
}
#ifdef __GLASGOW_HASKELL__
deriving (Eq, Read, Show, Data)
#else
deriving (Eq, Read, Show)
#endif
它使用deriving
实例==
,/=
Tree
(日期)。
我可以在不派生的情况下做同样的事情吗? 我尝试这样的事情:
data Test a = Test a
instance Eq Test where
(Test a) == (Test b) = a == b
但它抛出了一个例外。我认为原因是关于 a 和 b 的类型。
如果我想使用==
为我的数据定义自定义操作,我该怎么办。
我知道我可以将Functor
与fmap
一起使用。但我想在a = Test 1
和b = Test "a"
的地方使用像a == b
这样的==
。可能吗?
您可以在Tree
或Test
上定义Eq
的instance
,但您的定义存在一些问题。
instance Eq Test where
(Test a) == (Test b) = a == b
第一个是Eq Test
中的Test
仍然是参数化的。实际上,您编写了data Testa= ...
,因此这意味着存在一个类型参数。因此,您可以使用以下命令指定它:
instance Eq(Testa)where
(Test y) == (Test x) = x == y
现在,您指定Eq
是在Test a
上定义的。我还将a
和b
重命名为x
和y
。这不是必需的,因为"类型世界"和"可变世界"是分开的,但它使事情变得不那么混乱。
但是仍然存在一个问题:您称x == y
.但是没有关a
本身就是Eq
的实例。因此,您需要使用类型约束:
instanceEq a =>Eq (Test a) where
(Test y) == (Test x) = x == y
现在,如果Test a
也是Eq
的实例,则指定是Eq
的实例a
。
因此,对于Tree
数据结构,Eq
的instance
应如下所示:
instance (Eq a, Eq (Forest a)) => Eq (Tree a) where
(Tree x1 y1) == (Tree x2 y2) = x1 == x2 && y1 == y2
(当然,我在这里定义了两棵树是如何相等的,您可能希望以(语义上)不同的方式定义两棵树的相等性,因此您本身不应该复制粘贴此代码)。
请注意,就像@luqui所说的那样,如果type Forest a = [Tree a]
,那么您可以省略Eq (Forest a)
类型约束,因为instance Eq a => Eq [a]
成立。所以在这种情况下是:
instance Eq a => Eq (Tree a) where
(Tree x1 y1) == (Tree x2 y2) = x1 == x2 && y1 == y2