匹配预期类型与实际类型

1 haskell types typeclass

我目前要做的是创建一个名为的类型Value:

data Value =  Num Int
            | Sum Int Int
            | Dif Int Int
            | Neg Int
              deriving (Eq)
Run Code Online (Sandbox Code Playgroud)

我想用它实现一个eval函数:

eval :: Value -> Int
eval (Num x) = x
eval (Sum x y) = x + y
eval (Dif x y) = x - y
eval (Neg x) = -x
Run Code Online (Sandbox Code Playgroud)

我的预期结果应该是:

eval $ Dif (Sum (Num 3) (Num 6)) (Neg 4)
> 13
Run Code Online (Sandbox Code Playgroud)

使用我当前的代码,我能够自己测试每个操作符并且它们起作用.

eval (Dif 3 4)
>-1
Run Code Online (Sandbox Code Playgroud)

当我尝试在上面的预期输入中执行嵌套操作时出现问题,然后我得到错误:

"无法将预期类型Int与实际类型匹配Value"

我正在尝试理解这个问题,因为我认为我的操作应该返回一个Int,因为我的Value类型采取Int下一个操作应该具有预期的类型.我一直在测试各种输入,以查看我当前的eval函数实际上在做什么,并发现如果我这样做

eval (Dif (eval (Sum 3 5)) 4)
>4
Run Code Online (Sandbox Code Playgroud)

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

Jon*_*rdy 6

data Value = Num Int
           | Sum Int Int
           | Dif Int Int
           | Neg Int
Run Code Online (Sandbox Code Playgroud)

在这里,您已指定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
Run Code Online (Sandbox Code Playgroud)

现在这表示表达式,其中Num是文字Int但其他构造函数在Values上运行.然后eval函数相应地改变:

eval :: Value -> Int
eval (Num x) = x
eval (Sum x y) = eval x + eval y
-- ...
Run Code Online (Sandbox Code Playgroud)