Haskell覆盖函数

Aro*_*Lee 2 haskell

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

Compare Vec1 [1, 2, 3]   Vec1 [1, 2, 4]
Compare VecS ["a","b", "c"] VecS ["a", "b", "d"]
Run Code Online (Sandbox Code Playgroud)

但是,在我的功能上,我对两种情况都有"几乎"相同的实现,

有没有办法简化我的代码,以便它只有一个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))
Run Code Online (Sandbox Code Playgroud)

Wil*_*sem 5

我认为你的目标是自己做太多的工作.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
Run Code Online (Sandbox Code Playgroud)

所以该函数有三个子句.有两个第一个deels Vec1S,在这种情况下,我们检查两个列表的平等ab.第二个条款几乎相同,只是我们检查了两个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
Run Code Online (Sandbox Code Playgroud)

然后使用myvec1 == myvec2.