繁体   English   中英

如何在ocaml中指定函数参数并以List形式返回类型?

[英]How to specify a function parameter and return type as a List in ocaml?

我目前正在为编程语言课程自学ocaml ,并且试图弄清楚如何指定函数参数和返回类型作为List

我已创建一个程序,读取文件charchar存储每个charList ,反转列表,然后返回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

首先, List是一个模块而不是类型,因此您可能是指list 但是,您不能仅使用list注释,因为list本身并不是类型:您不希望拥有不可知事物的列表,而是拥有本身具有已知类型的元素的列表。 例如,在您的情况下,您有一个字符列表,可以将其写为char list 同样,整数列表将被输入int list

更确切地说, list本身不是类型,而是类型构造函数,该构造函数将列表元素的类型作为参数并返回此类元素列表的类型。

ps:如果您正在学习OCaml,则可以尝试重写代码,而无需使用引用来习惯功能更强大的样式。

正如@octachron正确指出的那样, List不是ocaml中的正确类型。 你可能的意思是'a list 查看您的代码,您可以通过解决以下两点来纠正代码:

  • 如下纠正函数签名, 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) ;;

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM