можно обобщить:

сейчас у меня есть код, который по сути работает так:

data Expression 
    = Literal Bool 
    | Variable String
    | Not Expression 
    | Or Expression Expression 
    | And Expression Expression
    deriving Eq

simplify :: Expression -> Expression
simplify (Literal b) = Literal b
simplify (Variable s) = Variable s
simplify (Not e) = case simplify e of
    (Literal b) -> Literal (not b)
    e'          -> Not e'
simplify (And a b) = case (simplify a, simplify b) of
    (Literal False, _) -> Literal False
    (_, Literal False) -> Literal False
    (a', b')           -> And a' b'
simplify (Or a b) = case (simplify a, simplify b) of
    (Literal True, _) -> Literal True
    (_, Literal True) -> Literal True
    (a', b')          -> Or a' b'

И еще много таких шаблонов, касающихся всех способов, которыми можно упростить логическое выражение. Однако, по мере того, как я добавляю больше операторов и правил, это становится невероятно большим и неуклюжим. Тем более что некоторые правила необходимо добавить дважды, чтобы учесть коммутативность.

Как я могу красиво рефакторировать множество и множество паттернов, некоторые из которых (большинство, я бы сказал) даже симметричны (например, паттерны And и Or)?

Прямо сейчас добавление правила для упрощенияAnd (Variable "x") (Not (Variable "x")) вLiteral False требует, чтобы я добавил два вложенных правила, что почти оптимально.

Ответы на вопрос(0)

Ваш ответ на вопрос