Thompson的练习14.16-17要求我将乘法和(整数)除法的运算添加到Expr类型中,它代表一种简单的算术语言,然后定义函数 show 和的 我的解决方案适用于除除法之外的每个算术运算: ,例如, 但是,当我尝试实现除法时,我遇到了问题。我不理解当我尝试编译以下内容时收到的错误消息: 这是错误: 首先,我不知道为什么为数据类型定义data Expr = L Int
| Expr :+ Expr
| Expr :- Expr
| Expr :* Expr
| Expr :/ Expr
instance Num Expr where
(L x) + (L y) = L (x + y)
(L x) - (L y) = L (x - y)
(L x) * (L y) = L (x * y)
instance Eq Expr where
(L x) == (L y) = x == y
instance Show Expr where
show (L n) = show n
show (e1 :+ e2) = "(" ++ show e1 ++ " + " ++ show e2 ++ ")"
show (e1 :- e2) = "(" ++ show e1 ++ " - " ++ show e2 ++ ")"
show (e1 :* e2) = "(" ++ show e1 ++ " * " ++ show e2 ++ ")"
show (e1 :/ e2) = "(" ++ show e1 ++ " / " ++ show e2 ++ ")"
eval :: Expr -> Expr
eval (L n) = L n
eval (e1 :+ e2) = eval e1 + eval e2
eval (e1 :- e2) = eval e1 - eval e2
eval (e1 :* e2) = eval e1 * eval e2
*Main> (L 6 :+ L 7) :- L 4
((6 + 7) - 4)
*Main> it :* L 9
(((6 + 7) - 4) * 9)
*Main> eval it
81
it :: Expr
instance Integral Expr where
(L x) `div` (L y) = L (x `div` y)
eval (e1 :/ e2) = eval e1 `div` eval e2
Chapter 14.15-27.hs:19:9:
No instances for (Enum Expr, Real Expr)
arising from the superclasses of an instance declaration
at Chapter 14.15-27.hs:19:9-21
Possible fix:
add an instance declaration for (Enum Expr, Real Expr)
In the instance declaration for `Integral Expr'
div
为什么Expr要求我定义Enum Expr
或Real Expr
的实例。
答案 0 :(得分:3)
嗯,这就是定义Integral
类型类的方式。有关信息,您可以例如只需在 GHCi 中输入:i Integral
。
你会得到
class (Real a, Enum a) => Integral a where ...
这意味着任何a
类型Integral
必须首先为Real
和Enum
。这就是生活。
请注意,也许你的类型搞砸了很多。看看
instance Num Expr where
(L x) + (L y) = L (x + y)
(L x) - (L y) = L (x - y)
(L x) * (L y) = L (x * y)
这个只允许你添加Expr
个会话,如果它们包含普通数字。我很确定你不想那样。
您想要添加任意表达式,并且您已经有了这个语法。这只是
instance Num Expr where
(+) = (:+)
(-) = (:-)
-- ...
这允许您使用完全正常的语法编写(L 1) + (L 2)
。同样,eval
不应只是减少表达式而是产生一个数字,因此具有类型eval :: Expr -> Integer
。分工很简单
eval (a :/ b) = (eval a) `div` (eval b)
这是定义的,因为你只需要划分数字。