Ответ 1
Я не думаю, что это возможно в haskell. Однако есть несколько альтернатив:
Выделить общий код с привязкой where
Это не имеет особого смысла в вашем примере, но полезно, если у вас больше кода в выражении case:
combine o1 o2 = case (o1,o2) of
(Valid, Invalid) -> handleInvalid
(Invalid, Valid) -> handleInvalid
...
where
handleInvalid = ...
Использование шаблонов подстановок
По моему опыту, это происходит не так часто, что вы хотите использовать два или шаблоны в одном шаблоне. В этом случае вы можете обрабатывать все "хорошие" случаи и использовать шаблон для всех остальных:
combine o1 o2 = case (o1,o2) of
(Valid, Valid) -> Valid -- This is the only valid case
_ -> Invalid -- All other cases are invalid
Это имеет тот недостаток, что он обходит проверку целостности и что вы не можете использовать шаблоны подстановок для других целей.
Использовать защитные устройства и ==
Если типы, которые вы хотите сопоставить, являются типами, подобными перечислению, вы можете подумать о создании экземпляра Eq
. Затем вы можете использовать ==
и ||
для соответствия нескольким конструкторам в одном защитнике:
combine o1 o2
| o1 == Invalid && o2 == Valid || o1 == Valid && o2 == Invalid = Invalid
| ...
Я согласен с тем, что это выглядит не так хорошо, и у него также есть недостаток в обход проверки целостности и не предупреждает вас, если шаблоны перекрываются, поэтому я бы не рекомендовал его.