Вопрос

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.

Это было полезно?

Решение

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
Лицензировано под: CC-BY-SA с атрибуция
Не связан с StackOverflow
scroll top