为什么在这个非常简单的打印命令中出现语法错误

时间:2019-05-06 06:38:58

标签: syntax-error ocaml ocaml-toplevel

我正在尝试运行以下非常简单的代码:

open Str
print (Str.first_chars "testing" 0)

但是,它给出了以下错误:

$ ocaml testing2.ml 
File "testing2.ml", line 2, characters 0-5:
Error: Syntax error

错误消息中没有其他详细信息。

print_endline相同的错误;甚至没有打印命令。因此,错误的部分原因是:Str.first_chars "testing" 0

here中有关上述功能的文档如下:

  

val first_chars:字符串->整数->字符串

     

first_chars s n返回s的前n个字符。这是一样的   用作Str.string_before。

在第二条语句的末尾添加;;;没有任何区别。

以上代码的正确语法是什么。

编辑: 使用@EvgeniiLepikhin建议的以下代码:

open Str
let () =
    print_endline (Str.first_chars "testing" 0)

错误是:

File "testing2.ml", line 1:
Error: Reference to undefined global `Str'

并使用以下代码:

open Str;;
print_endline (Str.first_chars "testing" 0)

错误是:

File "testing2.ml", line 1:
Error: Reference to undefined global `Str'

仅使用以上代码中的print命令(而不是print_endline),错误是:

File "testing2.ml", line 2, characters 0-5:
Error: Unbound value print

注意,我的Ocaml版本是:

$ ocaml -version
The OCaml toplevel, version 4.02.3

我认为Str应该是内置的,因为opam找不到它:

$ opam install Str
[ERROR] No package named Str found.

我还尝试了@glennsl注释中建议的以下代码:

#use "topfind"
#require "str"
print (Str.first_chars "testing" 0)

但这也给出了简单的syntax error

2 个答案:

答案 0 :(得分:1)

OCaml程序是definitions的列表,这些列表按顺序进行评估。您可以定义值,模块,类,异常以及类型,模块类型,类类型。但是,让我们关注到目前为止的价值。

在OCaml中,没有语句,命令或指令。它是functional programming language,其中的所有内容都是一个表达式,并且在对表达式求值时会产生一个值。该值可以绑定到变量,以便以后可以引用。

print_endline函数采用类型为string的值,将其输出到标准输出通道,并返回类型为unit的值。类型unit仅具有一个称为unit的值,可以使用()表达式来构造。例如,print_endline "hello, world"是产生该值的表达式。我们不能只将表达式放在文件中并希望将其编译,因为表达式不是定义。定义语法很简单,

let <pattern> = <expr>

其中是变量或数据构造函数,它将与模式中出现的<expr>生成的值的结构以及可能绑定的变量相匹配,例如,以下是定义< / p>

let x = 7 * 8
let 4 = 2 * 2 
let [x; y; z] = [1; 2; 3]
let (hello, world) = "hello", "world"
let () = print_endline "hello, world"

您可能会注意到,print_endline "hello, world"表达式的结果未绑定到任何变量,而是与unit()匹配,可以看到(实际上看起来像)一个空的元组。您也可以写

let x = print_endline "hello, world"

甚至

let _ = print_endline "hello, world"

但是,最好在定义的左侧明确显示所期望的内容。

所以,现在我们格式正确的程序应该看起来像这样

 open Str

 let () = 
    print_endline (Str.first_chars "testing" 0)

我们将使用ocamlbuild来编译和运行我们的程序。 str模块不是标准库的一部分,因此我们必须告诉ocamlbuild我们将使用它。我们需要创建一个新文件夹,并将程序放入名为example.ml的文件中,然后可以使用以下命令对其进行编译

 ocamlbuild -pkg str example.native --

ocamlbuild工具将从后缀native推断出您的目标是什么(在本例中,这是构建本机代码应用程序)。 --意味着在编译后立即运行已构建的应用程序。上面的程序当然不会打印任何内容,下面是一个示例程序,该程序将在打印testing字符串的前零个字符之前打印一些问候消息,

open Str

let () =
  print_endline "The first 0 chars of 'testing' are:";
  print_endline (Str.first_chars "testing" 0)

这是它的工作方式

$ ocamlbuild -package str example.native --
Finished, 4 targets (4 cached) in 00:00:00.
The first 0 chars of 'testing' are:

此外,您可以使用提供交互式解释程序的example.ml顶级工具直接解释ocaml文件,而不是编译程序并运行结果应用程序。您仍然需要将str库加载到顶层,因为它不是预先链接在其中的标准库的一部分,这是正确的调用

ocaml str.cma example.ml

答案 1 :(得分:0)

您应该添加;;在“打开Str”之后:

open Str;;
print (Str.first_chars "testing" 0)

另一种选择是声明代码块:

open Str
let () =
    print (Str.first_chars "testing" 0)