Haskell模式匹配优化

时间:2018-12-17 01:40:54

标签: haskell recursion types pattern-matching

我已经开始为大学课程学习Haskell,并且编写了具有模式匹配功能的函数(称为Simplify)。但是我不确定如何优化我的代码,因为我觉得代码太难了。

无论如何,这是我编写的代码:

data Proposition = Proposition Bool
                | Const Bool
                | Var String
                | And Proposition Proposition
                | Or Proposition Proposition
                | Not Proposition deriving (Show, Eq)


simplify :: Proposition -> Proposition

simplify (And _ (Const False)) = (Const False)
simplify (And (Const False) _) = (Const False)
simplify (And p (Const True)) = simplify p
simplify (And (Const True) p) = simplify p
simplify (Or _ (Const True)) = (Const True)
simplify (Or (Const True) _) = (Const True)
simplify (Or a b) = simplify (Or (simplify a) (simplify b))
simplify (Const b) = (Const b)
simplify (Var v) = (Var v)
simplify (Not (Const True)) = (Const False)
simplify (Not (Const False)) = (Const True)
simplify (Not p) = simplify (Not (simplify p))

1 个答案:

答案 0 :(得分:2)

您似乎通常希望遵循该模式

  1. 简化所有子表达式。
  2. 简化表达式。

对我来说,这建议使用recursion-schemes软件包。

{-# language TemplateHaskell, TypeFamilies, DeriveTraversable #-}
import Data.Functor.Foldable
import Data.Functor.Foldable.TH

data Proposition
  = Const Bool
  | Var String
  | And Proposition Proposition
  | Or Proposition Proposition
  | Not Proposition
  deriving (Show, Eq)

makeBaseFunctor ''Proposition

这神奇地生成了一个类型

data PropositionF x
  = ConstF Bool
  | VarF String
  | AndF x x
  | OrF x x
  | NotF x
  deriving (Functor, Foldable, Traversable)

以及一些相关实例。请注意,PropositionF用其类型参数的副本替换每次出现的Proposition。现在您可以写

simplify :: Proposition -> Proposition
simplify = cata go
  where
    go :: PropositionF Proposition -> Proposition

    go (AndF (Const True) x) = x
    go (AndF f@(Const False) _) = f
    go (AndF x (Const True)) = x
    go (AndF _ f@(Const False)) = f

    go (OrF t@(Const True) _) = t
    go (OrF (Const False) x) = x
    go (OrF _ t@(Const True)) = t
    go (OrF x (Const False)) = x

    go (NotF (Const x)) = Const (not x)

    go x = embed x -- Catch-all: no rules apply

所有递归简化都是“自动”处理的,所有“这里没有令人兴奋的”情况都在一行中处理。