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:
let read_file (char_List: 'char list ref) : 'char list =
!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.