Ваш шаблон соответствует слишком специфично. Например, вы пишете предложение:
variables (And (Var e1) (Var e2)) = …
и, таким образом, ограничиваетесь And
, где операндами являются значения, заключенные в конструктор данных Var
. Но это не обязательно. Мы можем просто написать это как:
variables (And <b>e1</b> <b>e2</b>) = …
, тогда e1
и e2
- это BoolExpr
s, которые могут быть построены со всеми возможными конструкторами данных. Таким образом, мы можем определить функцию следующим образом:
variables :: BoolExpr -> [Variable]
variables T = []
variables F = []
variables (Var e1) = [e1]
variables (And e1 e2) = variables e1 ++ variables e2
variables (Or e1 e2) = variables e1 ++ variables e2
variables (Not e) = variables e
Обратите внимание, что переменная будет встречаться несколько раз раз, если она является частью выражения несколько раз. Таким образом, вы можете захотеть передать результат через фильтр уникальности , если вам нужен список уникальных переменных. Кроме того, вы также можете отсортировать результат.
Мы можем сделать это, определив функцию, которая работает поверх переменных, например:
uniqVariables :: BoolExpr -> [Variable]
uniqVariables e = _ (variables e)
, где _
- это нечтоВы должны заполнить. Я оставляю это как упражнение.