如何获取出现在布尔表达式中的变量列表?

时间:2019-10-31 12:14:37

标签: haskell boolean pattern-matching

您好,我需要帮助来构造一个返回布尔表达式变量的函数。我正在尝试获取模式,但是我无法资助适用于所有测试用例的通用方法。

这是代码

module BoolExpr (Variable, BoolExpr(..), evaluate) where
import Data.List
import System.IO

type Variable = Char
data BoolExpr = T
 |F
 |Var Variable
 |Not BoolExpr
 |And BoolExpr BoolExpr
 |Or BoolExpr BoolExpr
 deriving(Show)


--this is my attempt 
variables :: BoolExpr -> [Variable]
variables T = []
variables F = []
variables (Var e1)= [e1]
variables (And (Var e1) (Var e2))=variables (Var e1) ++variables (Var e2)
variables (Or (Var e1) (Var e2))=variables (Var e1) ++variables (Var e2)
variables ( And (Var e1) (Or (Var e2)(Var e3)) ) = variables (Var e1) ++ variables (Var e2) ++ variables (Var e3) 
variables (xy)=variables x ++ variables y
variables _ = []


一些测试用例及其所需的输出

> variables T
""

> variables (Or T F)
""

> variables (Var 'a')
"a"

> variables (And (Var 'a') (Or (Var 'c') (Var 'b')))
"abc"

> variables (And (Var 'a') (Or (Var 'a') (Var 'a')))
"a"

但是如果使用三个以上左右的变量,该函数将失败。我无法以一般形式制作

1 个答案:

答案 0 :(得分:2)

您的模式匹配也是 特定的。例如,您写了一个子句:

variables (And (Var e1) (Var e2)) = …

,因此您将自己限制为And,其中操作数是包装在Var数据构造函数中的值。但这不是必需的。我们可以这样写:

variables (And e1 e2) = …

因此e1e2BoolExpr,可以使用所有可能的数据构造函数构造。因此,我们可以将函数定义为:

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

请注意,如果变量多次出现在表达式中,则将多次出现 次。因此,如果您想要一个 unique 变量列表,则可能需要通过 uniqness过滤器传递结果。您可能还希望对结果进行排序。

我们可以通过定义一个在变量之上起作用的函数来做到这一点,例如:

uniqVariables :: BoolExpr -> [Variable]
uniqVariables e = _ (variables e)

其中_是您需要填写的内容。我将其保留为练习。