Возможно ли сопоставление с образцом в множестве пониманий в 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
Другие вопросы по тегам