我目前要做的是创建一个名为Value
的类型:
data Value = Num Int
| Sum Int Int
| Dif Int Int
| Neg Int
deriving (Eq)
我想用它实现一个eval函数:
eval :: Value -> Int
eval (Num x) = x
eval (Sum x y) = x + y
eval (Dif x y) = x - y
eval (Neg x) = -x
我的预期结果应该是:
eval $ Dif (Sum (Num 3) (Num 6)) (Neg 4)
> 13
使用我当前的代码,我可以自己测试每个操作符并运行它们。
eval (Dif 3 4)
>-1
当我尝试在上面的预期输入中执行嵌套操作时出现问题,然后我得到错误:
"无法将预期类型
匹配Int
与实际类型Value
"
我试图理解这个问题,因为我认为我的操作应该返回Int
,并且因为我的Value
类型需要Int
,所以下一个操作应该具有预期的类型。我一直在测试各种输入,以查看我当前的eval函数实际上在做什么,并发现如果我这样做
eval (Dif (eval (Sum 3 5)) 4)
>4
我得到了预期的结果。我在这里做错了什么?
答案 0 :(得分:6)
data Value = Num Int
| Sum Int Int
| Dif Int Int
| Neg Int
此处您已指定Value
构造函数仅适用于Int
个值,例如,Neg
的类型为Int -> Value
。因此,您无法编写Neg (Neg 1)
或Sum (Num 1) (Num 2)
之类的内容,因为您尝试使用带标记的Value
,其中需要未标记的Int
。在Lisp中,当函数只需要(Num . 1)
时,就好像你传递了1
。
您可以更改类型的定义以接受Value
:
data Value = Num Int
| Sum Value Value
| Dif Value Value
| Neg Value
现在这表示表达式,其中Num
是文字Int
,但其他构造函数在Value
上运行。然后eval
函数会相应更改:
eval :: Value -> Int
eval (Num x) = x
eval (Sum x y) = eval x + eval y
-- ...