我尝试编写一个函数来检查两个向量是否相等:
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
,在这种情况下,我们检查两个列表a
和b
的相等性。第二个子句几乎相同,除了我们检查两个VecS
。最后,我们使用eqAssert _ _
。这里的_
是通配符:它匹配所有内容。剩下的模式是(Vec1 a) (VecS b)
和(VecS a) (Vec1 b)
,无论a
和b
是什么,在这种情况下,我们只需返回False
。此外,在此处实现
eqAssert
有点奇怪。我们可以自动将其设为Eq
的实例,在这种情况下,Haskell将为(==)
自动实现MyVector
函数。所以我们可以这样写:data MyVector = Vec1 [Integer] | VecS[String] deriving Eq
然后使用
myvec1 == myvec2
代替。