Возможно ли сопоставление с образцом в множестве пониманий в Haskell или какая альтернатива?
Я пытаюсь выяснить, возможно ли сопоставление с образцом в понимании множеств Хаскелла. У меня есть список списков, содержащих кортежи, или вложенные списки и кортежи;
НАПРИМЕР
[[(1,("A",1)), (2,("B",1))], [(0,("A",1)), (3,("B",2)), (2,("C",1))]]
Я хочу отказаться от кортежей, содержащих "А", и преформовать произвольные вычисления на других.
Я думал так:
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
Где следующее может разрешать подстановочные знаки:
x /= (1,("A", 1))
Такие как:
x /= (_,("A", _))
Стоит отметить, что числа во вложенном кортеже всегда будут иметь тип int, не уверен, поможет ли это...
Я оглянулся, но не вижу, возможно ли это, кажется, что фильтрация, возможно, является лучшим вариантом, как отмечено ниже; однако мы фильтруем по неизвестным.
Понимание списка Haskell и сопоставление с образцом
Моя проблема - абстрагированный пример из более крупного произведения / функции, но, надеюсь, я уловил суть проблемы здесь. Я открыт для альтернативных предложений.
1 ответ
Если вы хотите отфильтровать элементы, которые соответствуют шаблону, вы можете использовать шаблон в левой части <-
например,
... = [package x | x@(_, ("A", _)) <- xs] : ...
Это выбросит все, что не соответствует шаблону.
Фильтрация элементов, которые не соответствуют шаблону, не так хороша. Вы можете сделать это с помощью case
Выражение в качестве охранника, но это становится уродливым.
... = [package x | x <- xs, case x of (_,("A", _)) -> False; _ -> True] : ...
Более привлекательная альтернатива - переместить сопоставление с образцом в функцию.
... = [package x | x <- xs, want x] : ...
where want (_,("A", _)) = False
want _ = True