У меня есть много методов, которые имеют шаблонный код в их определении, посмотрите на пример выше.Соответствие шаблону в функции Haskell
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)
Как вы можете видеть, определения для replace
функции следует шаблон. Я хочу иметь такое же поведение функции, упрощая его определение, вероятно, используя некоторые сопоставления с образцом, может быть, с групповым символом _
или X
над аргументами, что-то вроде:
replace x y (X f g) = X (replace x y f) (replace x y g)
Для избежания следующих определений:
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)
Есть ли способ? Забудьте о цели функции, это может быть что угодно.
Может 'DeriveFunctor' или сделать явный экземпляр этого? Тогда приведенное выше может закончиться как «заменить x y = fmap (\ z ->, если x == z, тогда y else x)'. Конечно, это означает, что 'Formula' будет иметь вид' * -> * ', но это звучит разумно. Формула Була была бы логической формулой. – Alec
Вы могли бы сделать «Формулу» экземпляр ['Compos'] (https://hackage.haskell.org/package/uniplate-1.6.12/docs/Data-Generics-Compos.html), это поможет? – Cactus