Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Haskell override function

Tags:

haskell

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))
like image 721
Aron Lee Avatar asked Oct 15 '25 04:10

Aron Lee


1 Answers

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 Vec1s, 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 VecSs. 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.

like image 57
Willem Van Onsem Avatar answered Oct 17 '25 22:10

Willem Van Onsem



Donate For Us

If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!