Reputation: 535
Ok, I'm extremely new to Haskell as in I started learning this morning, and have been tasked with taking 2 lists of tuples [("s",1)..] and returning true if they have all the same elements otherwise return false. So far I'm thinking of taking the first element from list one and comparing it to all the elements in list 2 and do that for all the elements and then return true or false. I don't know how to keep track of all the booleans, its easy for if there is a false
|head list1 =/ elementList2 = False
but i'm just confusing my self, so far i have, I have already defined List
listCheck :: List->List -> Bool
listCheck (h1:t1) (h1:t1)
| h1 == [] = True
| fst (head h1) /= fst (head h2) = False
| snd (head h1) /= snd (head h2) = False
| otherwise = listCheck (t1) (t2)
Any suggestions? The lists can be in any order, so [("a",1),("b",1)] and [("b",1),("a",1)] are equal. the order of the lists can't be changed.
Upvotes: 1
Views: 5138
Reputation: 30237
The way I always recommend newcomers approach this problem is this:
In this case, your description of what you're thinking can be finessed into a #1-style solution. Let's quote it:
So far I'm thinking of taking the first element from list one and comparing it to all the elements in list 2 and do that for all the elements and then return true or false.
Here, instead of thinking of doing that just with the first element, picture doing the same thing to all the elements as one step to the solution. There's a standard function that captures this pattern:
-- The `map` function applies the function given as the first argument
-- to all of the elements of the second argument. The result is a list
-- of all the individual results.
--
-- Example:
--
-- >>> map (+10) [1, 2, 3, 4]
-- [11, 12, 13, 14]
map :: (a -> b) -> [a] -> [b]
So if you can write a function that tests for one value whether it exists in the second list, you can use map
to apply that function to all elements of the first list:
step1 :: Eq a => [a] -> [a] -> [Bool]
step1 xs ys = map checkOne xs
where checkOne x = _fillInTheBlank
(The _fillInTheBlank
bit is called a "hole"—you're supposed to actually write the correct code in there!)
The second step would be to check the [Bool]
to see whether all of the elements are True
. You return True
if they are, and False
if at least one is false. There is a standard function for that as well:
-- Returns `False` if any element of the list is `False`, `True` otherwise.
and :: [Bool] -> Bool
And now:
listCheck :: Eq a => [a] -> [a] -> Bool
listCheck xs ys = and (map checkOne xs)
where checkOne x = _fillInTheBlank
map :: (a -> b) -> [a] -> [b]
-- Write your own version of `map`
and :: [Bool] -> Bool
-- Write your own version of `and`
Note what I've done: I've split the problem into smaller parts, each of which I can solve with functions like map
and and
that will be useful in many other cases. That's what you should be shooting for.
Upvotes: 0
Reputation: 92117
If your goal is to compare the nth element of each list, you are quite close already. The only problem is that you are pattern-matching to pull the two lists apart into head/tail, and then acting as if you hadn't, calling head
and tail
again:
listCheck :: (Eq a, Eq b) => [(a,b)] -> [(a,b)] -> Bool
listCheck xs ys
| xs == [] = True
| fst (head xs) /= fst (head ys) = False
| snd (head xs) /= snd (head ys) = False
| otherwise = listCheck (tail xs) (tail ys)
This is far from the most elegant way of doing things, but it is the closest I could find to what you seemed to be trying to write.
Upvotes: -1
Reputation: 23135
listCheck l1 l2 = sort l1 == sort l2
will work fine if list elements are totally ordered, which they will be in the usual case of Strings, numbers etc (and naturally tuples of such elements).
If your elements don't have an ordering things get a lot more difficult, but I don't think you'll encounter that situation often.
Upvotes: 0
Reputation: 21027
I think it is reasonable to take the head of the list and create an equality function using it. The use any
or all
from the List library to compare with the tail.
As this is a college exercise I guess you don't want the answer given to you ;-)
Upvotes: 2