我目前正在教自己ocaml
编程语言类,我正在尝试弄清楚如何指定函数参数并将类型返回为List
。
我创建了一个程序,通过char
将每个char
存储在char
中来读取文件List
,反转列表然后返回List
。
当前代码:
(*
Creating a function that will read all the chars
in a file passed in from the command argument.
This function takes a parameter of type List.
This function will return a List.
*)
let read_file (char_List : List) : List =
let char_in = open_in Sys.argv.(1) in (* Creating a file point/in_channel *)
try
while true do
let c = input_char char_in in (* Getting char from the file *)
char_List := c :: !char_List (* Storing the char in the list *)
done
with End_of_file ->
char_List := List.rev !char_List; (* End of file was reaching reversing char list *)
close_in char_in; (* Closing the file pointer/in_channel *)
;;
(* Storing the result of read_file to buffer which buffer is of type list *)
let buffer = ref [] in
read_file(buffer);
print_string "\nThe length of the buffer is: ";
print_int (List.length !buffer); (* Printing length of the list *)
print_string ("\n\n");
List.iter print_char !buffer; (* Iterating through the list and print each element *)
如果我删除指定参数类型并返回List
类型,则代码按预期运行。然而;我想指定参数的类型和返回类型为List
。
如何将函数参数和返回类型指定为List
?
答案 0 :(得分:2)
首先,List
是一个不是类型的模块,所以你可能意味着list
。但是,您不能仅使用list
进行注释,因为列表本身不是类型:您不希望有一个不可知事物的列表,而是一个已知类型的元素列表。例如,在您的情况下,您有一个字符列表,可以写为char list
。同样,整数列表将被键入int list
。
更准确地说,list
本身不是一个类型,而是一个类型构造函数,它将列表元素的类型作为参数,并返回此类元素列表的类型。
P.S。 :如果您正在学习OCaml,您可以尝试重写代码而不使用引用来习惯更实用的样式。
答案 1 :(得分:2)
正如@octachron正确指出的那样,List
在ocaml中不是正确的类型。你可能意味着'a list
。查看代码,您可以通过解决以下2点来纠正您的代码:
let read_file (char_List: 'char list ref) : 'char list =
!char_List
和!char_List
。您更正的代码可能如下所示,
let read_file (char_List: 'char list ref) : 'char list =
let char_in = open_in Sys.argv.(1) in (* Creating a file point/in_channel *)
try
while true do
let c = input_char char_in in (* Getting char from the file *)
char_List := c :: !char_List (* Storing the char in the list *)
done;
!char_List
with End_of_file ->
char_List := List.rev !char_List; (* End of file was reaching reversing char list *)
close_in char_in; (* Closing the file pointer/in_channel *)
!char_List
虽然这有效,但您可能希望在ocaml中使用更实用的方法。没有变异和递归函数的版本可以实现如下:
let get_chars file =
let rec loop ic acc =
match Pervasives.input_char ic with
| c -> loop ic (c::acc)
| exception(End_of_file) -> List.rev acc
in
let ic = Pervasives.open_in file in
loop ic []
然后在ocaml toploop(repl)中你可以执行这样的功能
get_chars "/tmp/union_find.ml";;
或者
get_chars Sys.argv.(1)
;;