I have a small Erlang function that compares if two lists are equal:
myEq([], []) -> true;
myEq([X|Xs], [X|Ys]) -> myEq(Xs, Ys);
myEq(_, _) -> false.
The comparison takes place on line 2, the X
of [X|Xs]
always binds to the first element of the first list, the [X|Ys]
matches only if the first elements of both lists are equal.
If I try this in Haskell I get an error message: "Conflicting definitions for x
".
A possible solution in Haskell would be:
myEq (x:xs) (y:ys) = if x == y then myEq xs ys else False
But I would like to know if it is possible to do this in Haskell using pattern matching?
No, in Haskell you cannot use the same variable x
in the head of a clause. Haskell does not do unification or equality checks like for instance respectively Prolog and Erlang do. This is specified in the Haskell '98 report:
The set of patterns corresponding to each match must be linear---no variable is allowed to appear more than once in the entire set.
(copied, boldface added)
The only way to do it is using a guard (or any other type of checking in the body of course). You can however write it more elegant like:
myEq [] [] = True
myEq (x:xs) (y:ys) | x == y = myEq xs ys
-- | otherwise = False
myEq _ _ = False
the otherwise
case can be omitted since Haskell will fallback on the last clause and thus return False
.
Or perhaps even more elegant:
myEq [] [] = True
myEq (x:xs) (y:ys) = x == y && myEq xs ys
myEq _ _ = False
Personally I think that is better since here you state explicitly that x
is equal to y
so making mistakes like by accident writing the same variable cannot happen. Although of course it is a matter of taste.
No. Every variable can be bound at most once on the pattern matching side. If you wanted to bind a variable twice you would have to evaluate to perform unification.
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