我有此功能
let rec g (a:float) (b:int) : int =
let rec func (x:float*char) (y:int) : float =
let (v,w) = x in
let w' = int_of_char w in
(func (float_of_int y, w) (g v w')) +. 2.1
我知道有一个问题无法在特定条件下停止递归(编译器将提示堆栈溢出错误)。但是在编译时出现语法错误,我认为类型是正确的,并且在函数名称前添加了rec,仍然无法正常工作。怎么了?
答案 0 :(得分:1)
如果您将使用某种自动缩进工具缩进代码(强烈建议您这样做),则代码问题将变得显而易见,例如,经过ocp-indent之后,代码看起来像这样:
let rec g (a:float) (b:int) : int =
let rec func (x:float*char) (y:int) : float =
let (v,w) = x in
let w' = int_of_char w in
(func (float_of_int y, w) (g v w')) +. 2.1
因此,如您所见,let rec func ...
表达式尚未完成,它必须具有in
部分,但不是。这是一个简单的模板,用于编写内部包含函数的函数,
let <outer-function-name> <outer-args> =
let <inner-function-name> <inner-args> =
<inner-function-body> in
<outer-function-body>
用您的代码替换用<
和>
分隔的部分,您将一切正常。
问题的症结最可能是您混淆了以下两种语法结构:
let <var> = <exp>
和
let <var> = <exp> in <body>
它们通常是混乱的,考虑到它们的相似程度也就不足为奇了。但是,它们有很大的不同。前者是定义 1 ,而后者是表达式。前者可能只出现在模块的顶层,而后者可能出现在期望表达的任何地方。我知道这可能会造成混淆,因此您可能会从阅读我的其他答案中受益,我在其中给出了simple examples个有关OCaml如何完成工作的信息。
1))最接近于某些其他语言中称为 statement 的事物