我有以下类型的值,我想根据这些类型进行计算,但是我得到一个错误说:
此表达式具有类型值,但预期表达式为int
那么我应该怎么做才能进行计算?
type binop =
| Plus
| Minus
| Mul
| Div
| Eq
| Ne
| Lt
| Le
| And
| Or
| Cons
type expr =
| Const of int
| True
| False
| NilExpr
| Var of string
| Bin of expr * binop * expr
| If of expr * expr * expr
| Let of string * expr * expr
| App of expr * expr
| Fun of string * expr
| Letrec of string * expr * expr
type value =
| Int of int
| Bool of bool
| Closure of env * string option * string * expr
| Nil
| Pair of value * value
val x : value = Int 1
val x : value = Int 1
当我这样做时
x+x;;
然后它会抛出错误,我想要这样的东西:
Nano.value = Int 2
修复类似这样的东西它会返回value = Int
但是我想要Nano.value = Int
的东西,以及名为Nano.ml的文件,所以我想要Nano.value
let add (x,y) = match (x,y) with
| (Int xx, Int yy) -> Int (xx + yy)
| ( _ , _) -> Int 0
答案 0 :(得分:1)
没有为类型值的值定义'+'运算符,所以这里发生的是你为整数调用'+'运算符。
您需要定义一个运算符来添加您的值类型:
let ( +! ) x y = match (x,y) with
| (Int xx, Int yy) -> xx + yy
| _ -> raise <some exception>
Int 8 +! Int 2 ... should yield 10.
(注意:我现在无法轻松访问OCaml REPL,因此可能无法编译)
另外,不确定添加两个Closures,Nil's还是Pair's意味着什么,你必须确定对于你的加法运算符,你会注意到我只是提出了一些除了Ints之外的例外。您可能希望填写适合该类型的操作。
答案 1 :(得分:1)
正如其他答案所提到的,您需要为value
类型定义自己的“加号”运算符。这样的事情应该有效:
exception Bad_addition
let rec (++) a b = match (a,b) with
| (Int(x),Int(y)) -> Int(x+y)
| (Bool(x),Bool(y)) -> Bool(x || y)
| (Nil,Nil) -> Nil
| (Pair(x1,y1),Pair(x2,y2)) -> Pair(x1 ++ x2,y1 ++ y2)
| _ -> raise Bad_addition
这将为您提供一个名为++
的运算符,您可以使用该运算符将值一起添加。例如,执行Int(1) ++ Int(1)
会生成结果Int(2)
。
请注意,我已将布尔值的“加法”定义为逻辑或两个Nil
值的加法Nil
,并添加成对的逐点加法,但您可以使用为这些实现不同的行为。