繁体   English   中英

实例方程式在Haskell中不起作用

[英]Instance Eq is not working in Haskell

因此,给了我以下数据类型,我不得不编写代码来检查元素是否在列表中(我想我做到了这一点)。 之后,我必须声明实例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     |                                                 ^^^^^^^^

让我们首先分析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

这里有两个问题:

  1. 我们需要a有一个Eq类型约束为好,因为我们需要检查,如果该列表中的元素是相同的;
  2. 我们用xsys调用element ,但是xsys都具有[a]类型,因此这将不起作用。

因此,我们首先需要一种机制来检查一个列表的所有元素是否出现在另一个列表中。 我们可以用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

请注意,由于以下两个原因,以上内容可能仍然不是您想要的:

  1. 不检查两个列表的顺序 ,我认为这是有意的;
  2. 如果发生在第一个列表多次的元素,那么它并没有因为它至少发生一次,我们是罚款发生多次在第二个列表,只要。 因此,两个列表的长度可以不同,并且仍然将两个Amount视为相等。

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM