Reputation: 19
I have the following function :
let extract n l =
let rec aux acc pro = function
|[] -> acc
|a::b -> if (List.length pro) = n then aux (pro::acc) [] (a::b) else aux acc (a::pro) b; aux acc (pro) b
in aux [] [] l
As you can see in my pattern matching at the second test's case I am calling two times the function. Is it possible ?
So it is possible to have this kind of function :
let rec some_function = function
| [] ->[]
| a::b -> some_function b; some_function b (*so I am calling two times the function in a single test*)
I am asking this question because here I have the following warning :
File "main.ml", line 4, characters 48-72:
Warning 10: this expression should have type unit.
So there is a problem at the exact place I called two times my recursive function.
It might be because I am using ;
but in this case how could I seperate these two calls ?
Thank you !
Upvotes: 1
Views: 823
Reputation: 1071
To add onto FlorianWeimer's answer, some information about your error message.
Warning 10: this expression should have type unit.
OCaml is strongly typed. Therefore, if a function returns, say, an integer or a list, and you don't do anything with it, it'll wonder what's going on and warn you.
A function call like print_int 5;
returns ()
, which is of type unit
. That basically means that it returns nothing because you're not calling it to compute something, but to do something. It has done that thing and now it returns and you move on.
But a function call like float_of_int 5;
, that returns a value (the float 5.0
). You (probably) didn't call it to do something, but to compute something, and what it returns is what interests you. Same goes for arithmetic expressions like 3+6;
or for straight up values like 10;
or "abc";
or [];
.
That's why, if you write one of these things that have a value and you don't use that value (in an assignment, or as a parameter of another function), OCaml warns you. It tells you "I computed something that I didn't assign, didn't return, and didn't use as the argument of something else. Usually, things of type unit
are the only things like that. Are you sure you don't have a bug in your code?"
Sometimes you know what you're doing and you don't want that warning. In that case, you can call the ignore
function. ignore
will take anything and ignore it, returning ()
. For instance, ignore 5;
or ignore (float_of_int 10);
won't throw the "this expression should have type unit" warnings that you'd get with 5;
or float_of_int 10;
.
Upvotes: 1
Reputation: 33694
It is possible in the sense that the compiler accepts it, but it only makes sense if you do something with the result (or the function has a side effect). The classic example for two function calls is the recursive computation of the Fibonacci sequence:
let rec fib = function
| 0 -> 0
| 1 -> 1
| n -> fib (n - 1) + fib (n - 2)
Upvotes: 0