Von*_*fry 3 haskell instance typeclass
抱歉我的英语不好.标题可能无法解释我的意思.
在Data.Tree中,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
Run Code Online (Sandbox Code Playgroud)
它使用deriving到实例==,并/=为Tree(日期).
我可以在没有推导的情况下做同样的事情吗?我尝试这样的事情:
data Test a = Test a
instance Eq Test where
(Test a) == (Test b) = a == b
Run Code Online (Sandbox Code Playgroud)
但它引发了一个例外.我认为原因是关于a和b的类型.
什么我可以做我是否要定义我的数据的自定义操作==.
我知道我可以使用Functor同fmap做到这一点.但我想使用==像a == b地方a = Test 1和b = Test "a".可能吗?
您可以定义instance的Eq上Tree或Test,但也有一些问题,你的定义.
instance Eq Test where
(Test a) == (Test b) = a == b
Run Code Online (Sandbox Code Playgroud)
第一个是Testin 仍然Eq Test是参数化的.实际上,你写的这意味着有一个类型参数.所以你可以用:data Test a = ...
instance Eq (Test a) where
(Test y) == (Test x) = x == yRun Code Online (Sandbox Code Playgroud)
现在,您指定了Eq已定义的内容Test a.我也改名a并b以x和y.这是不必要的,因为"类型世界"和"变量世界"是分开的,但它使事情变得不那么混乱.
但仍有问题:你打电话x == y.但是没有担保人a本身就是一个例子Eq.因此,您需要使用类型约束:
instance Eq a => Eq (Test a) where
(Test y) == (Test x) = x == yRun Code Online (Sandbox Code Playgroud)
现在,您可以指定Test a为实例Eq ,如果 a是的实例Eq为好.
为了您的Tree数据结构中,instance中Eq因此应该是这样的:
instance (Eq a, Eq (Forest a)) => Eq (Tree a) where
(Tree x1 y1) == (Tree x2 y2) = x1 == x2 && y1 == y2
Run Code Online (Sandbox Code Playgroud)
(当然,我在这里定义如何两棵树都是平等的,有可能要定义在(语义)不同的方式平等了两棵树,所以你不应该本身复制粘贴此代码).
需要注意的是-像@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
Run Code Online (Sandbox Code Playgroud)