Reputation: 1517
I am trying to work out if it is possible to pattern match in Haskell set comprehensions. I have a list of lists containing Tuples, or nested lists and tuples;
E.G
[[(1,("A",1)), (2,("B",1))], [(0,("A",1)), (3,("B",2)), (2,("C",1))]]
I want to discard the tuples containing "A" and preform arbitrary computations on the others.
I was thinking along the lines:
pack(xs:xss) = [package x | x <- xs, x /= (1,("A", 1))] : (pack xss)
pack(_) = []
package x = case x of
(i, ("B", j)) -> (i + j, ("B", j * i))
(i, ("C", j)) -> (i * j, ("C", j + i))
(otherwise) -> x
Where the following might permit wildcards:
x /= (1,("A", 1))
Such as:
x /= (_,("A", _))
It is worth noting that the numbers in the nested tuple will always be of type int, not sure if that helps...
I have looked around but can not see if this is possible, it appears that maybe filtering is a better option as noted below; however we are filtering on unknowns.
Haskell List Comprehension and Pattern Matching
My issue is an abstracted example from a larger piece of work/function but hopefully I have captured the essence of the issue here. I am open to alternative suggestions.
Upvotes: 0
Views: 221
Reputation: 139840
If you wanted to filter the elements that match a pattern, you could use a pattern on the left hand side of the <-
, e.g.
... = [package x | x@(_, ("A", _)) <- xs] : ...
This will throw away anything that doesn't match the pattern.
Filtering elements that don't match a pattern isn't quite as nice. You could do it using a case
expression as a guard, but it gets kind of ugly.
... = [package x | x <- xs, case x of (_,("A", _)) -> False; _ -> True] : ...
A prettier alternative is to move the pattern match into a function.
... = [package x | x <- xs, want x] : ...
where want (_,("A", _)) = False
want _ = True
Upvotes: 7