我正在尝试编写一个函数,通过识别将计算为零的部分来简化表达式,以便n * 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)
使用这种语法模式匹配是否可行?
编辑:感谢您的澄清答复!
答案 0 :(得分:4)
不能那样做。考虑一下这个:
data Operator = Add | Sub | Mult | Div | Power
data Exp = Num Int | Neg Exp | Bin Operator Exp Exp
现在,您可以编写与尝试的内容非常相似的内容:
elimiZeros (Bin a b c) = ...
答案 1 :(得分:3)
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
。