我正在尝试在Haskell中实现以下代码,以评估算术表达式,遗憾的是它在Couldn't match expected type `Integer' against inferred type `Value'
处给出了错误(IVal (eval c x)) + (IVal (eval c (Prim IntAddOp xs)))).
Plz帮我解决了一些问题。
type Env = GenEnv Value
data Value
= IVal Integer
| BVal Bool
--------------------------------------------------
eval :: Env -> Exp -> Value
eval _ (Num n) = IVal n
eval _ (Prim IntAddOp ((Num x) : (Num y):[])) = IVal (x+y)
eval c (Prim IntAddOp (x: xs)) = IVal ((IVal (eval c x)) + (IVal (eval c
(Prim IntAddOp xs))))
谢谢...
答案 0 :(得分:4)
最后一行应该改变:
IVal $
case eval c x of
IVal ix ->
case eval c (Prim IntAddOp xs) of
IVal ip -> ix + ip
_ -> error "trying to add int value to bool value"
_ -> error "trying to add bool value to int value"
(或类似的东西。你没有提供数据结构的所有定义以确定。)
然而,这可以更多地整理一下。此外,您似乎永远不会使用Env参数。
编辑:这是一种更好的方式。注意我们正在使用Maybe monad:将一个布尔值添加到整数值是没有意义的。eval :: Expression -> Maybe Value
eval (Integer i) = return $ IVal i
eval (Boolean b) = return $ BVal b
eval (Add l r) =
do el <- eval l
er <- eval r
return . IVal $ l + r
eval (And l r) =
do el <- eval l
er <- eval r
return . BVal $ l && r
... and so on
如果您需要错误消息,请将Maybe替换为错误monad。
答案 1 :(得分:2)
此错误意味着它所说的内容。
首先,Haskell期待什么?
IVal ( something )
Haskell希望something
成为Integer
,因为您对Value
的定义应该是:
data Value
= IVal Integer
| BVal Bool
其次,Haskell推断了什么?
(IVal (eval c x)) + (IVal (eval c (Prim IntAddOp xs)))
我必须假设您为Num
定义了Value
个实例,否则+
将无效。因此,当您向Value
添加Value
时,您应该获得Value
结果。 (我知道添加的两件事是Values
,因为IVal
是Value
类型的构造函数)
所以Haskell推断这个表达式的类型为Value
。
为什么不匹配?
Haskell期待一个Integer
表达式,你给它一个Value
表达式。错误意味着它所说的。那么如何解决呢?好吧,我不知道。在黑暗中进行刺杀,您可以从添加中移除IVal
构造函数。
( (eval c x) + (eval c (Prim IntAddOp xs)) )
等一下,eval
的结果是Value
,而不是Integer
,所以...我们仍在添加Values
,并将其包含在内IVal
比以前更加错误。
我们如何定义一个函数来从Integer
中获取IVal
。
extract :: Value -> Integer
extract (IVal x) = x
extract (BVal True) = 1
extract (BVal False) = 0
在这里,我使用了将布尔值视为1或0的可怕的类似C的约定。您可能希望在extract
s上保留BVal
未定义,或者抛出错误,或其他任何内容。至少现在我们有办法从Integer
中提取Value
。
所以现在我假设你实际上没有为Num
设置Value
个实例。让我们从这两个表达式中提取Integers
,以便将它们加在一起。
( extract (eval c x) + extract (eval c (Prim IntAddOp xs)) )
现在 应推断为Integer
。那么我们可以将它包装在IVal
构造函数中。
IVal (extract (eval c x) + extract (eval c (Prim IntAddOp xs)))
问题解决了吗?
答案 2 :(得分:0)
eval _ (Prim _ ([])) = IVal (0)
eval _ (Prim IntAddOp ((Num x) : (Num y):[])) = IVal (x+y)
eval s (Prim IntAddOp (x: xs)) = IVal (test (eval s x)+ test (eval s (Prim IntAddOp
xs)))
这很好,正在评估1 + 2 + 3 = ...;
谢谢你们帮助人们.......