tags:

views:

206

answers:

2

New to Haskell and have a stumbling block. I'm trying to filter a list of tuples based on the first item.

filter (==(x,_)) lis

I get an illegal '_' error, but I'm not sure how I can get around it?

+6  A: 

In Haskell, you cannot iterate over a tuple like you can a list.

If the tuple only has two items, you can use fst to retrieve the first item of the tuple and snd to retrieve the second item.

One way to do what I think you want to do is this approach:

Prelude> let lst = [(1,2), (3,4)]
Prelude> filter ((==1).fst) lst
[(1,2)]

Which only returns the items in the list where the first element is equal to 1; of course, you can substitute x where I put 1.

To be a little more specific, (==1).fst first applies fst to the element in lst, then applies (==1) to the result of fst -- technically, the dot composes the two functions together.

Mark Rushakoff
That's great, thanks. Was wondering what those .'s were doing on all the sample code!
Zippy
I think the uses of (and differences between) `.` and `$` are one of the most common hurdles to beginning Haskell -- so don't worry, you aren't the only one who's had trouble with it!
Mark Rushakoff
+4  A: 

You can't give an argument with a wildcard _ in it to the == operator (or to any other function). The argument needs to be real value, not a pattern that should be matched against.

If you want to use pattern matching you could use a lambda function as you filter condition:

filter (\(a,_) -> a == x) lis

Also, there is the predefined function fst to extract the first element of a two-element tuple. This can be combined with == to do the same test:

filter ((== x) . fst)) lis
sth