我收到了一份关于haskell中数据类型的练习,但我不知道如何解决这个问题。
他们给了我一个数据,比如:data CatLista a = Nil | Unit a| Conc (CatLista a) (CatLista a) deriving Eq
并且我需要使数据类型变为:Nil->[],单元x->[x] ,浓缩液->与(++(相同的操作员
因此,如果运行Conc (Unit 9)(Conc (Unit 5) (Unit 3)) == Conc (Conc (Unit 9) (Unit 5))(Conc (Unit 3) Nil)
,则应给出true,而Conc (Unit 9)(Unit 3) == Conc (Unit 3) (Unit 9)
应给出false。
我已经尝试过这样实例化show类:
instance Show a => Show (CatLista a) where
show a = case a of
Nil -> []
Unit x -> "[" ++ show x ++ "]"
Conc Nil dos -> show dos
Conc uno Nil -> show uno
Conc uno dos -> "[" + show uno ++ "," ++ show dos ++ "]"
我对haskell还很陌生,所以我可能不知道一些基础知识,因为我不明白为什么如果我用与下面的Conc (Unit 9)(Conc (Unit 5) (Unit 3)) == Conc (Conc (Unit 9) (Unit 5))(Conc (Unit 3) Nil)
相同的命令运行它(返回Conc uno dos -> show uno ++ show dos
(,它仍然返回False,即使很难,它们在我的show实例中都返回相同的[9][5][3]。
编辑
多亏了你,我做了它,它知道正确地返回像这个代码预期的值:
toLista :: Eq a => CatLista a -> [a]
toLista Nil = []
toLista (Unit x) = [x]
toLista (Conc a b)
| a == Nil = toLista b
| b == Nil = toLista a
| otherwise = (++) (toLista a) (toLista b)
instance (Show a,(Eq a)) => Show (CatLista a) where
show a= show (toLista a)
但我仍然不知道为什么如果我尝试相同的比较,它仍然返回False,即使很难,我也会得到相同的结果[9,5,3]。
这可能是因为我对Haskell缺乏了解,对此感到抱歉。
如果两个值在调用show
时产生相同的String
,则这两个值是不等价的。(==) :: Eq a => a -> a -> Bool
函数由Eq
类型类实现。因此,您需要为自己的CatLista
实现Eq
的instance
。
如果使用deriving Eq
,则Eq
的默认实现是,如果两个值具有相同的数据构造函数,则它们是相同的,并且通过对它们调用(==)
,参数在元素上是等效的。
因此,您可以使用自己实现Eq
的实例
data CatLista a = Nil | Unit a| Conc (CatLista a) (CatLista a) -- ← no deriving Eq
instance Eq a =>Eq(CatLista a) where
ca == cb= toLista ca == toLista cb
因为在数据声明中包含了deriving Eq
,所以您要告诉编译器生成一个默认的相等方法。编译器无法读懂你的想法,也无法知道你打算通过子列表的串联来表示列表。
您知道您打算Conc [1, 2] [3]
代表与Conc [1] [2, 3]
1相同的列表;两者中的任何一个都应被视为代表CCD_ 20。编译器不知道这一点。生成的等式方法看到,在一种情况下,我们在Conc
构造函数的第一个字段中有[1, 2]
,而在另一种情况中,我们有[1]
。这两个东西是不相等的,所以默认的相等方法说整个结构也不相等。
为了避免这种情况,请停止使用Show
实例。Show
用于将CatList
转换为String
的代码来构建它。它与测试相等性无关。不可能通过定义Show
实例来更改==
的结果。
您需要从数据声明中删除deriving Eq
。这意味着编译器不会生成默认的相等方法,因此您可以编写自己的方法来执行不同的操作(比较两个CatList
s是否表示相同的列表,而不是比较它们是否具有相同的结构(。
1我在这里滥用符号来使用括号语法编写子列表;这是不是的有效代码,我只是想让子结构中的差异更容易看到。