Ocaml Camlp4解析器函数:表达式的类型为int,但表达式的类型应为float

Ocaml Camlp4解析器函数:表达式的类型为int,但表达式的类型应为float,ocaml,camlp4,Ocaml,Camlp4,我正在编写一个简单的解析器函数,该函数期望流中有一个项,并返回一个int,但出于某种原因,编译器一直期望浮点值,原因我无法理解;特别是考虑到代码是 我尝试过将这两个变量类型转换为int,通常只是对语法进行修改,但函数太简单了,我不知道到底出了什么问题。我知道,对于普通函数,可以使用let:type->type指定类型,但我不知道如何使用解析器函数 下面是函数: let parse_binary_preference=parser |[]->(整数/浮点数) | [< >] -> 30 在里面

我正在编写一个简单的解析器函数,该函数期望流中有一个项,并返回一个int,但出于某种原因,编译器一直期望浮点值,原因我无法理解;特别是考虑到代码是

我尝试过将这两个变量类型转换为int,通常只是对语法进行修改,但函数太简单了,我不知道到底出了什么问题。我知道,对于普通函数,可以使用
let:type->type
指定类型,但我不知道如何使用解析器函数

下面是函数:

let parse_binary_preference=parser
|[<'Token.Number n>]->int\u of \u float n
| [< >] -> 30 
在里面
下面是在案例中使用它的更大背景,这也是问题的一部分(尽管我不认为是):

let parse_binary_preference=parser
|[<'Token.Number n>]->(整数/浮点数)
| [< >] -> 30 
在里面
分析器
|[<(前缀,种类)=解析_运算符;
'Token.Kwd op??“预期操作员”;
prec=解析二进制优先级;
“Token.Kwd”(“??”预期“(“在操作员原型中”);
args=parse_first_arg[];
运算符原型中的“Token.Kwd')??“expected')”>]->
我现在刚刚拿到标准

File "parser.ml", line 108, characters 49-50:
Error: This expression has type int but an expression was expected of type
         float
类型错误

有人知道为什么会有浮动吗?如何使函数预期为int

编辑:

我现在意识到我现在的措辞很糟糕,但是我意识到程序的上下文决定了函数的类型,我问的是程序中的什么使得它假设函数返回了int。它似乎超出了我发布的范围,因此,我正在更新我的帖子,用与所显示的所有内容相关的代码

以下是完整的相关代码集。首先,我为没有包括这一点表示歉意

token.ml:

类型令牌=
(*小学*)
|字符串标识符|整数编号
(*控制*)
|如果| Else |用于
(*用户操作*)
|二元|一元
parser.ml

let parse_prototype=
让rec parse_args acculator=parser
|[<'Token.Kwd',';'Token.Ident id;e=parse_args(id::acculator)>]->e
|[<>]->蓄能器
在里面
让parse_first_arg累加器=解析器
|[<'Token.Ident id;e=parse_args(id::acculator)>]->e
|[<>]->蓄能器
在里面
让parse_操作符=解析器
|[<'Token.Binary>]->“Binary”,2
|[<'Token.Unary>]->“一元”,1
在里面
让parse_binary_preference=解析器
|[<'Token.Number n>]->(浮点n的整数)(*第108行*)
| [< >] -> 30 
在里面
分析器
|[<'令牌.Ident id;
“Token.Kwd”(“??”预期“(“原型中”);
args=parse_first_arg[];
原型中的“Token.Kwd”)??“预期交割”)”>]->
Ast.Prototype(id,数组,of_list(list.rev args))
|[<(前缀,种类)=解析_运算符;
'Token.Kwd op??“预期操作员”;
prec=解析二进制优先级;
“Token.Kwd”(“??”预期“(“在操作员原型中”);
args=parse_first_arg[];
运算符原型中的“Token.Kwd')??“expected')”>]->
让name=prefix^(String.make 1 op)在
让args=Array.of_list(list.rev args)在
(*验证op*的参数数是否正确)
如果Array.length args!=那好吧
raise(Stream.Error“op def中的操作数无效”)
其他的
如果种类==1,则
Ast.Prototype(名称、参数)
其他的
Ast.BinOpPrototype(名称、参数、prec)
| [< >] ->
raise(Stream.Error“原型中需要函数名”)
ast.ml

类型原型=
|字符串*字符串数组的原型
|字符串的BinOpPrototype*字符串数组*int

错误的来源不在您显示的行中:有一个
令牌
模块和
parse_first_arg
parse_操作符
函数的实现,使您的代码得以编译

一件可能很奇怪的事情是,您的Token.Number使用浮点作为参数

还要注意,camlp4及其解析器扩展已经被废弃

有人知道为什么会有浮动吗?如何使函数预期为int

嗯,由于您没有显示代码,所以无法告诉您代码哪里出错了,但我至少可以指出您对OCaml工作原理的概念性误解,希望它能帮助您修复代码:)

在OCaml中,没有类型转换,您不能让函数期望任何东西,因为类型是从您编写的代码中推断出来的

例如,这里有一个函数

 let number_of_words s = String.count s ~f:(Char.is_whitespace) + 1
它的类型被推断为
string->int
,在任何情况下都不能更改它,因为类型基本上是由代码的结构定义的。编译器可以推断函数/表达式适用的最一般上下文

在我们的示例中,编译器知道
String.count
接受
String
类型的值,因此
s
也必须是
String
类型,它知道
String.count
返回
int
类型的值,
(+)
只能应用于整数。因此,返回的类型是
int
,仅此而已

如果您将在不可接受的环境中应用您的功能

"the phrase has " ^ number_of_words "hello, world"
编译器告诉我们,单词“hello,world”的表达式
number>的类型为
int
,但它的类型应为
 "the phrase has " ^ string_of_int (number_of_words "hello, world")
  string_of_int 42
  - : string = "42"