1

Thompson 中的练习 14.16-17 要求我将乘法和(整数)除法运算添加到表示简单算术语言的 Expr 类型,然后为 Expr 定义函数showeval(计算 Expr 类型的表达式)。

我的解决方案适用于除除法之外的每个算术运算:

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 Expror的一个实例Real Expr

4

1 回答 1

3

好吧,这Integral就是定义类型类的方式。有关信息,您可以例如:i Integral输入GHCi

你会得到

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不应该只是减少表达式,而是产生一个数字,因此具有 type eval :: Expr -> Integer。就此而言,除法很简单

eval (a :/ b) = (eval a) `div` (eval b)

这是定义的,因为您只是除以numbers

于 2010-07-28T12:23:08.907 回答