首页 > 解决方案 > 如何修复 Ocaml Unbound 构造函数错误

问题描述

我是 OCaml 的新手。我正在尝试编写这个称为 H 序列的基本递归函数。这是我的代码:

let rec H n = 
    if n == 0 then
        0
    else 
       n - H(H(H(n - 1)))
;;


print_int(H 3);

我很确定我的函数 H 是正确的但是我得到了这个错误:

File "main.ml", line 1, characters 8-9:
Error: Unbound constructor H

我不确定如何以及如何绑定到 H。如果有人能给我一些建议,将不胜感激。如果它有助于我使用这个网站来运行我的代码: https ://www.tutorialspoint.com/compile_ocaml_online.php

标签: ocaml

解决方案


在 Ocaml 中,标识符的第一个字符用于确定其语法类别。尤其是,

  • 变量
  • 类型
  • 记录字段
  • 班级
  • 类类型
  • 实例变量

必须以小写字母开头。反之

  • 构造函数
  • 模块

必须以大写字母开头。(它们是构造函数[]()(::)true的5 个例外false)。和

  • 模块类型
  • 多态变体构造函数

可以以小写或大写字母开头。但是,为它们使用大写字母更为惯用。

所以如果你定义

let rec H n = 
    if n == 0 then
        0
    else 
       n - H(H(H(n - 1)))

编译器读取H为构造函数,因此它认为您正在尝试以类似于

type t = C of int
let (C n) = C 1

换句话说,您的问题的解决方案是重命名您的变量h

let rec h n = 
    if n = 0 then
        0
    else 
       n - h(h(h(n - 1)))

(不要==在 OCaml 中使用非可变变量)。

如果您想知道为什么构造函数和变量之间存在这种区别,主要原因之一是否则可能会编写一些非常混乱的模式匹配。例如考虑

type t =
| X
| Y
| Z

let f x = match x with
| X -> 0
| y -> 1

在模式匹配的第一个分支中

| X -> 0

我们正在检查是否x是构造函数X。但是,在第二个分支中,

| y -> 1

我们将变量重命名为x分支y中的。在这里,我们可以使用第一个字符的大小写来知道我们在哪些情况下。如果没有这种语法区别,我们将需要记住在模式匹配期间是否有构造函数Xy在范围内。


推荐阅读