我尝试编写一个函数来检查两个向量是否相等:

Compare Vec1 [1, 2, 3]   Vec1 [1, 2, 4]
Compare VecS ["a","b", "c"] VecS ["a", "b", "d"]


但是,在我的函数中,两种情况的实现几乎“相同”,

有没有一种方法可以简化我的代码,使其仅对Integer和String实现

data MyVector = Vec1 [Integer] | VecS[String]

eqAssert::MyVector->MyVector->Bool
eqAssert (Vec1 []) (Vec1 []) = True
eqAssert (Vec1  _) (Vec1 []) = False
eqAssert (Vec1 (x:cx)) (Vec1 (y:cy)) =
  if length (x:cx) /= length (y:cy)
    then False
    else (if x /= y then False else eqAssert (Vec1 cx) (Vec1 cy))

eqAssert (VecS []) (VecS []) = True
eqAssert (VecS  _) (VecS []) = False
eqAssert (VecS (x:cx)) (VecS (y:cy)) =
  if length (x:cx) /= length (y:cy)
    then False
    else (if x /= y then False else eqAssert (VecS cx) (VecS cy))

最佳答案

我认为您的目标是自己做太多工作。 Haskell具有一个Eq类型类,并为此具有相等性检查(==) :: Eq a => a -> a -> a函数。

此外,在Haskell中,每个a都保持Eq a不变,这也意味着Eq [a]成立。在这种情况下,对列表进行相等性检查,以使两个列表相等(假设它们具有相同数量的元素),并且如果我们并行枚举两个列表,则第一个列表的每个元素等于另一个列表中的对应元素清单。

因此wen可以简化功能,例如:

eqAssert :: MyVector -> MyVector -> Bool
eqAssert (Vec1 a) (Vec1 b) = a == b
eqAssert (VecS a) (VecS b) = a == b
eqAssert _ _ = False


因此,该函数具有三个子句。第一个包含两个Vec1,在这种情况下,我们检查两个列表ab的相等性。第二个子句几乎相同,除了我们检查两个VecS。最后,我们使用eqAssert _ _。这里的_是通配符:它匹配所有内容。剩下的模式是(Vec1 a) (VecS b)(VecS a) (Vec1 b),无论ab是什么,在这种情况下,我们只需返回False

此外,在此处实现eqAssert有点奇怪。我们可以自动将其设为Eq的实例,在这种情况下,Haskell将为(==)自动实现MyVector函数。所以我们可以这样写:

data MyVector = Vec1 [Integer] | VecS[String] deriving Eq


然后使用myvec1 == myvec2代替。

10-07 19:12
查看更多