Haskell模式匹配隐式类型

Haskell模式匹配隐式类型,haskell,pattern-matching,Haskell,Pattern Matching,我是Haskell的新手,我正在尝试用模式匹配做一些东西。我甚至不知道这样做是否可行。 我有一个数据Fml: 数据Fml a=和(Fml a)(Fml a) |NAnd(Fml a)(Fml a) |或(Fml a)(Fml a) |NOr(Fml a)(Fml a) |异或(Fml a)(Fml a) |XNOr(Fml a)(Fml a) |暗示(Fml a)(Fml a) |当量(Fml a)(Fml a) |非(Fml a) |最终(变量a) 派生(显示) Var只是一个值(示例:1)

我是Haskell的新手,我正在尝试用模式匹配做一些东西。我甚至不知道这样做是否可行。 我有一个数据Fml:

数据Fml a=和(Fml a)(Fml a)
|NAnd(Fml a)(Fml a)
|或(Fml a)(Fml a)
|NOr(Fml a)(Fml a)
|异或(Fml a)(Fml a)
|XNOr(Fml a)(Fml a)
|暗示(Fml a)(Fml a)
|当量(Fml a)(Fml a)
|非(Fml a)
|最终(变量a)
派生(显示)
Var只是一个值(示例:1) 我试图制作一个简单的函数,将所有变量合并到一个数组中。我已经做到了:

getVar::(等式a)=>Fml a->[Fml a]
getVar(和pq)=getVar p++getVar q
getVar(NAnd p q)=getVar p++getVar q
getVar(或pq)=getVar p++getVar q
getVar(NOr p q)=getVar p++getVar q
getVar(XOr p q)=getVar p++getVar q
getVar(XNOr p q)=getVar p++getVar q
getVar(暗示p q)=getVar p++getVar q
getVar(等价于pq)=getVar p++getVar q
getVar(非p)=getVar p
getVar x=[x]
但我不满意,因为这些案例中有8个都在做同样的事情。 我想知道这样做是否可行

getVar(pq)=getVar p++getVar q

您可以为操作员定义类型:

data Op2 = And | NAnd | Or | NOr | Xor | XNor | Imply | Equiv
data Op2=And | NAnd |或| NOr | Xor | XNor |暗示|等效
然后定义一个采用运算符和两个参数的数据构造函数:

data Fml a
    = Fml2 Op2 (Fml a) (Fml a)
    | Not (Fml a)
    | Final (Var.Var a)
    deriving (Show)
数据Fml a
=Fml2 Op2(Fml a)(Fml a)
|非(Fml a)
|最终(变量a)
派生(显示)
因此,您的函数如下所示:

getVar :: Eq a => Fml a -> [Var.Var a]
getVar (Fml2 _ p q) = getVar p ++ getVar q
getVar (Not p) = getVar p
getVar (Final v) = [v]
getVar::Eq a=>Fml a->[Var.Var a]
getVar(Fml2 p q)=getVar p++getVar q
getVar(非p)=getVar p
getVar(最终v)=[v]

我认为输出类型应该是
Var.Var
s的列表,而不是
fmla
,因为您的函数提示它正在查找变量列表。

最后一种情况应该是
getVar(Final x)=[x]
对吗?另外,除非您想编写代码,否则这是不可能的。getVar x=[x]工作正常,因为我想返回[Fml]OK!谢谢:)@NicolasFAU:但这看起来很“奇怪”,因为你的函数暗示你在返回变量,而这里你在返回公式。所有公式都具有相同的数据构造函数,但类型构造函数不知道这一点。太好了!谢谢。对于函数的返回,我表达得很糟糕。我需要Fml,而不是Var@NicolasFAU:不过,建议将
getVar
的结果类型设置为
[Var a]
,因为它更精确。然后,如果你想从中生成一个
Fml
,你可以简单地
映射Final
到它上面,但是你不需要像{Final v->{-do something with var-};->error这样的伪模式匹配,当你知道你有一个变量时,}。