Reputation: 1065
When trying to run the following function in OCaml
:
let rec func1 o_list =
match o_list with
| [] -> []
| h::t -> let (nt,inner_list) = h in
if check_if_clear inner_list then
[nt,inner_list]::clear_rules
func1 t
;;
the program outputs an error
Characters 139-141: [nt,inner_list]::clear_rules
Error: This variant expression is expected to have type unit The constructor :: does not belong to type unit
Also you can assume that the function check_if_clear
always returns true
for now.
o_list
is a list of pair and pair itself contains an element and a list.
So it is something like this [ 'x , ['a,'b,'c]]
and clear_rules
is just an empty list at first.
Upvotes: 2
Views: 10818
Reputation: 8720
Your original example seems to have a missing semicolon after clear_rules
. Once that is inserted and with stubs for the additional functionality, the error message is reproducible. It has the following reason:
The then
branch of the if-expression
if check_if_clear inner_list then
[nt,inner_list]::clear_rules
returns a value of type ('nt_type, 'inner_list_type) list list
; this is because [nt, inner_list]
constructs a single item list of the pair (nt, inner_list)
and then the cons operator ::
makes it the head of a list. So, the then
branch returns a non-unit type.
Conversely, the else
branch (by virtue of not existing) has type unit (i.e. no actual value). But in OCaml, the types for the then
and else
branch of an expression must match (i.e. be of the same type or subtypes of a common supertype); an if expression without an else
branch therefore always has type unit, and so does the then
branch of such an expression. Because it doesn't in your case, the compiler tells you that (in a roundabout way), by noting that the cons operator ::
has a different type (it creates a list and returns it) than the unit type it had inferred.
I suspect from your comments that your intention was not to create a list, but to perform some action with a side effect. For this, you'll probably need to write that action differently.
Upvotes: 6
Reputation: 1065
I managed to solve the problem that I was facing in another way, instead of trying to use some external list, I made my function to return the desired list. Here is the code
let rec func1 o_list clear_list =
match o_list with
| [] -> clear_list
| h::t -> let (nt,inner_list) = h in
if check_if_clear inner_list then
func1 t ([nt,inner_list]::clear_list)
else
func1 t clear_list
;;
Upvotes: 2