简体   繁体   中英

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

I am currently teaching myself ocaml for a programming language class and I am trying to figure out how to specify a function parameter and return type as a List .

I have create a program that reads a file char by char stores each char in a List , reverses the list then returns the List .

Current code:

(* 
   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 *)

If I remove specifying the parameter type and return type of List the code runs as intended. However; I would like to specify the type of the parameter and return type as a List .

How do you specify the function parameter and return type to be a List ?

First, List is a module not a type, so you probably meant list . However, you cannot annotate with only list , because a list is not a type by itself: you do not want to have a list of unknowable things, but a list of elements which have themselves a known type. For instance, in your case, you have a list of characters, which can be written as char list . Similarly, a list of integers will be typed int list .

More precisely, list is not a type by itself but a type constructor which takes as argument a type for the elements of the list and returns a type for the list of such elements.

ps : if you are learning OCaml you could try to rewrite your code without using references to get used to a more functional style.

As @octachron correctly pointed out, List is not a correct type in ocaml. You probably meant 'a list . Looking at your code, you can correct your code by addressing the 2 points below:

  • Correct function signature as follows, let read_file (char_List: 'char list ref) : 'char list =
  • Add !char_List after done and !char_List .

You corrected code may look like the following,

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

While this works, however, you may want to prefer a more functional approach in ocaml. A version without mutation and with recursive function could be implemented as follows:

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 []

Then in ocaml toploop(repl) you can execute the function as such

  • get_chars "/tmp/union_find.ml";;

or perhaps

  • get_chars Sys.argv.(1) ;;

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

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