data Foo = Bar1
| Bar2 Foo Foo
| Bar3 Foo
| Bar4 Foo Foo Foo
Теперь предположим, что кто-то построил дерево Foo
, и я хочу проверить, допустимы ли аргументы значения Foo. Правила для аргументов конструктора:
Bar2 Bar1 Foo
Bar3 (Bar2|Bar3|Bar4)
Bar4 Bar1 Bar1 (Bar1|Bar4)
Я знаю конструктор значения и хочу проверить только непосредственные аргументы, ничего рекурсивного. Нравится:
bar2 Bar1 Bar1 = True
bar2 Bar1 (Bar2 {}) = True
bar2 Bar1 (Bar3 _) = True
bar2 Bar1 (Bar4 {}) = True
bar2 _ _ = False
И например. аналогично для Bar4:
bar4 Bar1 Bar1 Bar1 = True
bar4 Bar1 Bar1 (Bar4 {}) = True
bar4 _ _ _ = False
Как я могу выразить эти условия наиболее кратко? Перечисление всех комбинаций в некоторых случаях слишком много. Насколько мне известно, синтаксиса «ИЛИ» для сопоставления с образцом не существует.
ОБНОВИТЬ
Я адаптировал решение Даниэля и пришел к этому:
data Foo = Bar1
| Bar2 Foo Foo
| Bar3 Foo
| Bar4 Foo Foo Foo
deriving (Data, Typeable)
bar2 a b = a `isOf` [Bar1] && b `isOf` [Bar1,Bar2{},Bar3{},Bar4{}]
bar4 a b c = [a,b] `areOf` [Bar1] && c `isOf` [Bar1,Bar4{}]
isOf l r = toConstr l `elem` map toConstr r
areOf l r = all (`isOf` r) l
Что мне нравится в этом, так это то, что мне не нужно менять свой тип данных, кроме добавления предложения производного, и что он читаем. Недостаток, конечно, в том, что это динамические проверки. В моем случае это нормально, поскольку это просто проверки, подобные утверждениям, для обнаружения ошибок программирования.
Bar2
,Bar3
иBar4
? (Т.е. проверяют ли условия, что они легальны.) Если это так, то, вероятно, лучше попытаться закодировать условия в системе типов, чтобы не было возможности их сломать. - person huon   schedule 17.08.2012Bar2
какbar2 Bar1 _ = True
. - person Petr   schedule 17.08.2012instanceof
в Java, тогда я мог бы, по крайней мере, сделать это с некоторыми вложенными if'ами. Я думаю, что эквивалент сcase..of
немного неудобен в Haskell для этого конкретного случая. - person letmaik   schedule 17.08.2012bar4 Bar1 Bar1 a = case a of Bar1 -> True; Bar4 {} -> True; _ -> False
лучше, чем совпадение повторяющегося шаблона. - person huon   schedule 17.08.2012