匹配预期类型与实际类型

时间:2017-01-30 00:42:37

标签: haskell types typeclass

我目前要做的是创建一个名为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

我得到了预期的结果。我在这里做错了什么?

1 个答案:

答案 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
-- ...