Haskell函数中的模式匹配

jon*_*eto 2 haskell pattern-matching

我有很多方法在其定义中有样板代码,请看上面的例子.

replace:: Term -> Term -> Formula -> Formula
replace x y (Not f)            = Not $ replace x y f
replace x y (And f g)          = And (replace x y f) (replace x y g)
replace x y (Or f g)           = Or (replace x y f) (replace x y g)
replace x y (Biimp f g)        = Biimp (replace x y f) (replace x y g)
replace x y (Imp f g)          = Imp (replace x y f) (replace x y g)
replace x y (Forall z f)       = Forall z (replace x y f)
replace x y (Exists z f)       = Exists z (replace x y f)
replace x y (Pred idx ts)      = Pred idx (replace_ x y ts)
Run Code Online (Sandbox Code Playgroud)

如您所见,replace函数的定义遵循模式.我想要有相同的函数行为,简化他的定义,可能使用一些模式匹配,可能使用通配符_X参数,如:

replace x y (X f g)          = X (replace x y f) (replace x y g)
Run Code Online (Sandbox Code Playgroud)

为避免以下定义:

replace x y (And f g)          = And (replace x y f) (replace x y g)
replace x y (Or f g)           = Or (replace x y f) (replace x y g)
replace x y (Biimp f g)        = Biimp (replace x y f) (replace x y g)
replace x y (Imp f g)          = Imp (replace x y f) (replace x y g)
Run Code Online (Sandbox Code Playgroud)

有什么办法吗?忘记函数的目的,它可以是任何东西.

Dan*_*ner 6

如果您有许多应该以统一方式处理的构造函数,那么您应该使您的数据类型反映出来.

data BinOp      = BinAnd | BinOr | BinBiimp | BinImp
data Quantifier = QForall | QExists
data Formula    = Not Formula
                | Binary BinOp Formula Formula -- key change here
                | Quantified Quantifier Formula
                | Pred Index [Formula]
Run Code Online (Sandbox Code Playgroud)

现在,所有二元运算符的模式匹配都更容易:

replace x y (Binary op f g) = Binary op (replace x y f) (replace x y g)
Run Code Online (Sandbox Code Playgroud)

要保留现有代码,您可以打开PatternSynonyms并定义旧版本的And,Or依此类推:

pattern And x y = Binary BinAnd x y
pattern Forall f = Quantified QForall f
Run Code Online (Sandbox Code Playgroud)