我正在尝试编写一个函数,通过识别将评估为零的部分来简化表达式,以便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) = ...
如果允许,b
和c
的类型是什么?好吧,可能是Int
或Bool
,我们无法确定。因此,通常禁止使用(a b c)
模式,要求模式必须以显式构造函数开头(除非模式只是一个变量)。
在代码中,您可以尝试使用多个方程式
elimiZeros (Add b (Num 0)) = ...
elimiZeros (Add b c ) = ...
...
避免您的大部分if
s。