数据类型和非详尽模式

Har*_*son 1 haskell

如果有数据类型

data Arith  = Con Int
              | Add Arith Arith
              | Sub Arith Arith
              | Mul Arith Arith
              | Div Arith Arith
Run Code Online (Sandbox Code Playgroud)

一个实例:

instance Show Arith where
    show (Con i)     = show i
    show (Add e1 e2) =  "(" ++ show e1 ++ " + " ++ show e2 ++ ")" 
    show (Sub e1 e2) =  "(" ++ show e1 ++ " - " ++ show e2 ++ ")" 
    show (Mul e1 e2) =  "(" ++ show e1 ++ " * " ++ show e2 ++ ")" 
show (Div e1 e2) =  "(" ++ show e1 ++ " / " ++ show e2 ++ ")" 
Run Code Online (Sandbox Code Playgroud)

和一个函数评估预期的行为如下:

ghci> eval (Mul (Con 5) (Div (Con 6) (Con 2) ))
15
Run Code Online (Sandbox Code Playgroud)

当我尝试比基本案例更复杂的东西时,这就是我想出的那种不起作用.

eval :: ArithExp -> Int
eval (Con e1)                = e1
eval (Add (Con e1) (Con e2)) = e1 + e2
eval (Sub (Con e1) (Con e2)) = e1 - e2
eval (Div (Con e1) (Con e2)) = e1 `div` e2
eval (Mul (Con e1) (Con e2)) = e1 * e2
Run Code Online (Sandbox Code Playgroud)

当我尝试任何不在这种情况下的东西时,我当然会得到关于详尽模式的错误.

所以我的问题是,如何在不做天真的方式的情况下捕捉所有模式?

我注意到Add被定义为Add Arith Arith,Sub Arith Arith所以我如何在我的eval函数中利用它?我试过做:

eval (Add Arith Arith) = Arith + Arith
Run Code Online (Sandbox Code Playgroud)

但这也不起作用(不在范围错误中).

你不需要给我一个完整的代码示例或任何东西,我只是想指出正确的方向.在haskell仍然是新的.

谢谢.

小智 6

你应该使用递归.

eval (Add a1 a2) = (eval a1) + (eval a2)
Run Code Online (Sandbox Code Playgroud)

等等..