编辑:忽略这个问题!请参阅下面的评论。
我想要一个 OCaml 表达式,它传递一个文件(作为“in_channel”),然后逐行读取文件,进行一些处理,直到最后,然后返回处理结果。
我写了这个测试:
let rec sampler_string file string_so_far =
try
let line = input_line file in
let first_two_letters = String.sub line 0 2 in
sampler_string file (string_so_far ^ first_two_letters)
with End_of_file -> string_so_far;;
let a = sampler_string (open_in Sys.argv.(1)) "";;
(这里的“做一些处理”是将每行的前两个字符添加到运行计数中,其想法是最后应返回包含每行前两个字符的字符串。)
这不起作用:OCaml 认为“sampler_string”生成单位类型的内容,而不是字符串类型。 (当我尝试将结果用作字符串时,稍后会出现困难。)我认为这个问题是因为唯一的基本情况发生在异常中(End_of_file)。
所以,一个具体问题和一个一般问题:
- 有没有办法通过显式告诉 OCaml 期望sampler_string 的结果应该是字符串来修复此代码?
- 对于逐行读取文件到底并返回逐行处理结果的例程,是否有一些标准的、更好的语法?
最佳答案
正如 Damien Pollet 所说,您的 Sampler_string 函数在我的机器 ocaml v3.12.0 上也可以正常编译(并正确运行)。不过,我会回答你的问题:
您可以使用
:
运算符指定函数/值的类型。例如,这是您的函数及其类型注释。您会注意到返回类型位于函数声明的最末尾。let rec sampler_string (file : in_channel) (string_so_far : string) : string = ...
我不知道是否有更好的方法逐行读取文件。被迫通过异常处理文件结尾确实是一种痛苦。 Here's a blog post on the subject ,尽管那里提供的功能是将文件读入行列表。 Another mailing list version .
一些挑剔:
- 您不需要使用
;;
来分隔函数/值定义,ocamlc 可以从空格中找出它。 - 您应该关闭文件套接字。
- 如果文件中的行少于 2 个字符,String.sub 将引发异常。
关于file-io - 唯一基本情况是异常的递归表达式 [Context : Reading from files in OCaml],我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/5024511/