表达式中的模式匹配操作员/构造函数



我正在尝试编写一个函数,通过识别将评估为零的部分来简化表达式,以便n*0-> 0-> 0和n 0-> n等。

elimiZeros :: Exp -> Exp

数据类型是:

data Exp = Num Int
     | Add Exp Exp
     | Sub Exp Exp
     | Mult Exp Exp
     | Div Exp Exp
     | Power Exp Exp
     | Neg Exp
     deriving Show

要避免自己与每个操作员进行匹配,我尝试同时匹配几个操作员,但是我遇到了一个编译器错误:"模式中的解析错误:a":

elimiZeros :: Exp -> Exp
elimiZeros (Num n) = (Num n)
elimiZeros (a b c) = 
  if c == (Num 0)
    then case a of
      Add -> elimiZeros b
      Sub -> elimiZeros b
      Mult -> (Num 0)
  else if b == (Num 0)
    then case a of
      Add -> elimiZeros c
      Sub -> elimiZeros c
      -- etc, not finished
  else (a b c)

是否可以与此语法进行模式匹配?

编辑:谢谢您的澄清回复!

无法做到这一点。而是考虑这个:

data Operator = Add | Sub | Mult | Div | Power
data Exp = Num Int | Neg Exp | Bin Operator Exp Exp

现在,您可以写一些与您尝试过的非常相似的东西:

elimiZeros (Bin a b c) = ...

haskell不允许

这样的模式
f (a b c) = ...

要查看为什么,请考虑这种类型:

data T = A Int Int | B Bool Bool
f :: T -> ...
f (a b c) = ...

如果允许,bc的类型是什么?好吧,可能是IntBool,我们无法确定。因此,通常禁止使用(a b c)模式,要求模式必须以显式构造函数开头(除非模式只是一个变量)。

在代码中,您可以尝试使用多个方程式

elimiZeros (Add b (Num 0)) = ...
elimiZeros (Add b c      ) = ...
...

避免您的大部分ifs。

最新更新