I try to write a function to check whether two vectors are equal or not:
Compare Vec1 [1, 2, 3] Vec1 [1, 2, 4]
Compare VecS ["a","b", "c"] VecS ["a", "b", "d"]
However, on my function I have "almost" identical implementation for both cases,
is there a way to simplify my code so that it has only one implementation for Integer and 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))
I think you aim to do too much work yourself. Haskell has an Eq
typeclass, and an equality check (==) :: Eq a => a -> a -> a
function for that.
Furthermore in Haskell for every a
such that Eq a
holds, it also means that Eq [a]
holds. In that case the equality check is done on lists such that two lists are equal given these have the same number of elements, and if we enumerate the two lists in parallel, each element of the first list is equal to the corresponding element in the other list.
So wen can simplify the function like:
eqAssert :: MyVector -> MyVector -> Bool
eqAssert (Vec1 a) (Vec1 b) = a == b
eqAssert (VecS a) (VecS b) = a == b
eqAssert _ _ = False
So the function has three clauses. The first one deels with two Vec1
s, in that case we check the equality of the two lists a
and b
. The second clause is almost identical, except that we check for two VecS
s. Finally we use eqAssert _ _
. Here _
is a wildcard: it matches everything. The remaining patterns are (Vec1 a) (VecS b)
and (VecS a) (Vec1 b)
regardless what a
and b
are, we simply return False
in that case.
It is furthermore a bit odd to implement an eqAssert
here. We can make it automatically an instance of Eq
, in that case Haskell will implement an (==)
function for MyVector
automatically. So we can write:
data MyVector = Vec1 [Integer] | VecS[String] deriving Eq
and then use myvec1 == myvec2
instead.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With