所以给了我以下数据类型,我不得不编写代码来检查元素是否在列表中(我想我做到了这一点)。 之后,我必须声明实例Eq,如果我的两个金额列表都相等,则它将为True。我应该使用我先前编写的元素代码。 有人可以告诉我我在做什么错吗?
data Amount a = Amount [a]
element [] _ = False
element (x:xs) y = ( x==y) || element xs y
instance Eq (Amount a) where
Amount xs == Amount ys = element xs ys && element ys xs
这是我收到的错误消息
• Couldn't match expected type ‘a’ with actual type ‘[a]’
‘a’ is a rigid type variable bound by
the instance declaration at Probeklausur1.hs:43:10-22
• In the second argument of ‘element’, namely ‘ys’
In the first argument of ‘(&&)’, namely ‘element xs ys’
In the expression: element xs ys && elementS ys xs
• Relevant bindings include
ys :: [a] (bound at Probeklausur1.hs:44:27)
xs :: [a] (bound at Probeklausur1.hs:44:14)
(==) :: Amount a -> Amount a -> Bool
(bound at Probeklausur1.hs:44:17)
|
44 | Amount xs == Amount ys = element xs ys && elementS ys xs | ^^
Probeklausur1.hs:44:49: error:
• Variable not in scope: elementS :: [a] -> [a] -> Bool
• Perhaps you meant ‘element’ (line 40)
|
44 | Amount xs == Amount ys = element xs ys && elementS ys xs | ^^^^^^^^
答案 0 :(得分:4)
让我们首先分析element
的类型:
element [] _ = False
element (x:xs) y = ( x==y) || element xs y
我们看到第一项是列表[a]
(基于[]
和(:)
数据构造函数)。此外,我们知道第二项具有列表元素类型的类型,因此a
,并且由于我们调用x == y
,因此必须存在Eq a
约束。因此我们得出:
element :: Eq a => [a] -> a -> Bool
为此已经存在一个非常相似的内置函数:elem :: Eq a => a -> [a] -> Bool
,因此最好使用此函数。
但是让我们现在来看一下实例声明:
instance Eq (Amount a) where
Amount xs == Amount ys = element xs ys && element ys xs
这里有两个问题:
a
具有Eq
类型约束,因为我们需要检查列表中的 elements 是否相同;和element
和xs
来调用ys
,但是xs
和ys
的类型都是[a]
,所以这是行不通的。 因此,我们首先需要一种机制来检查一个列表的 all 个元素是否出现在另一个列表中。我们可以使用all :: (a -> Bool) -> [a] -> Bool
函数进行检查:
allElem :: Eq a => [a] -> [a] -> Bool
allElem xs = all (flip elem xs)
所以现在我们可以这样写:
instance Eq a => Eq (Amount a) where
Amount xs == Amount ys = allElem xs ys && allElem ys xs
请注意,由于以下两个原因,以上内容可能仍然不是您想要的:
Amount
视为相等。